实现预定流程全链路: 任务状态机 + 编排器 + 地面站 + 真机/SITL入口
- utils/task_runner: 6态状态机(WAIT→ARM_TAKEOFF→GOTO(L2)→TRACK(L1)→APPROACH→RTL) + 编排器(快照采集/状态动作) + 双层日志(事件JSONL/遥测CSV) + 吊舱控制指令(0x07/0x0F/0x0E/0x08) - pod_bridge: ground_link 地面坐标UDP注入(超龄判无效,无激光替代表4); set_heading_servo_enabled() 运行时L1/L2切换(切换即reset清积分防输出跳变); pod_locked 提为公共门控; config 新增 ground_inject 段 - virtual_pod 模拟吊舱(无电机语义) + verify_px4 增量④仅飞控验证 + pod_sitl_test L1 SITL全流程(飞行编排不塞进 run_bridge, 保持纯offboard闭环入口) - 入口: task_runner_sitl(VirtualPod+虚拟目标, SITL端到端跑通约1m24s) / task_runner_real(真串口+UDP注入+吊舱控制) - 地面站 ground_station: 坐标注入 + 状态可视化(Flask) - S1标定回填(2026-10-09): beta_sign=+1 / alpha_sign=-1, 加标定回归测试守护 - 新增测试: task_runner x4 + ground_link/virtual_pod*/bridge/px4_gateway 增量; 全量 483 passed - 文档: 预定流程(需求) + 预定流程-操作指南(操作/待办) + L1方案补S1结论与实现状态
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""px4_gateway.py —— PX4(MAVSDK) 侧网关:读飞控遥测 + 发 offboard 速度指令。
|
||||
|
||||
职责(桥接的飞控侧):
|
||||
* 订阅 PX4 遥测(position / attitude_euler / gps_info / velocity_body),缓存为
|
||||
* 订阅 PX4 遥测(position / attitude_euler / gps_info / velocity_ned),缓存为
|
||||
OwnState 快照,供桥接层构造 表3(载机姿态下发) 与 GuidanceInput(引导输入);
|
||||
* 复用 visual_track_control.MavsdkCommandGateway 发送 offboard 速度设定点
|
||||
(不重造三分支映射,直接喂 GuidanceLaw 的 ControlOutput)。
|
||||
@@ -98,9 +98,11 @@ class Px4Gateway:
|
||||
self._state.position_time_ms = now # 仅此流刷新,姿态高频流不得代刷
|
||||
|
||||
def update_attitude(self, e: Any) -> None:
|
||||
self._state.roll_rad = float(e.roll_rad)
|
||||
self._state.pitch_rad = float(e.pitch_rad)
|
||||
self._state.yaw_rad = float(e.yaw_rad)
|
||||
"""MAVSDK attitude_euler() 返回 EulerAngle(roll_deg/pitch_deg/yaw_deg,度),
|
||||
转弧度存入 OwnState(下游控制律统一用弧度 NED)。"""
|
||||
self._state.roll_rad = math.radians(float(e.roll_deg))
|
||||
self._state.pitch_rad = math.radians(float(e.pitch_deg))
|
||||
self._state.yaw_rad = math.radians(float(e.yaw_deg))
|
||||
self._state.has_attitude = True
|
||||
self._state.time_ms = self._now_ms()
|
||||
|
||||
@@ -110,9 +112,11 @@ class Px4Gateway:
|
||||
self._recompute_valid()
|
||||
self._state.time_ms = self._now_ms()
|
||||
|
||||
def update_velocity_body(self, v: Any) -> None:
|
||||
def update_velocity_ned(self, v: Any) -> None:
|
||||
"""MAVSDK velocity_ned() 返回 VelocityNed(north/east/down_m_s),
|
||||
水平合速度即地速(表3 ground_speed 语义)。"""
|
||||
self._state.ground_speed_mps = math.hypot(
|
||||
float(v.forward_m_s), float(v.right_m_s))
|
||||
float(v.north_m_s), float(v.east_m_s))
|
||||
self._state.time_ms = self._now_ms()
|
||||
|
||||
def own_state(self) -> OwnState:
|
||||
@@ -125,7 +129,9 @@ class Px4Gateway:
|
||||
|
||||
# --- 遥测订阅(异步胶水)----------------------------------------------
|
||||
async def start_telemetry(self) -> None:
|
||||
"""订阅四路遥测流,后台任务持续刷新缓存。"""
|
||||
"""订阅四路遥测流,后台任务持续刷新缓存。幂等:已订阅则直接返回。"""
|
||||
if self._tasks:
|
||||
return # 已订阅,避免重复起任务(runner 会先订阅,bridge.start 再触发时跳过)
|
||||
t = self._drone.telemetry
|
||||
self._tasks = [
|
||||
asyncio.ensure_future(self._consume(t.position(), self.update_position)),
|
||||
@@ -133,7 +139,7 @@ class Px4Gateway:
|
||||
self._consume(t.attitude_euler(), self.update_attitude)),
|
||||
asyncio.ensure_future(self._consume(t.gps_info(), self.update_gps)),
|
||||
asyncio.ensure_future(
|
||||
self._consume(t.velocity_body(), self.update_velocity_body)),
|
||||
self._consume(t.velocity_ned(), self.update_velocity_ned)),
|
||||
]
|
||||
logger.info("[Px4Gateway] 遥测订阅已启动")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user