対象: Issue #107「隣接耕基本経路パターン1をTabletで計画・確認できるようにする」
状態: 2026-08-26利用者承認済みの実装計画(2026-08-27、2026-08-28、2026-08-29にTrack 2の筆決定・
入口候補方式・軌跡管理基盤、2026-08-30に横断前予測入口の最短経路方式を利用者承認により改訂)
正本: 製品挙動はdocs/specifications/adjacent-tillage-basic-route-pattern-1.md、圃場幾何契約は
docs/runbooks/navigation-field-geometry-pipeline-contract-pattern-1.md、UI規範は
docs/standards/ui-design-guidelines.mdを優先する。
PC simulator-uiで検証済みのPattern 1を、Android Tablet上で実際の筆・入口・Profile・中央耕方向から生成し、
完成計画を確認して今回使用する計画として決定・保持できるようにする。
完了範囲は次のとおり。
FinalTillagePlanResult.SolvedだけをTabletで完成計画としてpreviewする。TillagePlanを端末へ保持し、再起動後も再表示できるようにする。走行中のaction進捗、逸脱判定、作業機操作、音声・画面誘導、作業完了判定は後続Issueとする。複数pattern選択、
registry/socket、plugin、DSL、外部package、動的Profile schema、汎用入出力契約も実装しない。
:track-coreに置く1つのproduction serviceをPCとTabletが呼ぶ。TillagePlanRequestはFieldSnapshot、EntranceSnapshot、ProfileSnapshot、CenterDirectionSelectionの4要素を維持する。現行コードのFieldPlanningGeometry.resolveEntranceは、入口が筆頂点の許容誤差内にある場合、
explicitCirculationAtCornerが無ければAmbiguousEntranceCornerで停止する。PCの
FieldPlanPreviewRequestはこの値を独立フィールドとして持つが、契約上のTillagePlanRequestには存在しない。
また、現行EntranceSnapshotはこの確認値を保持できない。
入口producerで一度解決しても、確認値をsnapshotに保存しなければStage 3で失われる。そのため、単にTablet UIから
一時値をplannerへ渡す実装は禁止する。
EntranceSnapshotへnullableなcirculationAtCorner: PerimeterCirculation?を追加する。
null。入口位置から一意に導入側circulationを解決する。AmbiguousEntranceCornerで停止する。TillagePlanRequestへ独立したexplicitCirculationAtCornerを追加しない。PC側の独立requestフィールドは移行期間だけadapter入力として受け、共通production serviceを呼ぶ前に
EntranceSnapshot.circulationAtCornerへ統合する。移行完了後、production pipeline内部へ独立値を渡さない。
各実装Trackはコード変更前に仕様適合規約の契約対応表をIssue本文またはtrack_recordへ保存する。
表の全項目が埋まるまで実装へ進まない。
角上入口の確認値を失わないdomainへ移行し、PC/Tabletが共有するPattern 1の唯一のproduction実行入口を
:track-coreへ置く。幾何規則は変更しない。
EntranceSnapshotへcirculationAtCornerを追加し、既存生成箇所を辺上入口のnullへ移行する。resolveFixedTillageConstraintsは独立引数ではなくsnapshot内の確認値を消費する。TillagePlanRequestと結果型を:track-coreへ追加する。:track-coreへ追加する。FieldPlanPreviewServiceを共通serviceへ委譲するPC adapterへ縮小する。NavGeometryWarning.AmbiguousEntranceCornerの古い説明を実際の挙動へ合わせる。TillagePlanの全field、action順、role、type、座標、residualが一致する。:track-core:test:pc-tool:testnavigationContractConformanceassembleReleaseTillagePlanPipelineResult全体、完成TillagePlanのTrack 1は既にPCで検証済みのplannerを共通serviceへ抽出する内部移行であり、Tabletのproduction producer・
workflow・previewはまだ存在しない。同じPC入力・PC表示・plannerを再度目視してもTablet配線や実用性の証拠には
ならないため、Track 1だけは上記の完全一致fixtureを可視化gateの代替証拠とする。入口、導入/仕上げcirculation、
3→1→2、exit、residualを含む完成仮計画の利用者可視化は、Tablet production inputから成立するTrack 3で行う。
fixture値を直接注入せず、Tabletのbundled筆と実際の位置・利用者操作からFieldSnapshotと
確認済みEntranceSnapshotを生成する。
境界横断までの点列から平均進行方向を求める方式へ変更、軌跡管理基盤を統合し検出済み候補を
identityベースで保持する方式へ変更、横断前予測を現在位置から最近傍境界点への最短経路へ変更。その後の
利用者確認で入口producerを筆決定時の単発スナップショットへ変更し、距離範囲query・参考用exit廃止を確定)
appにbundled fude-overlay.geojsonを読むTablet専用reader/repositoryを追加する。EntranceSelectionState: Idle/SelectingField/Selecting/AwaitingCornerCirculation/Confirmed)上で排他的に表す。TrajectoryMemory(表示用)・RecentFixHistory(入口検出用)・外部記録の3系統でTrajectoryRepository(track-core)へ統合した。参照用軌跡TrajectoryReferenceHistory、旧TrajectoryMemory)は記録ON/OFFに関わらず常時更新される単一の.dtrkファイルへのTrajectoryRecorder出力)だけを制御する。RecentFixHistoryは廃止した。TrajectoryRepositoryは、最新点から過去方向へ遡った累積走行距離の指定範囲をCold+Hotの保持中折れ線からqueryByTravelDistance(fromLatestM, toLatestM)相当、入力は0以上の有限値かつfromLatestM <= toLatestM、返却順は古い点→新しい点とし、不正値を黙って補正しない。実横断判定にはcirculationAtCornerとして同じsnapshotへ保存する。EntranceSnapshotは保持し、Resetは明示的な取消操作でだけdispatchする。pc-toolのFieldGeoJsonReaderはJVM専用であり、Android appから直接再利用しない。reader同士を依存させず、
同じGeoJSON fixtureとcanonical expected valueを両moduleのテストで使用する。
比較対象はpolygon UUID、geometry種別、polygon数、shell/holes、座標順、全緯度経度とする。Polygon、MultiPolygon、
穴あり、不正geometry、UUID未検出を含める。最終的なplan parityはTrack 5で別に検証する。
WorkMenu「耕うん計画を作成」(現在地包含筆の自動選択、0件・複数件なら筆選択モード→地図タップ)
→ 筆決定時に1回だけ、登録入口、筆外現在位置から最近傍境界点への予測、筆内なら過去Hotからの実横断復元、または利用者方向指定
→ 利用者確認 → EntranceSnapshot
辺中点、入口座標、CW/CCWをfixtureからplan requestへ直接注入した試験はcontract fixtureとして分類し、
production配線の証拠にはしない。
:app:testDebugUnitTest:track-core:testnavigationContractConformanceassembleReleaseConfirmedのField/EntranceSnapshotが保持され、Track 3相当のEntranceSnapshotへ到達Track 2の筆・入口、active Profile、中央方向を一続きの製品workflowへ統合し、共通production serviceから
完成計画または構造化停止原因を得る。完成仮計画の地図表示、方向編集、再計算、失敗表示、作り直し、
計画終了、「この計画を使う」で後続の正式承認工程へ渡す境界までを所有する。
計画未開始
→ 筆選択中
→ (共通事前判定で対象外・データ不良: この経路計画を使用できない)
→ 入口確認中
→ 角入口の外周方向確認中
→ 作業機設定不正 / 初回計算中
→ 完成仮計画表示中 ⇄ 自由回転調整中 ⇄ 再計算中
→ 条件変更で再作成可能な失敗 / この経路計画を使用できない失敗
→ 後続の正式承認工程へ渡せる状態
製品上の状態を単一sealed stateで排他管理し、複数Booleanで画面状態を表さない。Track 2の筆・入口選択
ロジックを再利用するが、後段と別workflowとして独立進行させない。確認済みFieldSnapshotと
EntranceSnapshotを値のまま単一workflowへ引き継ぎ、Boolean群へ再エンコードしない。
計算は純粋な状態遷移処理の中で同期実行しない。画面を止めない実行担当からTablet productionで唯一の
Pattern1TillagePlanService.planを呼び、成功・失敗・キャンセルを明示イベントとして状態へ戻す。
実行中だけ有効な編集識別子と再計算番号を持ち、現在の編集識別子、最新番号、未キャンセル、入力一致を
満たす結果だけを採用する。二重起動を防ぎ、古い結果を破棄する。
同じアプリ処理が生きている間は、設定画面往復、別アプリ、画面消灯、画面再作成をまたいで未承認計画と
編集状態をプロセス内共有状態へ保持する。アプリ処理終了、強制終了、新規起動、端末再起動では破棄する。
未承認計画、編集識別子、再計算番号を永続化せず、終了コールバックに依存しない。
ProfileSnapshotへ変換して再利用する。centerTillageDirectionCandidates、既存順・重複除去なし、0°/360°境界を正しく扱い角度差最小、同差ならdefaultCenterTillageHeadingDeg規則を廃止)。筆と入口が確定した時点で1回だけ決定し、CenterDirectionSelectionに専用の由来(InitialProvisional)を持たせ、利用者がfinishingLap3StartAnchorを先に固定し、中央laneを各WorkAreaのlateral範囲からProfileの(WorkArea, 構成)の終端隅からfinishingLap3StartAnchorまで、仕上げcirculationと同じheadingDegと揃った到着、逆走・U ターンなし)を求める。finishingLap3StartAnchorまで実際にたどる空走経路長が最短のものを終端WorkArea/構成(workAreaIndex, 構成index)昇順)。全候補が不可ならCENTER_GEOMETRY_OPERATION_FAILED。CenterTillagePassとFinishingLap(3)本体の間にこの空走をDEADHEAD固定FinishingLapApproach(3)=耕したまま接続するTILLとは別role)として1本置く。#115で設けた「中央耕終了→CenterPass終点 → 空走 → FinishingLap(3)始点をfinishingLap3StartAnchorの座標一致は完成条件にしない。DEADHEAD固定TILLへ変えない。覆われないと判明したらDEADHEAD_TRACE_NOT_COVEREDで停止)。中央列間・WorkArea間overlapWidthCm / 100.0メートルだけ外周側へbufferし、fieldでclipしたcenterWorkRemainingRegionを中央耕の被覆対象とする。中央laneはProfileの固定pitchで並べ、対象幅へのCENTER_GEOMETRY_OPERATION_FAILED、中央未耕はCENTRAL_UNTILLED_AREA_REMAINS、空走が後続外周耕で覆えないDEADHEAD_TRACE_NOT_COVERED、合成後のaction境界の座標断絶はROUTE_DISCONTINUOUSとする。「中央からCENTER_TO_FINISHING_CONNECT_FAILED)とINTERNAL_TRANSFER stageは復活させない。finishingLap3StartAnchor.pointの座標差だけを理由に停止させない。centerTillageDirectionCandidatesによる代表辺候補を既存順で巡回し、初期仮方向として選ばれた候補の次からFieldPlanningGeometry.classifyFieldForPattern1の共有判定で決め、Tabletの計画開始前判定とSeedHeadingUnavailable)・イベント・画面・専用問い合わせコード・専用テストは設けない。単一workflowにはPattern1PlanState.FieldUnusableForPattern1を持つ。正常な対応筆は辺候補が最低1件得られることをSolvedだけを完成仮計画として地図へ表示する。code、stage、nature、implicatedInputsだけを持つ構造化原因をNOT_IMPLEMENTEDで停止する。重複した3周計画をFieldUnusableForPattern1)CenterTillagePassの直後が「任意で1本の中央耕終了→lap 3空走(ロータリー上げDEADHEAD、role はFinishingLapApproach以外)、その直後にlap 3本体」であり間に他のactionが無いこと、FinishingLapApproach(3)CenterPass終点 → 空走 → FinishingLap(3)始点を含む全境界が座標連続であること。最後の中央pass終点とfinishingLap3StartAnchorのROUTE_DISCONTINUOUSにならないことを確認する。根拠のない専用接続centerWorkRemainingRegionの拡張量、固定pitch、中央TILLCenterTillageLaneChange)の分類test(全区間が後続TILLで覆われるケースはDEADHEAD、e726ebb6(再現入口 (33.204093667, 133.105705438)、進入方向 108.899°、初期仮方向はinitialProvisionalHeading で算出)では、入口→開始前移動(計画外)→北東側 center start→中央耕NOT_IMPLEMENTEDとなり、重複3周計画を返さないfixture:track-core:test、:app:testDebugUnitTest、:pc-tool:test、:pc-tool:testSimulatorUiTs、navigationContractConformance、assembleRelease(JDK21)仮計画の地図表示、辺方向回転、自由回転、再計算、失敗表示、作り直し、計画終了、
「この計画を使う」の受け渡し境界はTrack 3が所有する。Track 4はその後の正式承認、決定snapshotの
永続化・再起動復元、ナビゲーション移行を所有する。
正式承認以降の利用者画面には次だけを表示する。
centerTillageStartAnchorと走行方向内部Stage、candidate lane、WorkArea候補、diagnostic partial、入口から中央開始までの線、入口境界外の退出線は
実行可能表示に含めない。作業地図へ常設ボタンを増やさず、段階別パネルと下部ドックの主操作を使う。
Track 3で「この計画を使う」が受理された計画について、次をversion付きの1 snapshotとして原子的に保存する。
TillagePlan破損、不明schema、未対応pattern versionは自動補完せず、計画を使用不可として理由を表示する。旧snapshotを残したまま
新計画を部分書込みしない。再起動後はpreviewを復元するが、誘導は自動開始しない。
navigationContractConformance、:app:testDebugUnitTest、assembleReleaseFieldでplan parityまで到達する。PCは自動parity fixtureの実行環境およびTabletとの差異が出た場合の診断用比較環境として使い、同じplannerを
同じPC表示で再確認すること自体を利用者gateにはしない。
実地試用だけのTrackであっても、確認手順、入力、端末build、plan ID/version、結果、差異をTrackへ記録する。
各境界で対象test、machine gate、release buildをgreenに保つ。
EntranceSnapshot移行、角上入口fixture、PC request adapter反転。コードだけを先に入れて既存テスト反転を後続コミットへ送らない。production producer未配線の状態をfixture producerで
完成扱いにしない。
次のいずれかが必要になった場合は実装を停止し、契約変更として利用者承認へ戻す。
circulationAtCorner以外の新しい入口曖昧性解消値。各Trackは次の表を具体的な型・関数・test名で埋めてから開始する。
| 必須項目 | Trackで記録する内容 |
|---|---|
| 対象Stage | Stage 0〜11の対象番号・見出し |
| 農作業上の起点 | 筆選択、圃場進入、入口確認、Profile/方向操作等 |
| 入力 | 型と直前Stage |
| producer provenance | production、利用者確認、fallback、fixture/testを分離 |
| 出力 | 型、consumer、直後Stage |
| 継承条項 | 現行契約からそのまま使う規則・技術 |
| 置換条項 | 旧PC独立引数、旧呼出経路等、無効化する実装 |
| 禁止事項 | 追加しない入力・fallback・候補化 |
| contract fixture | 到達済みA〜Gと角上入口fixture |
| operational E2E fixture | fixture直接注入なしの農作業開始点からの手順 |
| regression fixture | 変更で落ちる既存testと同Track内の反転方法 |
| 可視化gate | PC/Tabletで確認するlayer・値・順序 |
| 停止条件 | 契約変更として利用者承認へ戻す条件 |