feat(control-station): add rover scene telemetry and guarded keyboard control

This commit is contained in:
DCCONSTRUCTIONS
2026-09-25 16:37:57 +03:00
parent 63cbb08ea0
commit 6d772b29fe
36 changed files with 3536 additions and 21 deletions
@@ -0,0 +1,38 @@
import {AuthorityModel, type Decision} from '../../../../packages/rover-control/src/authority';
import {type ControlProfile} from '../../../../packages/rover-control/src/profile';
/** Synthetic event replay, with no wall clock, I/O, timers or hardware adapter. */
export function trace(profile: ControlProfile): {label: string; decision: Decision}[] {
const model = new AuthorityModel(profile, ['left', 'right'], {
maxAgeMs:100, neutralMs:200, maxCommandMs:100, monitoredAxes:['leftY','rightY','leftX','rightX'],
}, 'preview');
const rows: {label:string;decision:Decision}[] = [];
let now = -50, token = '';
function step(value=0, link: 'live'|'lost'='live', core=false, request=false) {
now+=50;
const axes = {leftY:0,rightY:0,leftX:0,rightX:0};
axes[profile.mode==='tank'?'leftY':profile.stick==='left'?'leftY':'rightY']=value;
return model.step({now, link:{state:link,at:now},
axes:Object.fromEntries(Object.entries(axes).map(([key,v])=>[key,{value:v,at:now,sequence:now}])),
drives:{left:{healthy:true,stopped:value===0,at:now},right:{healthy:true,stopped:value===0,at:now}},
requestCore:request?{owner:'autonomy',at:now,sequence:1}:undefined,
command:core?{token,at:now,expires:now+75,sequence:now,demand:{left:.4,right:.4}}:undefined,
});
}
const add=(label:string,decision:Decision)=>rows.push({label,decision});
for(let i=0;i<5;i++)step();
const grant=step(0,'live',false,true);token=grant.token??'';
add('Mission Core получил явный допуск',grant);
add('Автономная команда движения',step(0,'live',true));
add('Первое отклонение рычага',step(.8,'live',true));
for(let i=0;i<20;i++)step(.8);
add('Тот же рычаг удерживается',step(.8));
add('Остановка подтверждена, оба рычага отпущены',step());
for(let i=0;i<3;i++)step();
add('Непрерывная нейтраль подтверждена',step());
add('Второе отклонение — ручное движение',step(.8));
add('Запоздавшая команда прежней задачи',step(.8,'live',true));
add('Радиосвязь потеряна',step(0,'lost'));
add('Связь вернулась с отклонённым рычагом',step(.8));
return rows;
}