Skip to content
Merged

canary #6978

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,12 @@ android {
dimension "environment"
applicationId "me.tinykitten.trainlcd.dev"
versionNameSuffix "-dev"
versionCode 100000761
versionCode 100000763
versionName "10.15.1"
}
prod {
dimension "environment"
versionCode 100000761
versionCode 100000763
versionName "10.15.1"
}
// ストア配信する dev (Canary) と applicationId を分けた、ローカル検証専用のフレーバー。
Expand All @@ -177,7 +177,7 @@ android {
dimension "environment"
applicationId "me.tinykitten.trainlcd.local"
versionNameSuffix "-local"
versionCode 100000761
versionCode 100000763
versionName "10.15.1"
}
}
Expand Down
6 changes: 3 additions & 3 deletions android/wearable/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ android {
dimension = "environment"
applicationIdSuffix = ".dev"
versionNameSuffix = "-dev"
versionCode = 100000762
versionCode = 100000764
versionName = "10.15.1"
}
create("prod") {
dimension = "environment"
versionCode = 100000762
versionCode = 100000764
versionName = "10.15.1"
}
// :app の local フレーバーと対になるローカル検証専用フレーバー。Wear の Data Layer は
Expand All @@ -100,7 +100,7 @@ android {
dimension = "environment"
applicationIdSuffix = ".local"
versionNameSuffix = "-local"
versionCode = 100000762
versionCode = 100000764
versionName = "10.15.1"
}
}
Expand Down
4 changes: 2 additions & 2 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default {
userInterfaceStyle: 'automatic',
// Expo SDK 57 の各モジュール(expo / expo-modules-core ほか)は podspec で iOS 16.4 以上を要求する
deploymentTarget: '16.4',
buildNumber: '2910',
buildNumber: '2911',
scheme: IS_DEV ? 'CanaryTrainLCD' : 'ProdTrainLCD',
bundleIdentifier: IS_DEV
? 'me.tinykitten.trainlcd.dev'
Expand All @@ -71,7 +71,7 @@ export default {
? 'me.tinykitten.trainlcd.dev'
: 'me.tinykitten.trainlcd',
permissions: [],
versionCode: 100000761,
versionCode: 100000763,
},
owner: 'trainlcd',
experiments: {
Expand Down
2 changes: 1 addition & 1 deletion ios/Modules/VitsTTS/VitsTTSModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ final class VitsTTSModule: NSObject {
try outputs.withUnsafeMutableBufferPointer { outValues in
try check(
api.pointee.Run!(
session, nil, inNames.baseAddress, inValues.baseAddress, inputs.count,
session, nil, inNames.baseAddress, inValues.baseAddress, inValues.count,
outNames.baseAddress, outputNameArgs.count, outValues.baseAddress),
"Run")
}
Expand Down
36 changes: 18 additions & 18 deletions ios/TrainLCD.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2550,7 +2550,7 @@
CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist;
Expand Down Expand Up @@ -2590,7 +2590,7 @@
CODE_SIGN_ENTITLEMENTS = ProdTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Prod/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = TrainLCD;
Expand Down Expand Up @@ -2649,7 +2649,7 @@
CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand Down Expand Up @@ -2756,7 +2756,7 @@
CODE_SIGN_ENTITLEMENTS = TrainLCD/trainlcd.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand Down Expand Up @@ -2837,7 +2837,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist;
Expand Down Expand Up @@ -2877,7 +2877,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryTrainLCD.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
INFOPLIST_FILE = TrainLCD/Schemes/Dev/Info.plist;
Expand Down Expand Up @@ -3089,7 +3089,7 @@
CODE_SIGN_ENTITLEMENTS = RideSessionActivity/CanaryRideSessionActivity.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3141,7 +3141,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3192,7 +3192,7 @@
CODE_SIGN_ENTITLEMENTS = WatchWidget/ProdWatchWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3250,7 +3250,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3301,7 +3301,7 @@
CODE_SIGN_ENTITLEMENTS = WatchWidget/CanaryWatchWidget.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3358,7 +3358,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
Expand Down Expand Up @@ -3407,7 +3407,7 @@
CODE_SIGN_ENTITLEMENTS = RideSessionActivity/ProdRideSessionActivity.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3459,7 +3459,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down Expand Up @@ -3678,7 +3678,7 @@
CODE_SIGN_ENTITLEMENTS = ProdAppClip/ProdAppClip.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3734,7 +3734,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3784,7 +3784,7 @@
CODE_SIGN_ENTITLEMENTS = CanaryAppClip/CanaryAppClip.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down Expand Up @@ -3842,7 +3842,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2910;
CURRENT_PROJECT_VERSION = 2911;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = E6R2G33Z36;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
Expand Down
39 changes: 39 additions & 0 deletions src/hooks/useWrongDirectionDetector.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,45 @@ describe('useWrongDirectionDetector (hysteresis)', () => {
expect(result.current.isLoopLineWrongDirection).toBe(false);
});

it('静止したまま小さなGPSノイズで揺れ続けても逆方向と判定されない', () => {
// #6967: 増加だけを累積し、ノイズトレランス以内の減少を相殺しないと、
// 実際には動いていなくても累積が単調に伸びて閾値に達する。
// 0.00009 度 ≒ 8m の往復なので、位置は 8m の帯から一歩も出ていない。
const NOISE_LON_DELTA = 0.00009;

const store = createStore();
seedStore(store);

const { result } = renderDetector(store);

// 旧ロジックでは 76 サンプル目(38 往復)で累積が 300m に達していた
for (let i = 0; i < 200; i += 1) {
act(() =>
setLocationLon(
store,
i % 2 === 0 ? BASE_LON : BASE_LON - NOISE_LON_DELTA
)
);
}

expect(result.current.isWrongDirection).toBe(false);
expect(result.current.isLoopLineWrongDirection).toBe(false);
});

it('ノイズ以下の後退を挟んでも、実際に遠ざかっていれば逆方向と判定される', () => {
const store = createStore();
seedStore(store);

const { result } = renderDetector(store);

act(() => setLocationLon(store, BASE_LON));

// 100m 級の西進のあいだに、ノイズトレランス以内(約 8m)の東進を挟む
advanceWest(store, [-0.001, 0.00009, -0.001, -0.001, -0.001, -0.001]);

expect(result.current.isWrongDirection).toBe(true);
});

it('公開フックは atom を読むだけで、Effectフックを呼ばなくても初期値を返す', () => {
const store = createStore();
const wrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => (
Expand Down
36 changes: 25 additions & 11 deletions src/hooks/useWrongDirectionDetector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useNextStation } from './useNextStation';

// 連続何回の距離増加で逆方向と判定するか
const WRONG_DIRECTION_CONSECUTIVE_COUNT = 4;
// 逆方向判定に必要な最小累積距離(m)
// 逆方向判定に必要な、最接近点からの最小の正味距離(m)
const WRONG_DIRECTION_MIN_DISTANCE = 300;
// GPSノイズとみなして無視する減少幅(m)。これ以下の減少では検知カウンタを維持する
const WRONG_DIRECTION_NOISE_TOLERANCE = 10;
Expand Down Expand Up @@ -56,8 +56,10 @@ export const useWrongDirectionDetectorEffect = (): void => {
const prevDistanceRef = useRef<number | null>(null);
// 連続で距離が増加した回数
const consecutiveIncreaseCountRef = useRef(0);
// 連続増加中の累積距離(m)
const cumulativeIncreaseRef = useRef(0);
// 連続増加中に次駅へ最も近づいたときの距離(m)。「遠ざかった距離」はここからの
// 正味の差で測る。正の増加だけを足し込む累積だと、ノイズとして無視した小さな
// 減少が相殺されず、静止していてもGPSの揺れだけで単調に伸びる(#6967)
const nearestDistanceRef = useRef<number | null>(null);
// 通知済みのnextStation ID(undefinedは未設定、null/numberは通知済み駅ID)
const notifiedForStationIdRef = useRef<number | null | undefined>(undefined);
// 前回のnextStation ID(駅変更検知用)
Expand Down Expand Up @@ -89,7 +91,7 @@ export const useWrongDirectionDetectorEffect = (): void => {
const resetDetectionState = useCallback(() => {
prevDistanceRef.current = null;
consecutiveIncreaseCountRef.current = 0;
cumulativeIncreaseRef.current = 0;
nearestDistanceRef.current = null;
notifiedForStationIdRef.current = undefined;
writeState(false, false);
}, [writeState]);
Expand Down Expand Up @@ -149,31 +151,43 @@ export const useWrongDirectionDetectorEffect = (): void => {
const prevDistance = prevDistanceRef.current;
prevDistanceRef.current = currentDistance;

// 初回測定は比較対象がないのでスキップ
// 初回測定は比較対象がないので、正味の増加を測る起点だけ置いて終了する
if (prevDistance == null) {
nearestDistanceRef.current = currentDistance;
return;
}

const increase = currentDistance - prevDistance;

if (increase > 0) {
// 遠ざかった: 連続カウンタと累積距離を伸ばす
// 遠ざかった: 連続カウンタを伸ばす
consecutiveIncreaseCountRef.current += 1;
cumulativeIncreaseRef.current += increase;
} else if (increase < -WRONG_DIRECTION_NOISE_TOLERANCE) {
// 明確に近づいた: 連続カウンタをリセット
// 明確に近づいた: 連続カウンタをリセットし、起点も現在地へ張り直す
// (= 正味の増加を 0 に戻す)。
// ただし wrongDirectionDetected 自体は据え置き、通知発火済みフラグも維持する。
// 一度逆方向と判定された後、GPSノイズで一時的に近づいたとしても、
// 次駅が変わるか到着するまでは「逆方向状態」のまま扱う
consecutiveIncreaseCountRef.current = 0;
cumulativeIncreaseRef.current = 0;
nearestDistanceRef.current = currentDistance;
}
// 上記いずれにも当てはまらない小さな減少は GPS ノイズとして無視する
// 小さな減少は GPS ノイズとして連続カウンタを落とさない(ヒステリシス)。
// ただし起点の更新は増減に関わらず行うため、距離そのものには反映される。

// 起点より近づいたら起点を更新する。無視した小さな減少もここで効くので、
// 静止中の揺れでは正味の増加が伸びない
const nearestDistance =
nearestDistanceRef.current == null
? currentDistance
: Math.min(nearestDistanceRef.current, currentDistance);
nearestDistanceRef.current = nearestDistance;
// 最接近点からの正味の増加距離(m)
const netIncrease = currentDistance - nearestDistance;

if (
consecutiveIncreaseCountRef.current >=
WRONG_DIRECTION_CONSECUTIVE_COUNT &&
cumulativeIncreaseRef.current >= WRONG_DIRECTION_MIN_DISTANCE
netIncrease >= WRONG_DIRECTION_MIN_DISTANCE
) {
// 同一のnextStationに対して既に通知済みならスキップ
if (
Expand Down
Loading