Update fleet manual remote scaling

This commit is contained in:
2026-07-15 14:01:46 +08:00
parent 68dd6fc061
commit 2ade94f196
8 changed files with 83 additions and 160 deletions
+46 -21
View File
@@ -37,14 +37,17 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
[AsLowerIO(desc = "(手动)多车联动模式")] public int MultiVehicleManualMode;
[FieldMember(desc = "多车联动已同步")] public bool MultiVehicleAligned;
[AsLowerIO(desc = "多车联动:遥控器Vx")] public float MultiVehicleManualVx;
[AsLowerIO(desc = "多车联动:遥控器Vy")] public float MultiVehicleManualVy;
[AsLowerIO(desc = "多车联动:遥控器Vth")] public float MultiVehicleManualVth;
[AsLowerIO(desc = "多车联动:遥控器Vx比例")] public float MultiVehicleManualVx;
[AsLowerIO(desc = "多车联动:遥控器Vy比例")] public float MultiVehicleManualVy;
[AsLowerIO(desc = "多车联动:遥控器Vth比例")] public float MultiVehicleManualVth;
[AsLowerIO(desc = "多车联动:遥控暂停")] public bool MultiVehicleHold;
// ===== Clumsy 侧脚本/动作驱动的手动等价输入(不走 Medulla IO,不会被 IO 同步覆盖)=====
// 手动 IO 字段是 [AsLowerIO]Medulla→ClumsyMedulla 每周期回写),Clumsy 侧 MovementTest 写它们会被覆盖。
// 因此提供这组内部字段,让 Clumsy 侧动作(如 FleetRotateInPlace)能像 FleetRemote 一样驱动车队联动
// ScriptEnabled=使能;Mode 0=常规 1=蟹行 2=原地旋转;Vx/Vy/Vth 语义与手动遥控完全一致(m/s、m/s、deg/s
// 因此提供这组内部字段,让 Clumsy 侧动作(如 FleetRotateInPlace)能像 FleetRemote 一样驱动车队联动
// ScriptEnabled=使能;Mode 0=常规 1=蟹行 2=原地旋转。
// 注意:Medulla 遥控 IO 是归一化摇杆比例;脚本字段保持物理量,避免动作参数再被 FleetManual* 二次缩放。
// Mode0: Vx=m/s, Vth=目标舵角degMode1: Vx=m/s, Vy=蟹行舵角degMode2: Vth=角速度deg/s。
[FieldMember(desc = "多车联动:脚本驱动使能")] public bool MultiVehicleScriptEnabled;
[FieldMember(desc = "多车联动:脚本驱动模式")] public int MultiVehicleScriptMode;
[FieldMember(desc = "多车联动:脚本驱动Vx")] public float MultiVehicleScriptVx;
@@ -214,7 +217,7 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
DLog.Log(
$"INPUT master={isMaster} endpoint={Conf.MultiVehicleMasterEndpoint} selfEndpoint={Conf.MultiVehicleSelfEndpoint} car={CarNum} " +
$"rawEn={MultiVehicleManualEnabled} rawMode={MultiVehicleManualMode} rawVx={MultiVehicleManualVx:0.000} rawVy={MultiVehicleManualVy:0.000} rawVth={MultiVehicleManualVth:0.000} " +
$"rawEn={MultiVehicleManualEnabled} rawHold={MultiVehicleHold} rawMode={MultiVehicleManualMode} rawVx={MultiVehicleManualVx:0.000} rawVy={MultiVehicleManualVy:0.000} rawVth={MultiVehicleManualVth:0.000} " +
$"scriptOn={scriptOn} effEn={manualEnabled} effMode={manualMode} effVx={manualVx:0.000} effVy={manualVy:0.000} effVth={manualVth:0.000} " +
$"auto={autoEnabled} notifFresh={notifFresh} notifAgeMs={notifAgeMs:0} fleetCnt={fleetCnt}/{Conf.MultiVehicleFleetNum}",
"MultiVehicleRemoteDbg");
@@ -624,6 +627,7 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
var manualVx = scriptOn ? MultiVehicleScriptVx : MultiVehicleManualVx;
var manualVy = scriptOn ? MultiVehicleScriptVy : MultiVehicleManualVy;
var manualVth = scriptOn ? MultiVehicleScriptVth : MultiVehicleManualVth;
var manualHold = !scriptOn && MultiVehicleHold;
VehicleSyncNotification activeNotification = null;
if (isMaster)
@@ -660,7 +664,7 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
Math.Max(300, Conf.MultiVehicleSyncInterval * 5);
FleetDiag(
$"ENTRY master={isMaster} | IO: ManualEn={MultiVehicleManualEnabled} Mode={MultiVehicleManualMode} " +
$"Vx={MultiVehicleManualVx:0.000} Vy={MultiVehicleManualVy:0.000} Vth={MultiVehicleManualVth:0.0} AutoEn(IO)={MultiVehicleAutoEnabled} " +
$"Hold={MultiVehicleHold} Vx={MultiVehicleManualVx:0.000} Vy={MultiVehicleManualVy:0.000} Vth={MultiVehicleManualVth:0.0} AutoEn(IO)={MultiVehicleAutoEnabled} " +
$"| SCRIPT en={MultiVehicleScriptEnabled} mode={MultiVehicleScriptMode} Vx={MultiVehicleScriptVx:0.000} Vy={MultiVehicleScriptVy:0.000} Vth={MultiVehicleScriptVth:0.0} " +
$"| gate: manualEnabled={manualEnabled} autoEnabled={autoEnabled} notifFresh={notifFresh} " +
$"notifManualEn={(MultiVehicleNotification != null ? MultiVehicleNotification.ManualEnabled.ToString() : "null")} " +
@@ -681,7 +685,7 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
ResetMultiVehicleRotateCenterDrift();
LogMultiVehicleRemoteDecision(
$"RETURN_IDLE master={isMaster} rawEn={MultiVehicleManualEnabled} scriptOn={scriptOn} auto={autoEnabled} " +
$"rawMode={MultiVehicleManualMode} rawVx={MultiVehicleManualVx:0.000} rawVy={MultiVehicleManualVy:0.000} rawVth={MultiVehicleManualVth:0.000}");
$"rawHold={MultiVehicleHold} rawMode={MultiVehicleManualMode} rawVx={MultiVehicleManualVx:0.000} rawVy={MultiVehicleManualVy:0.000} rawVth={MultiVehicleManualVth:0.000}");
UI.GetPainter("MultiVehicleFleet-vis", false).Clear();
sendMotionPainter.Clear();
lock (FleetLock)
@@ -762,10 +766,13 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
{
syncTh = 0;
fleetMode = manualMode;
var remoteRatioInput = !scriptOn;
if (fleetMode == 2)
{
// 原地旋转:摇杆左右 → 绕车队中心角速度(deg/s)。底盘 SetOriginBias 已设为车队中心
fleetOmega = manualVth;
// 外部遥控: Vth 为摇杆比例;内部脚本: Vth 为实际角速度(deg/s)
fleetOmega = remoteRatioInput
? ClampFloat(manualVth, -1f, 1f) * Math.Max(0f, Conf.FleetManualMaxRotateOmegaDegPerSec)
: manualVth;
fleetVx = 0;
fleetFrontTh = 0;
fleetRearTh = 0;
@@ -774,12 +781,16 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
}
else if (fleetMode == 1)
{
// 手动蟹行:Vx 只表示线速度,Vy 表示方向摇杆比例(-1..1),由 VyFac 映射为舵角
var speed = manualVx * Conf.ManualCarSyncVxFac;
var crabRatio = Math.Max(-90f, Math.Min(90f, manualVy));
var crabAngle = crabRatio * Conf.ManualCarSyncVyFac;
// 外部遥控: Vx/Vy 为摇杆比例;内部脚本: Vx 为线速度(m/s), Vy 为蟹行舵角(deg)
var speed = remoteRatioInput
? ClampFloat(manualVx, -1f, 1f) * Math.Max(0f, Conf.FleetManualMaxSpeed)
: manualVx;
var crabRatio = remoteRatioInput ? ClampFloat(manualVy, -1f, 1f) : 0f;
var crabAngle = remoteRatioInput
? crabRatio * Math.Abs(Conf.FleetManualMaxCrabAngleDeg)
: manualVy;
crabInputVx = speed;
crabInputVy = crabRatio;
crabInputVy = remoteRatioInput ? crabRatio : crabAngle;
crabRawAngle = crabAngle;
crabSteerLimit = Math.Min(179f, Math.Max(1f, Math.Abs(Conf.MultiVehicleCrabSteerLimitDeg)));
@@ -793,8 +804,13 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
}
else
{
fleetVx = manualVx * Conf.ManualCarSyncVxFac;
var targetTh = manualVth * Conf.ManualCarSyncVthFac;
// 外部遥控: Vx/Vth 为摇杆比例;内部脚本: Vx 为线速度(m/s), Vth 为目标舵角(deg)。
fleetVx = remoteRatioInput
? ClampFloat(manualVx, -1f, 1f) * Math.Max(0f, Conf.FleetManualMaxSpeed)
: manualVx;
var targetTh = remoteRatioInput
? ClampFloat(manualVth, -1f, 1f) * Math.Abs(Conf.FleetManualMaxSteerAngleDeg)
: manualVth;
var now = DateTime.Now;
var dt = (float)Math.Min(0.2, Math.Max(0, (now - _multiVehicleLastThTime).TotalSeconds));
_multiVehicleLastThTime = now;
@@ -804,6 +820,17 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
fleetFrontTh = _multiVehicleAccumulateTh;
fleetRearTh = -fleetFrontTh;
}
if (manualHold)
{
fleetMode = 0;
fleetVx = 0;
fleetFrontTh = 0;
fleetRearTh = 0;
fleetOmega = 0;
_multiVehicleAccumulateTh = 0f;
_multiVehicleLastThTime = DateTime.Now;
}
}
else
{
@@ -830,11 +857,9 @@ public class PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefin
}
}
}
else if (MultiVehicleNotification != null)
else if (activeNotification != null)
{
VehicleSyncNotification notification;
lock (_multiVehicleNotificationLock)
notification = MultiVehicleNotification;
var notification = activeNotification;
syncTh = notification.SyncTh;
syncDistance = notification.SyncDistance;