diff --git a/README.md b/README.md index 6f9a398..ec0d1c7 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ git config --global user.email "你注册GitHub的邮箱@example.com" # 或者使用更持久的存储(凭据将明文保存在磁盘,请确保系统安全) git config --global credential.helper store ``` -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 + 3. **首次推送时输入凭据:** - 执行 `git push` 等需要鉴权的操作时,Git 会提示输入用户名和密码。 @@ -199,3 +199,18 @@ git push origin feature/your_feature_name 开发完成后,请在 GitHub 页面上针对您的分支发起 **Pull Request (PR)**。由其他团队成员进行 Code Review,确认无误后再 Merge 合并入 `main` 分支。 --- + +关于大文件的处理(可选) +如果你希望优化仓库,可以考虑使用 Git LFS 管理大文件: +bash +复制 +# 1. 安装 Git LFS +git lfs install + +# 2. 追踪大文件(例如 .usd 文件) +git lfs track "*.usd" + +# 3. 提交 .gitattributes 文件 +git add .gitattributes +git commit -m "Add Git LFS tracking for large files" +⚠️ 注意:如果已经提交了大文件到历史记录,需要使用 git lfs migrate 来重写历史,否则只是追踪新文件。 \ No newline at end of file diff --git a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_chassis.proto b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_chassis.proto index 16b803e..5ad10a2 100644 --- a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_chassis.proto +++ b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_chassis.proto @@ -1,89 +1,137 @@ syntax = "proto3"; -// 规范包名,确保与运控调优(control)和传感器外参(sensor)在逻辑上严格物理隔离 +// 规范包名:agv.calibration.chassis +// 设计原则:专门负责底盘最底层机械物理特征的开环标定与体检 package agv.calibration.chassis; // ========================================================= // 核心服务:AGV 底盘底层硬件自诊与物理运动学标定代理服务 -// 部署端:Windows车端 (直连底层电机驱动器/PLC 的网关层) -// 调用端:Linux标定服务器 (掌控外部高精雷达真值) +// [部署端 Server]:Windows 车端 (只负责听口令、转电机、报裸数据) +// [调用端 Client]:Linux 车间服务器 (负责发口令、看雷达真值、算误差) // ========================================================= service AgvCalibChassisService { - + // --------------------------------------------------------- - // 1. 底层硬件接管与安全熔断 + // 第一步:权限接管与安全熔断 (剥夺车端算法大脑) // --------------------------------------------------------- - // 强制接管底层驱动器。注意:这里不仅要切断避障,还要切断底盘的“运动学正逆解算法” + // 💻 [Linux 发送 -> Windows]:要求切断底盘运动学逆解,进入纯物理开环直驱模式 + // 🚙 [Windows 返回 -> Linux]:返回接管是否成功的回执 rpc SetDiagnosticMode(DiagnosticModeRequest) returns (StandardResponse); - // 硬件级绝对急停 (直接向驱动器下发 Safe Torque Off / 机械抱死指令,无视任何上层状态) + // 💻 [Linux 发送 -> Windows]:无视一切状态立刻抱死电机的紧急急停指令 + // 🚙 [Windows 返回 -> Linux]:返回急停执行状态 rpc HardwareEmergencyBrake(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 2. 原始物理开环指令下发 (对应方案 4.2 诊断 与 4.3 物理标定) + // 第二步:打开体征监控水龙头 (数字孪生健康诊断) // --------------------------------------------------------- - // 允许 Linux 越过底盘协同模型,直接对指定驱动轮下发最原始的转速(RPM)或占空比 - // 核心用途:暴露真实的机械阻力差、诊断减速机卡死、测试轮胎滑移率 + // 💻 [Linux 发送 -> Windows]:发送空请求,触发高频推流开关 + // 🚙 [Windows 持续流式返回 -> Linux]:以 50Hz 频率持续不断地回传原始脉冲与电流 + rpc StreamHardwareTelemetry(Empty) returns (stream HardwareState); + + // --------------------------------------------------------- + // 第三步:原始物理开环考题下发 (逼迫底盘暴露机械缺陷) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:绕过算法,直接命令指定驱动轮以固定 RPM 盲跑 + // 🚙 [Windows 返回 -> Linux]:返回电机是否已成功按给定 RPM 运转 rpc ExecuteRawDriveCommand(RawDriveRequest) returns (StandardResponse); - // 允许 Linux 直接对转向机构下发绝对物理角度或往复扫频 - // 核心用途:测定舵机机械死区、往复间隙(Backlash)与静态机械零位偏差 + // 💻 [Linux 发送 -> Windows]:直接对转向机构下发绝对物理角度 (测机械装歪的角度) + // 🚙 [Windows 返回 -> Linux]:返回舵机是否已开始执行角度指令 rpc ExecuteRawSteerCommand(RawSteerRequest) returns (StandardResponse); // --------------------------------------------------------- - // 3. 物理运动学本底参数持久化 (出厂定稿写值) + // 第四步:物理本底参数定稿写值 (标定闭环结束) // --------------------------------------------------------- - // Linux 结合外部真值算出真实的物理机械参数后,下发并直接覆写到底盘驱动板 EEPROM 或底层配置中 + // 💻 [Linux 发送 -> Windows]:下发 Linux 结合外部真值算出的绝对物理修正系数 + // 🚙 [Windows 返回 -> Linux]:将系数覆写到本地硬盘/驱动板后,返回成功回执 rpc CommitKinematicParameters(KinematicParams) returns (StandardResponse); - - // --------------------------------------------------------- - // 4. 原始硬件级高频遥测 (数字孪生健康诊断的唯一依据) - // --------------------------------------------------------- - // 🚨 严禁推流经过滤波后的数据!必须是最底层的“原始编码器 Tick”和“绝对相电流”! - rpc StreamHardwareTelemetry(Empty) returns (stream HardwareState); } // ========================================================= // 基础通用消息结构 // ========================================================= + +// 空消息,通常作为触发类请求发送 +// 💻 [流向]:Linux 发送 -> Windows message Empty {} +// 通用应答载荷 +// 🚙 [流向]:Windows 返回 -> Linux message StandardResponse { bool success = 1; - string message = 2; // 异常时返回驱动器底层故障码 (如 "ERR_MOTOR_OVERCURRENT") + string message = 2; // 若失败,返回驱动器底层报错详情 (如 "ERR_MOTOR_OVERCURRENT") } +// ========================================================= +// 1. 权限模式请求载荷 +// ========================================================= +// 💻 [流向]:Linux 发送 -> Windows message DiagnosticModeRequest { enum Mode { - NORMAL_KINEMATICS = 0; // 正常模式 (底盘接收 V_x, Omega,由底层执行运动学逆解分配) - DIRECT_RAW_DRIVE = 1; // 直驱模式 (切断逆解,允许 Linux 直接独立控制左/右轮转速) + NORMAL_KINEMATICS = 0; // 正常模式 (底盘接收 V_x, Omega,由车端执行逆解分配) + DIRECT_RAW_DRIVE = 1; // 直驱模式 (切断逆解,允许 Linux 直接独立下发左/右轮转速) } Mode target_mode = 1; } // ========================================================= -// 2. 原始驱动指令 (发考题:逼迫底盘暴露出机械缺陷) +// 2. 硬件底层遥测推流载荷 (裸数据) // ========================================================= -message RawDriveRequest { - string test_case_id = 1; // 测试用例 (如 "Slip_Test_0.5m", "Straight_Friction_Test") +// 🚙 [流向]:Windows 疯狂上报 -> Linux (50Hz) +message HardwareState { + // 底层获取到脉冲那一瞬间的高精度单调系统时钟 (绝对微秒数) + int64 hardware_timestamp_us = 1; - // 直接下发给电机的原始指令 (若是两驱车,后轮填 0 即可) - double fl_motor_rpm = 2; // 左前轮 (Front-Left) 目标物理转速 (RPM) - double fr_motor_rpm = 3; // 右前轮 (Front-Right) 目标物理转速 (RPM) - double rl_motor_rpm = 4; // 左后轮 (Rear-Left) 目标物理转速 (RPM) - double rr_motor_rpm = 5; // 右后轮 (Rear-Right) 目标物理转速 (RPM) + // --- A. 原始编码器反馈 (Linux 拿它与雷达真值做除法,算真实物理位移与滑移率) --- + // 🚨 严禁返回平滑后的速度(m/s),必须返回最原始的累计脉冲 Ticks! + int64 encoder_ticks_fl = 2; // 左前轮累计脉冲 + int64 encoder_ticks_fr = 3; // 右前轮累计脉冲 + int64 encoder_ticks_rl = 4; + int64 encoder_ticks_rr = 5; - double duration_sec = 6; // 动作维持时间,断网防飞车底线:超时底层必须自动刹车 + // --- B. 物理舵角反馈 (Linux 拿它比对指令响应时间,测定机械死区) --- + double actual_steer_angle_front_deg = 6; + double actual_steer_angle_rear_deg = 7; + + // --- C. 动力与负载健康状态 (Linux 防烧毁熔断的判断依据) --- + // 若维持匀速所需的电流异常激增,说明减速机干涉或刹车未放,Linux 会立刻触发急停 + double current_fl_amp = 8; // 左前电机实际相电流 (安培) + double current_fr_amp = 9; + double current_rl_amp = 10; + double current_rr_amp = 11; + double current_steer_front_amp = 12;// 前转向舵机实际电流 (安培) + + // --- D. 驱动器硬件报警位 --- + uint32 driver_error_code = 13; // 0x00=健康, 0x01=过压, 0x02=堵转过流等 } -message RawSteerRequest { - string test_case_id = 1; // 测试用例 (如 "Deadzone_Sweep_5deg") +// ========================================================= +// 3. 原始动作指令请求载荷 +// ========================================================= +// 💻 [流向]:Linux 发送 -> Windows +message RawDriveRequest { + string test_case_id = 1; // 测试流水号 (如 "Slip_Test_0.5m") - // 针对舵机/转向推杆的绝对物理指令 (度) + // 直接下发给电机的原始指令 (若是两驱车,后轮填 0 即可) + double fl_motor_rpm = 2; // 左前轮目标物理转速 (RPM) + double fr_motor_rpm = 3; // 右前轮目标物理转速 (RPM) + double rl_motor_rpm = 4; + double rr_motor_rpm = 5; + + // 🚨 断网防飞车底线:若超过该时间未收到新指令,车端底层必须自动刹车 + double duration_sec = 6; +} + +// 💻 [流向]:Linux 发送 -> Windows +message RawSteerRequest { + string test_case_id = 1; // 测试流水号 (如 "Deadzone_Sweep_5deg") + + // 针对舵机/转向推杆的绝对物理角度指令 (度) double front_steer_angle_deg = 2; double rear_steer_angle_deg = 3; - // 专门用于 4.2节 测定机械间隙的扫频参数 + // 扫频测试参数 (用于测定机械往复间隙 Backlash) optional double sweep_amplitude_deg = 4; // 往复抖动幅度 (度) optional double sweep_frequency_hz = 5; // 抖动频率 (Hz) @@ -91,53 +139,27 @@ message RawSteerRequest { } // ========================================================= -// 3. 运动学本底参数定稿载荷 (纯物理修正系数) +// 4. 物理运动学本底参数定稿载荷 // ========================================================= +// 💻 [流向]:Linux 发送 -> Windows message KinematicParams { - // --- 1. 真实有效物理轮径 (解决“开环走直线画大弧”及闭环位移不准) --- + // (注:全字段使用 optional,Linux 测了哪一项就只下发哪一项要求车端覆盖,未发的不作修改) + + // --- 1. 真实有效物理轮径 (纠正“开环跑偏”与里程计位移误差) --- optional double wheel_radius_fl_m = 1; optional double wheel_radius_fr_m = 2; optional double wheel_radius_rl_m = 3; optional double wheel_radius_rr_m = 4; - // --- 2. 机械零位绝对偏差补偿 (解决“指令0度但车子斜着跑”) --- + // --- 2. 机械零位绝对偏差补偿 (纠正“指令0度但车子斜着走”) --- optional double steer_zero_offset_front_deg = 5; optional double steer_zero_offset_rear_deg = 6; - // --- 3. 旋转几何协同参数 (解决“原地打转时车体画圆甩尾摆动”) --- - optional double effective_track_width_m = 7; // 有效轮距 (左右轮真实物理间距) - optional double effective_wheel_base_m = 8; // 有效轴距 (前后轮真实物理间距) + // --- 3. 旋转几何协同参数 (纠正“原地打转时车体甩尾晃动”) --- + optional double effective_track_width_m = 7; // 左右轮真实物理有效轮距 (m) + optional double effective_wheel_base_m = 8; // 前后轮真实物理有效轴距 (m) - // 针对四驱四转等多舵轮底盘:瞬时旋转中心(ICR)的物理几何偏移 + // 针对多舵轮底盘:瞬时旋转中心(ICR)的物理几何偏移 optional double icr_offset_x_m = 9; optional double icr_offset_y_m = 10; -} - -// ========================================================= -// 4. 原始硬件遥测数据流 (Linux 用来排雷、熔断和算滑移率的裸数据) -// ========================================================= -message HardwareState { - int64 hardware_timestamp_us = 1; // 底层获取到脉冲那一瞬间的高精度单调系统时钟 (微秒) - - // --- A. 原始编码器反馈 (用于 4.2 阶段 Linux 计算轮胎打滑率 Slip Ratio) --- - // 🚨 严禁返回平滑后的速度(m/s),必须返回最原始的累计脉冲! - int64 encoder_ticks_fl = 2; - int64 encoder_ticks_fr = 3; - int64 encoder_ticks_rl = 4; - int64 encoder_ticks_rr = 5; - - // 实际物理舵角反馈 (度,用于 4.2 阶段比对指令下发时间,测定机械死区和相位滞后) - double actual_steer_angle_front_deg = 6; - double actual_steer_angle_rear_deg = 7; - - // --- B. 动力与负载健康状态 (用于 4.2 阶段诊断减速机干涉或刹车未放) --- - // 若维持低速所需的电流异常激增,说明机械装配存在过载阻力,Linux 将立刻熔断报警 - double current_fl_amp = 8; // 左前电机实际相电流 (安培) - double current_fr_amp = 9; - double current_rl_amp = 10; - double current_rr_amp = 11; - double current_steer_front_amp = 12;// 前转向舵机电流 - - // --- C. 驱动器底层硬件报警位 --- - uint32 driver_error_code = 13; // 0x00=健康, 0x01=过压, 0x02=堵转过流, 0x03=过热等 } \ No newline at end of file diff --git a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_control.proto b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_control.proto index ce66cdc..c8e1c0d 100644 --- a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_control.proto +++ b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_control.proto @@ -4,55 +4,68 @@ syntax = "proto3"; package agv.calibration.control; // ========================================================= -// 核心服务:AGV 底盘运动学标定与运控参数调优代理服务 -// 部署端:Windows车端 (作为 gRPC Server) -// 调用端:Linux标定服务器 (作为 gRPC Client) +// 核心服务:AGV 运控大脑(PID/MPC)参数自动化寻优调教代理 +// [部署端 Server]:Windows车端 (满血保留自身算法,负责执行闭环追踪与高频汇报) +// [调用端 Client]:Linux标定服务器 (上帝视角,负责发轨迹、看误差、AI打分与发新参数) // ========================================================= service AgvCalibControlService { // --------------------------------------------------------- - // 1. 权限接管与生命周期安全管控 + // 第一步:权限接管与生命周期安全管控 // --------------------------------------------------------- - // 夺取车辆控制权,强制剥夺车端原生的激光避障与自主导航逻辑 + // 💻 [Linux 发送 -> Windows]:要求切断避障,但保留底层 PID/MPC 算法就绪 + // 🚙 [Windows 返回 -> Linux]:回复模式切换成功,准备好接考题 rpc SetControlMode(ModeRequest) returns (StandardResponse); - // 软件级最高优看门狗急停(应对网络断连、越界飞车等紧急状况,底层必须无条件抱死电机) + // 💻 [Linux 发送 -> Windows]:断网或飞车时的最高级别急停,无视一切直接刹车 + // 🚙 [Windows 返回 -> Linux]:返回底层抱死结果 rpc EmergencyStop(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 2. 运动考题下发 (开环排雷 / 闭环寻优 / 波峰对齐) + // 第二步:运动考题下发 (开环排雷 / 闭环寻优 / 波峰对齐) // --------------------------------------------------------- - // 【场景A: 纯物理开环】要求车端切断所有PID/运动学逆解,直接将转速/PWM透传给底层电机 + // 【场景A: 纯物理开环备用】 + // 💻 [Linux 发送 -> Windows]:要求切断算法盲跑,多用于摸底或辅助验证 + // 🚙 [Windows 返回 -> Linux]:确认已按指定 RPM/PWM 运转 rpc ExecuteOpenLoopCmd(OpenLoopRequest) returns (StandardResponse); - // 【场景B: 算法闭环调优】下发测试轨迹,要求车端用"它自带的"运控算法(PID/MPC)去努力追踪 + // 【场景B: 算法闭环调优】 + // 💻 [Linux 发送 -> Windows]:下发一条由几百个点组成的测试轨迹(如 S型贝塞尔曲线) + // 🚙 [Windows 返回 -> Linux]:收到轨迹后,车端立刻使用它自带的 PID/MPC 算法努力贴合轨迹跑圈 rpc FollowTestTrajectory(TrajectoryRequest) returns (StandardResponse); - // 【场景C: 波峰时序对齐】下发极短促的阶跃加速指令,人为制造绝对速度波峰,供Linux提取Time Offset + // 【场景C: 波峰时序对齐】 + // 💻 [Linux 发送 -> Windows]:下发极短促的阶跃加速指令,人为制造绝对速度波峰 + // 🚙 [Windows 返回 -> Linux]:确认加速。(Linux 借此波峰算出网络的绝对 Time Offset) rpc ExecuteStepResponse(StepResponseRequest) returns (StandardResponse); // --------------------------------------------------------- - // 3. 运控参数 AI 寻优:动态热注入与最终固化 + // 第三步:运控参数 AI 寻优:动态热注入与最终固化 // --------------------------------------------------------- - // 寻优核心:将 Linux 算出的临时参数瞬间写入车端内存并立刻生效,准许开始下一圈测试 + // 💻 [Linux 发送 -> Windows]:Linux 发现上一圈跑得差,AI算出了新的 PID/前瞻距离,要求立即热注入 + // 🚙 [Windows 返回 -> Linux]:车端将新参数瞬间覆写进运行内存(不重启系统),随时准备用新参数重跑 rpc InjectTuningParameters(ControlParams) returns (StandardResponse); - // 调优结束:通知车端将目前内存中的最高分参数,永久覆写进硬盘的 config.yaml 或注册表 + // 💻 [Linux 发送 -> Windows]:Linux 判定误差极小,调优结束,命令固化目前内存里的最高分参数 + // 🚙 [Windows 返回 -> Linux]:车端将这组完美参数永久覆写进硬盘的 config.yaml 或系统注册表 rpc CommitControlParameters(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 4. 高频数字孪生体感上报 (50Hz) + // 第四步:高频数字孪生体感上报 (50Hz) // --------------------------------------------------------- - // 注意: 使用 server-streaming 服务端持续推流。车端被调用一次后, - // 需以 50Hz 频率疯狂向外广播自身底层状态,供 Linux 提取波峰并比对真值打分。 + // 💻 [Linux 发送 -> Windows]:空包触发,命令车端开始疯狂推流 + // 🚙 [Windows 持续流式返回 -> Linux]:以 50Hz 频率,持续上报自己的里程计坐标、速度和单调时间戳 rpc StreamTelemetry(Empty) returns (stream TelemetryData); } // ========================================================= // 基础通用消息结构 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (通常用作触发信号) message Empty {} +// 🚙 [流向]:Windows 返回 -> Linux (通用应答) message StandardResponse { bool success = 1; string message = 2; // 包含执行成功的回执,或底盘卡死/驱动器报错等异常原因 @@ -61,11 +74,13 @@ message StandardResponse { // ========================================================= // 1. 模式控制结构体 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message ModeRequest { enum Mode { NORMAL_MODE = 0; // 正常业务模式(打开避障和导航,出厂默认状态) OPEN_LOOP_MODE = 1; // 物理开环标定模式(切断所有算法纠偏,提线木偶状态) - TUNING_MODE = 2; // 闭环调优模式(切断环境避障,但保留原生 PID/MPC 追踪算法) + TUNING_MODE = 2; // 闭环调优模式(切断环境避障,但必须保留原生 PID/MPC 追踪算法) } Mode target_mode = 1; } @@ -73,16 +88,19 @@ message ModeRequest { // ========================================================= // 2. 动作指令请求载荷 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message OpenLoopRequest { double left_motor_cmd = 1; // 左驱动轮目标转速 (RPM) 或占空比 double right_motor_cmd = 2; // 右驱动轮目标转速 (RPM) 或占空比 double steering_angle = 3; // 针对单/多舵轮底盘的绝对舵角指令 (度,差速轮忽略) // 🚨 极度关键的安全设计:指令超时时间 - // 车端若失去网络连接,超时后必须由底层代码强制将速度归零,严防撞墙! + // 业务潜台词:车端若失去网络连接,超时后必须由底层代码强制将速度归零,严防撞墙! double duration_sec = 4; } +// 💻 [流向]:Linux 发送 -> Windows (组成考卷的一小步) message TrajectoryPoint { double x_m = 1; // 目标点 X 坐标 (米) double y_m = 2; // 目标点 Y 坐标 (米) @@ -91,11 +109,13 @@ message TrajectoryPoint { double curvature = 5; // 该点处的轨迹曲率 (可选项,用于辅助前瞻距离映射) } +// 💻 [流向]:Linux 发送 -> Windows (下发整张考卷) message TrajectoryRequest { string test_case_id = 1; // 考题名称,如 "Bezier_Curve_S_Speed_1.2" repeated TrajectoryPoint path = 2; // 组成考题曲线的稠密坐标点阵列 } +// 💻 [流向]:Linux 发送 -> Windows (制造波峰) message StepResponseRequest { double target_velocity_ms = 1; // 极速阶跃的目标线速度 (如猛烈加速到 1.5 m/s) double duration_sec = 2; // 阶跃维持时间 (极短,如 1~2 秒即可,用于产生绝对波峰) @@ -104,10 +124,13 @@ message StepResponseRequest { // ========================================================= // 3. 待调优运控参数载荷 (支持增量式热更新) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message ControlParams { - // 采用 optional 关键字,允许 Linux 每次只修改需要微调的单个参数,其余保持原样 + // 🚨 业务潜台词:采用 optional 关键字,允许 Linux 每次只下发需要修改的个别参数。 + // 没下发的参数,Windows 必须保持内存中的原样,千万不能清零! - // --- 底盘物理运动学修正系数 (由 4.3 阶段开环算得) --- + // --- 底盘物理运动学修正系数 (由第一阶段开环算得) --- optional double wheel_radius_left_ratio = 1; // 左侧真实有效轮径补偿乘数 (如 1.002) optional double wheel_radius_right_ratio = 2; // 右侧真实有效轮径补偿乘数 (如 0.998) optional double effective_track_width_m = 3; // 有效轮距 (m) @@ -131,26 +154,32 @@ message ControlParams { // ========================================================= // 4. 高频遥测推流载荷 (数字孪生状态汇报) // ========================================================= + +// 🚙 [流向]:Windows 疯狂上报 -> Linux (50Hz) message TelemetryData { // 🚨 互相关对齐的核心依据: // 必须使用 Windows 底层高精度单调时钟 (如 QueryPerformanceCounter) 的绝对微秒数。 // 绝对禁止在车端人为做时序平滑或使用受 NTP 影响的系统时间! int64 hardware_timestamp_us = 1; - // --- 车端推算的内部里程计位姿 (Odom) --- + // --- A. 车端推算的内部里程计位姿 (Odom) --- + // 业务潜台词:Linux 拿这个跟外面上帝视角的雷达真值相减,就算出了算法的实际追踪误差(RMSE) double odom_x_m = 2; double odom_y_m = 3; double odom_yaw_rad = 4; - // --- 底层执行器真实物理反馈 (用于提取波峰) --- + // --- B. 底层执行器真实物理反馈 (用于提取波峰) --- + // 业务潜台词:用于跟指令速度比对,提取波峰,并计算 Jerk (加加速度/平顺性) double feedback_linear_vel_ms = 5; // 编码器解算的真实线速度 (m/s) double feedback_angular_vel_rads = 6;// 陀螺仪或编码器解算的真实角速度 (rad/s) - // --- 硬件健康与功耗监控 (用于 Linux 诊断干涉卡死) --- + // --- C. 硬件健康与功耗监控 (用于 Linux 诊断干涉卡死) --- + // 业务潜台词:如果遇到急弯时电流长期满载,Linux 判定该考题超出了这台车的物理极限。 double left_motor_current_amp = 7; // 左驱动电机实时电流 (A) double right_motor_current_amp = 8; // 右驱动电机实时电流 (A) double steering_motor_current_amp = 9; // 转向舵机实时电流 (A) - // --- 算法控制输出量 (用于 Linux 识别死区或物理饱和) --- + // --- D. 算法控制输出量 (用于 Linux 识别死区或物理饱和) --- + // 业务潜台词:观察 PID 算出的期望舵角,看是否长期顶在软件限幅上 (如打满死舵) double cmd_steering_output = 10; // 控制算法计算出的期望底层舵角指令 (度/弧度) } \ No newline at end of file diff --git a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_sensor.proto b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_sensor.proto index 2295180..e9d0a40 100644 --- a/agv_calib_brain/src/agv_calib_core/proto/agv_calib_sensor.proto +++ b/agv_calib_brain/src/agv_calib_core/proto/agv_calib_sensor.proto @@ -1,38 +1,63 @@ syntax = "proto3"; -// 规范包名,防止与其他业务(如底盘运控调优)的接口冲突 +// 规范包名,防止与其他业务(如底盘 chassis 或 运控 control)的接口冲突 +// 设计原则:严格遵循“走-停-拍”防延迟策略与大文件分块流式传输 package agv.calibration.sensor; // ========================================================= -// 核心服务:传感器自动化标定代理服务 -// 部署端:Windows车端 (Server) | 调用端:Linux服务器 (Client) +// 核心服务:多传感器自动化外参标定代理服务 +// [部署端 Server]:Windows车端 (充当带轮子的三脚架与文件下载服务器) +// [调用端 Client]:Linux标定服务器 (掌控状态机、拉取大文件、算 Ceres 矩阵) // ========================================================= service SensorCalibrationService { - // 1. 走位调度:指挥车辆开到特定的观测点并【绝对静止】 + + // --------------------------------------------------------- + // 第一步:物理走位 (走) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:调度车辆开到指定的标定观测点,到达后【绝对刹车静止】 + // 🚙 [Windows 返回 -> Linux]:物理到位抱死刹车后,返回成功回执 + // 🚨 业务潜台词:Linux 收到回执后,必须在代码里强制 sleep(0.5s) 等待避震悬挂平息,冻结物理空间! rpc MoveToObservationPose (PoseRequest) returns (StandardResponse); - // 2. 同步锁存:命令车辆瞬间冻结指定传感器的当前画面/点云到内存 + // --------------------------------------------------------- + // 第二步:防延迟同步锁存 (停与拍) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:命令车辆瞬间将底层相机的显存和雷达的点云冻结到后备内存池 + // 🚙 [Windows 返回 -> Linux]:立刻锁存,并返回高精度硬件时间戳,作为后续拉取大文件的唯一“取件码” rpc TriggerSyncCapture (CaptureRequest) returns (CaptureResponse); - // 3. 大文件下载:通过凭证流式拉取图片和点云(注意:使用 stream 防爆内存) + // --------------------------------------------------------- + // 第三步:大文件流式下载 (传 —— 破解 Windows 网络延迟的绝杀) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:凭“取件码”请求下载巨大的图片/点云原文件 + // 🚙 [Windows 持续流式返回 -> Linux]:将 5MB+ 的无损文件切成小块,像流水一样源源不断传回 Linux + // 🚨 业务潜台词:必须使用 stream 关键字!否则 gRPC 会因为单包超过 4MB 瞬间崩溃! rpc DownloadImage (DataFetchRequest) returns (stream FileChunk); rpc DownloadPointCloud (DataFetchRequest) returns (stream FileChunk); - // 4. 标定闭环:Linux算完矩阵后,下发给车端持久化保存(覆写配置文件) + // --------------------------------------------------------- + // 第四步:标定闭环定稿 (写) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:Linux 攒够数据算完复杂的 4x4 外参矩阵后,下发给车端持久化保存 + // 🚙 [Windows 返回 -> Linux]:车端收到后直接覆写 sensor_config.yaml 或注册表,返回成功 rpc CommitCalibrationResults (CalibrationPayload) returns (StandardResponse); } // ========================================================= // 基础响应 // ========================================================= + +// 🚙 [流向]:Windows 返回 -> Linux (通用应答) message StandardResponse { bool success = 1; - string message = 2; // 成功提示或具体的报错原因(如:碰撞急停) + string message = 2; // 成功提示或具体的报错原因(如:标定点坐标越界导致碰撞防线触发) } // ========================================================= // 1. 物理走位请求 (走) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message PoseRequest { double target_x_m = 1; // 目标 X 坐标 (米) double target_y_m = 2; // 目标 Y 坐标 (米) @@ -43,15 +68,19 @@ message PoseRequest { // ========================================================= // 2. 触发同步抓拍请求与响应 (停与拍) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message CaptureRequest { - // 告诉车端这次要同时拍哪些传感器,例如 ["cam_front", "lidar_top"] + // 业务潜台词:告诉车端这次要同时拍哪些传感器,例如 ["cam_front", "lidar_top"] + // 收到指令的这一微秒,车端底层必须同时将名单里传感器的数据 copy 冻结出来!未点名的不管,节约内存。 repeated string sensor_ids = 1; } +// 🚙 [流向]:Windows 返回 -> Linux message CaptureResponse { bool success = 1; - // 极度关键:车端打上的高精度硬件时间戳(微秒)。 - // 这是提取数据的“取件码”,保证多传感器在物理时间上的绝对对齐! + // 🚨 极度关键:“取件码”!车端打上的高精度硬件时间戳(微秒)。 + // 业务潜台词:这是提取大文件的唯一凭证,无论一会儿 Wi-Fi 传得有多慢,只要凭证一致,保证拿回来的图片和点云在物理空间上是绝对严丝合缝对齐的! int64 capture_timestamp_us = 2; string error_message = 3; } @@ -59,21 +88,30 @@ message CaptureResponse { // ========================================================= // 3. 大文件下载请求与文件流块 (传) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (凭码提货) message DataFetchRequest { - int64 capture_timestamp_us = 1; // 阶段2拿到的取件码 - string sensor_id = 2; // 具体要下载哪个传感器,例如 "cam_front" + int64 capture_timestamp_us = 1; // 阶段2拿到的唯一“取件码” + string sensor_id = 2; // 具体要拉取哪个传感器的数据,例如 "cam_front" } -// 流式文件块 (规避 gRPC 单条消息默认 4MB 的内存限制) +// 🚙 [流向]:Windows 持续流式返回 -> Linux (流水线发货) message FileChunk { - bytes chunk_data = 1; // 文件的二进制分块(建议每次发 512KB - 1MB) - bool is_last_chunk = 2; // 是否为最后一块 - string format_ext = 3; // 格式标注,如 "png", "bmp", "pcd" + // 业务潜台词:规避 gRPC 单条消息默认 4MB 的内存限制,防止传大图片时程序崩溃。 + bytes chunk_data = 1; // 文件的二进制分块(建议车端 C++ 每次切 512KB - 1MB 发送) + bool is_last_chunk = 2; // 标记是否为最后一块,告诉 Linux 停止拼接并保存文件 + + // 🚨 致命防坑潜台词:绝对禁止传 "jpg" 或 "jpeg"! + // 有损压缩的伪影会导致亚像素角点提取出现好几个像素的偏差,毁掉整个 3D 标定精度。 + // 必须是 "png", "bmp", "raw" 或 "pcd"! + string format_ext = 3; } // ========================================================= -// 4. 标定结果载荷(支持内参、外参灵活组合组合发回车端) (写) +// 4. 标定结果载荷(支持内参、外参灵活组合发回车端) (写) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (下发算好的内参,多为离线预标定备用) message CameraIntrinsics { string camera_id = 1; double fx = 2; double fy = 3; @@ -81,24 +119,29 @@ message CameraIntrinsics { repeated double dist_coeffs = 6; // 畸变系数阵列 [k1, k2, p1, p2, k3] } +// 💻 [流向]:Linux 发送 -> Windows (下发算好的 6-DOF 外参矩阵) message SensorExtrinsics { + // 业务潜台词:告诉车端,source 坐标系 相对 target 坐标系,平移和旋转了多少。 string source_frame = 1; // 源坐标系,如 "lidar_top" 或 "cam_left" - string target_frame = 2; // 目标坐标系,如 "cam_front" 或 "base_link" + string target_frame = 2; // 目标坐标系,如 "cam_front" 或 "base_link" (底盘质心) - // 平移向量 (强制规定单位为毫米 mm) + // 平移向量 (强制规定工业制式单位为毫米 mm,消除浮点数歧义) double trans_x_mm = 3; double trans_y_mm = 4; double trans_z_mm = 5; - // 旋转姿态 (强制规定单位为度 degrees) + // 空间旋转姿态 (强制规定工业制式单位为度 degrees,方便人工排错,绝不混用弧度) double roll_deg = 6; double pitch_deg = 7; double yaw_deg = 8; } +// 💻 [流向]:Linux 发送 -> Windows (出厂全量包) message CalibrationPayload { - string task_id = 1; // 标定任务流水号,用于 MES 系统追溯 - // 采用 repeated 数组:Linux 可以一次性下发多个相机的内参和多个外参 + string task_id = 1; // 标定任务流水号,用于 MES 系统的云端溯源 + + // 业务潜台词:采用 repeated 数组,Linux 可以一次性把全车所有的内参、外参一股脑发过去。 + // 车端只需一个 for 循环,把这些矩阵依次写进硬盘即可。 repeated CameraIntrinsics updated_intrinsics = 2; repeated SensorExtrinsics updated_extrinsics = 3; } \ No newline at end of file diff --git a/agv_calib_eu/proto/agv_calib_chassis.proto b/agv_calib_eu/proto/agv_calib_chassis.proto index 73b9216..5ad10a2 100644 --- a/agv_calib_eu/proto/agv_calib_chassis.proto +++ b/agv_calib_eu/proto/agv_calib_chassis.proto @@ -1,89 +1,137 @@ syntax = "proto3"; -// 规范包名,确保与运控调优(control)和传感器外参(sensor)在逻辑上严格物理隔离 +// 规范包名:agv.calibration.chassis +// 设计原则:专门负责底盘最底层机械物理特征的开环标定与体检 package agv.calibration.chassis; // ========================================================= // 核心服务:AGV 底盘底层硬件自诊与物理运动学标定代理服务 -// 部署端:Windows车端 (直连底层电机驱动器/PLC 的网关层) -// 调用端:Linux标定服务器 (掌控外部高精雷达真值) +// [部署端 Server]:Windows 车端 (只负责听口令、转电机、报裸数据) +// [调用端 Client]:Linux 车间服务器 (负责发口令、看雷达真值、算误差) // ========================================================= service AgvCalibChassisService { // --------------------------------------------------------- - // 1. 底层硬件接管与安全熔断 + // 第一步:权限接管与安全熔断 (剥夺车端算法大脑) // --------------------------------------------------------- - // 强制接管底层驱动器。注意:这里不仅要切断避障,还要切断底盘的“运动学正逆解算法” + // 💻 [Linux 发送 -> Windows]:要求切断底盘运动学逆解,进入纯物理开环直驱模式 + // 🚙 [Windows 返回 -> Linux]:返回接管是否成功的回执 rpc SetDiagnosticMode(DiagnosticModeRequest) returns (StandardResponse); - // 硬件级绝对急停 (直接向驱动器下发 Safe Torque Off / 机械抱死指令,无视任何上层状态) + // 💻 [Linux 发送 -> Windows]:无视一切状态立刻抱死电机的紧急急停指令 + // 🚙 [Windows 返回 -> Linux]:返回急停执行状态 rpc HardwareEmergencyBrake(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 2. 原始物理开环指令下发 (对应方案 4.2 诊断 与 4.3 物理标定) + // 第二步:打开体征监控水龙头 (数字孪生健康诊断) // --------------------------------------------------------- - // 允许 Linux 越过底盘协同模型,直接对指定驱动轮下发最原始的转速(RPM)或占空比 - // 核心用途:暴露真实的机械阻力差、诊断减速机卡死、测试轮胎滑移率 + // 💻 [Linux 发送 -> Windows]:发送空请求,触发高频推流开关 + // 🚙 [Windows 持续流式返回 -> Linux]:以 50Hz 频率持续不断地回传原始脉冲与电流 + rpc StreamHardwareTelemetry(Empty) returns (stream HardwareState); + + // --------------------------------------------------------- + // 第三步:原始物理开环考题下发 (逼迫底盘暴露机械缺陷) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:绕过算法,直接命令指定驱动轮以固定 RPM 盲跑 + // 🚙 [Windows 返回 -> Linux]:返回电机是否已成功按给定 RPM 运转 rpc ExecuteRawDriveCommand(RawDriveRequest) returns (StandardResponse); - // 允许 Linux 直接对转向机构下发绝对物理角度或往复扫频 - // 核心用途:测定舵机机械死区、往复间隙(Backlash)与静态机械零位偏差 + // 💻 [Linux 发送 -> Windows]:直接对转向机构下发绝对物理角度 (测机械装歪的角度) + // 🚙 [Windows 返回 -> Linux]:返回舵机是否已开始执行角度指令 rpc ExecuteRawSteerCommand(RawSteerRequest) returns (StandardResponse); // --------------------------------------------------------- - // 3. 物理运动学本底参数持久化 (出厂定稿写值) + // 第四步:物理本底参数定稿写值 (标定闭环结束) // --------------------------------------------------------- - // Linux 结合外部真值算出真实的物理机械参数后,下发并直接覆写到底盘驱动板 EEPROM 或底层配置中 + // 💻 [Linux 发送 -> Windows]:下发 Linux 结合外部真值算出的绝对物理修正系数 + // 🚙 [Windows 返回 -> Linux]:将系数覆写到本地硬盘/驱动板后,返回成功回执 rpc CommitKinematicParameters(KinematicParams) returns (StandardResponse); - - // --------------------------------------------------------- - // 4. 原始硬件级高频遥测 (数字孪生健康诊断的唯一依据) - // --------------------------------------------------------- - // 🚨 严禁推流经过滤波后的数据!必须是最底层的“原始编码器 Tick”和“绝对相电流”! - rpc StreamHardwareTelemetry(Empty) returns (stream HardwareState); } // ========================================================= // 基础通用消息结构 // ========================================================= + +// 空消息,通常作为触发类请求发送 +// 💻 [流向]:Linux 发送 -> Windows message Empty {} +// 通用应答载荷 +// 🚙 [流向]:Windows 返回 -> Linux message StandardResponse { bool success = 1; - string message = 2; // 异常时返回驱动器底层故障码 (如 "ERR_MOTOR_OVERCURRENT") + string message = 2; // 若失败,返回驱动器底层报错详情 (如 "ERR_MOTOR_OVERCURRENT") } +// ========================================================= +// 1. 权限模式请求载荷 +// ========================================================= +// 💻 [流向]:Linux 发送 -> Windows message DiagnosticModeRequest { enum Mode { - NORMAL_KINEMATICS = 0; // 正常模式 (底盘接收 V_x, Omega,由底层执行运动学逆解分配) - DIRECT_RAW_DRIVE = 1; // 直驱模式 (切断逆解,允许 Linux 直接独立控制左/右轮转速) + NORMAL_KINEMATICS = 0; // 正常模式 (底盘接收 V_x, Omega,由车端执行逆解分配) + DIRECT_RAW_DRIVE = 1; // 直驱模式 (切断逆解,允许 Linux 直接独立下发左/右轮转速) } Mode target_mode = 1; } // ========================================================= -// 2. 原始驱动指令 (发考题:逼迫底盘暴露出机械缺陷) +// 2. 硬件底层遥测推流载荷 (裸数据) // ========================================================= -message RawDriveRequest { - string test_case_id = 1; // 测试用例 (如 "Slip_Test_0.5m", "Straight_Friction_Test") +// 🚙 [流向]:Windows 疯狂上报 -> Linux (50Hz) +message HardwareState { + // 底层获取到脉冲那一瞬间的高精度单调系统时钟 (绝对微秒数) + int64 hardware_timestamp_us = 1; - // 直接下发给电机的原始指令 (若是两驱车,后轮填 0 即可) - double fl_motor_rpm = 2; // 左前轮 (Front-Left) 目标物理转速 (RPM) - double fr_motor_rpm = 3; // 右前轮 (Front-Right) 目标物理转速 (RPM) - double rl_motor_rpm = 4; // 左后轮 (Rear-Left) 目标物理转速 (RPM) - double rr_motor_rpm = 5; // 右后轮 (Rear-Right) 目标物理转速 (RPM) + // --- A. 原始编码器反馈 (Linux 拿它与雷达真值做除法,算真实物理位移与滑移率) --- + // 🚨 严禁返回平滑后的速度(m/s),必须返回最原始的累计脉冲 Ticks! + int64 encoder_ticks_fl = 2; // 左前轮累计脉冲 + int64 encoder_ticks_fr = 3; // 右前轮累计脉冲 + int64 encoder_ticks_rl = 4; + int64 encoder_ticks_rr = 5; - double duration_sec = 6; // 动作维持时间,断网防飞车底线:超时底层必须自动刹车 + // --- B. 物理舵角反馈 (Linux 拿它比对指令响应时间,测定机械死区) --- + double actual_steer_angle_front_deg = 6; + double actual_steer_angle_rear_deg = 7; + + // --- C. 动力与负载健康状态 (Linux 防烧毁熔断的判断依据) --- + // 若维持匀速所需的电流异常激增,说明减速机干涉或刹车未放,Linux 会立刻触发急停 + double current_fl_amp = 8; // 左前电机实际相电流 (安培) + double current_fr_amp = 9; + double current_rl_amp = 10; + double current_rr_amp = 11; + double current_steer_front_amp = 12;// 前转向舵机实际电流 (安培) + + // --- D. 驱动器硬件报警位 --- + uint32 driver_error_code = 13; // 0x00=健康, 0x01=过压, 0x02=堵转过流等 } -message RawSteerRequest { - string test_case_id = 1; // 测试用例 (如 "Deadzone_Sweep_5deg") +// ========================================================= +// 3. 原始动作指令请求载荷 +// ========================================================= +// 💻 [流向]:Linux 发送 -> Windows +message RawDriveRequest { + string test_case_id = 1; // 测试流水号 (如 "Slip_Test_0.5m") - // 针对舵机/转向推杆的绝对物理指令 (度) + // 直接下发给电机的原始指令 (若是两驱车,后轮填 0 即可) + double fl_motor_rpm = 2; // 左前轮目标物理转速 (RPM) + double fr_motor_rpm = 3; // 右前轮目标物理转速 (RPM) + double rl_motor_rpm = 4; + double rr_motor_rpm = 5; + + // 🚨 断网防飞车底线:若超过该时间未收到新指令,车端底层必须自动刹车 + double duration_sec = 6; +} + +// 💻 [流向]:Linux 发送 -> Windows +message RawSteerRequest { + string test_case_id = 1; // 测试流水号 (如 "Deadzone_Sweep_5deg") + + // 针对舵机/转向推杆的绝对物理角度指令 (度) double front_steer_angle_deg = 2; double rear_steer_angle_deg = 3; - // 专门用于 4.2节 测定机械间隙的扫频参数 + // 扫频测试参数 (用于测定机械往复间隙 Backlash) optional double sweep_amplitude_deg = 4; // 往复抖动幅度 (度) optional double sweep_frequency_hz = 5; // 抖动频率 (Hz) @@ -91,53 +139,27 @@ message RawSteerRequest { } // ========================================================= -// 3. 运动学本底参数定稿载荷 (纯物理修正系数) +// 4. 物理运动学本底参数定稿载荷 // ========================================================= +// 💻 [流向]:Linux 发送 -> Windows message KinematicParams { - // --- 1. 真实有效物理轮径 (解决“开环走直线画大弧”及闭环位移不准) --- + // (注:全字段使用 optional,Linux 测了哪一项就只下发哪一项要求车端覆盖,未发的不作修改) + + // --- 1. 真实有效物理轮径 (纠正“开环跑偏”与里程计位移误差) --- optional double wheel_radius_fl_m = 1; optional double wheel_radius_fr_m = 2; optional double wheel_radius_rl_m = 3; optional double wheel_radius_rr_m = 4; - // --- 2. 机械零位绝对偏差补偿 (解决“指令0度但车子斜着跑”) --- + // --- 2. 机械零位绝对偏差补偿 (纠正“指令0度但车子斜着走”) --- optional double steer_zero_offset_front_deg = 5; optional double steer_zero_offset_rear_deg = 6; - // --- 3. 旋转几何协同参数 (解决“原地打转时车体画圆甩尾摆动”) --- - optional double effective_track_width_m = 7; // 有效轮距 (左右轮真实物理间距) - optional double effective_wheel_base_m = 8; // 有效轴距 (前后轮真实物理间距) + // --- 3. 旋转几何协同参数 (纠正“原地打转时车体甩尾晃动”) --- + optional double effective_track_width_m = 7; // 左右轮真实物理有效轮距 (m) + optional double effective_wheel_base_m = 8; // 前后轮真实物理有效轴距 (m) - // 针对四驱四转等多舵轮底盘:瞬时旋转中心(ICR)的物理几何偏移 + // 针对多舵轮底盘:瞬时旋转中心(ICR)的物理几何偏移 optional double icr_offset_x_m = 9; optional double icr_offset_y_m = 10; -} - -// ========================================================= -// 4. 原始硬件遥测数据流 (Linux 用来排雷、熔断和算滑移率的裸数据) -// ========================================================= -message HardwareState { - int64 hardware_timestamp_us = 1; // 底层获取到脉冲那一瞬间的高精度单调系统时钟 (微秒) - - // --- A. 原始编码器反馈 (用于 4.2 阶段 Linux 计算轮胎打滑率 Slip Ratio) --- - // 🚨 严禁返回平滑后的速度(m/s),必须返回最原始的累计脉冲! - int64 encoder_ticks_fl = 2; - int64 encoder_ticks_fr = 3; - int64 encoder_ticks_rl = 4; - int64 encoder_ticks_rr = 5; - - // 实际物理舵角反馈 (度,用于 4.2 阶段比对指令下发时间,测定机械死区和相位滞后) - double actual_steer_angle_front_deg = 6; - double actual_steer_angle_rear_deg = 7; - - // --- B. 动力与负载健康状态 (用于 4.2 阶段诊断减速机干涉或刹车未放) --- - // 若维持低速所需的电流异常激增,说明机械装配存在过载阻力,Linux 将立刻熔断报警 - double current_fl_amp = 8; // 左前电机实际相电流 (安培) - double current_fr_amp = 9; - double current_rl_amp = 10; - double current_rr_amp = 11; - double current_steer_front_amp = 12;// 前转向舵机电流 - - // --- C. 驱动器底层硬件报警位 --- - uint32 driver_error_code = 13; // 0x00=健康, 0x01=过压, 0x02=堵转过流, 0x03=过热等 } \ No newline at end of file diff --git a/agv_calib_eu/proto/agv_calib_control.proto b/agv_calib_eu/proto/agv_calib_control.proto index ce66cdc..c8e1c0d 100644 --- a/agv_calib_eu/proto/agv_calib_control.proto +++ b/agv_calib_eu/proto/agv_calib_control.proto @@ -4,55 +4,68 @@ syntax = "proto3"; package agv.calibration.control; // ========================================================= -// 核心服务:AGV 底盘运动学标定与运控参数调优代理服务 -// 部署端:Windows车端 (作为 gRPC Server) -// 调用端:Linux标定服务器 (作为 gRPC Client) +// 核心服务:AGV 运控大脑(PID/MPC)参数自动化寻优调教代理 +// [部署端 Server]:Windows车端 (满血保留自身算法,负责执行闭环追踪与高频汇报) +// [调用端 Client]:Linux标定服务器 (上帝视角,负责发轨迹、看误差、AI打分与发新参数) // ========================================================= service AgvCalibControlService { // --------------------------------------------------------- - // 1. 权限接管与生命周期安全管控 + // 第一步:权限接管与生命周期安全管控 // --------------------------------------------------------- - // 夺取车辆控制权,强制剥夺车端原生的激光避障与自主导航逻辑 + // 💻 [Linux 发送 -> Windows]:要求切断避障,但保留底层 PID/MPC 算法就绪 + // 🚙 [Windows 返回 -> Linux]:回复模式切换成功,准备好接考题 rpc SetControlMode(ModeRequest) returns (StandardResponse); - // 软件级最高优看门狗急停(应对网络断连、越界飞车等紧急状况,底层必须无条件抱死电机) + // 💻 [Linux 发送 -> Windows]:断网或飞车时的最高级别急停,无视一切直接刹车 + // 🚙 [Windows 返回 -> Linux]:返回底层抱死结果 rpc EmergencyStop(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 2. 运动考题下发 (开环排雷 / 闭环寻优 / 波峰对齐) + // 第二步:运动考题下发 (开环排雷 / 闭环寻优 / 波峰对齐) // --------------------------------------------------------- - // 【场景A: 纯物理开环】要求车端切断所有PID/运动学逆解,直接将转速/PWM透传给底层电机 + // 【场景A: 纯物理开环备用】 + // 💻 [Linux 发送 -> Windows]:要求切断算法盲跑,多用于摸底或辅助验证 + // 🚙 [Windows 返回 -> Linux]:确认已按指定 RPM/PWM 运转 rpc ExecuteOpenLoopCmd(OpenLoopRequest) returns (StandardResponse); - // 【场景B: 算法闭环调优】下发测试轨迹,要求车端用"它自带的"运控算法(PID/MPC)去努力追踪 + // 【场景B: 算法闭环调优】 + // 💻 [Linux 发送 -> Windows]:下发一条由几百个点组成的测试轨迹(如 S型贝塞尔曲线) + // 🚙 [Windows 返回 -> Linux]:收到轨迹后,车端立刻使用它自带的 PID/MPC 算法努力贴合轨迹跑圈 rpc FollowTestTrajectory(TrajectoryRequest) returns (StandardResponse); - // 【场景C: 波峰时序对齐】下发极短促的阶跃加速指令,人为制造绝对速度波峰,供Linux提取Time Offset + // 【场景C: 波峰时序对齐】 + // 💻 [Linux 发送 -> Windows]:下发极短促的阶跃加速指令,人为制造绝对速度波峰 + // 🚙 [Windows 返回 -> Linux]:确认加速。(Linux 借此波峰算出网络的绝对 Time Offset) rpc ExecuteStepResponse(StepResponseRequest) returns (StandardResponse); // --------------------------------------------------------- - // 3. 运控参数 AI 寻优:动态热注入与最终固化 + // 第三步:运控参数 AI 寻优:动态热注入与最终固化 // --------------------------------------------------------- - // 寻优核心:将 Linux 算出的临时参数瞬间写入车端内存并立刻生效,准许开始下一圈测试 + // 💻 [Linux 发送 -> Windows]:Linux 发现上一圈跑得差,AI算出了新的 PID/前瞻距离,要求立即热注入 + // 🚙 [Windows 返回 -> Linux]:车端将新参数瞬间覆写进运行内存(不重启系统),随时准备用新参数重跑 rpc InjectTuningParameters(ControlParams) returns (StandardResponse); - // 调优结束:通知车端将目前内存中的最高分参数,永久覆写进硬盘的 config.yaml 或注册表 + // 💻 [Linux 发送 -> Windows]:Linux 判定误差极小,调优结束,命令固化目前内存里的最高分参数 + // 🚙 [Windows 返回 -> Linux]:车端将这组完美参数永久覆写进硬盘的 config.yaml 或系统注册表 rpc CommitControlParameters(Empty) returns (StandardResponse); // --------------------------------------------------------- - // 4. 高频数字孪生体感上报 (50Hz) + // 第四步:高频数字孪生体感上报 (50Hz) // --------------------------------------------------------- - // 注意: 使用 server-streaming 服务端持续推流。车端被调用一次后, - // 需以 50Hz 频率疯狂向外广播自身底层状态,供 Linux 提取波峰并比对真值打分。 + // 💻 [Linux 发送 -> Windows]:空包触发,命令车端开始疯狂推流 + // 🚙 [Windows 持续流式返回 -> Linux]:以 50Hz 频率,持续上报自己的里程计坐标、速度和单调时间戳 rpc StreamTelemetry(Empty) returns (stream TelemetryData); } // ========================================================= // 基础通用消息结构 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (通常用作触发信号) message Empty {} +// 🚙 [流向]:Windows 返回 -> Linux (通用应答) message StandardResponse { bool success = 1; string message = 2; // 包含执行成功的回执,或底盘卡死/驱动器报错等异常原因 @@ -61,11 +74,13 @@ message StandardResponse { // ========================================================= // 1. 模式控制结构体 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message ModeRequest { enum Mode { NORMAL_MODE = 0; // 正常业务模式(打开避障和导航,出厂默认状态) OPEN_LOOP_MODE = 1; // 物理开环标定模式(切断所有算法纠偏,提线木偶状态) - TUNING_MODE = 2; // 闭环调优模式(切断环境避障,但保留原生 PID/MPC 追踪算法) + TUNING_MODE = 2; // 闭环调优模式(切断环境避障,但必须保留原生 PID/MPC 追踪算法) } Mode target_mode = 1; } @@ -73,16 +88,19 @@ message ModeRequest { // ========================================================= // 2. 动作指令请求载荷 // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message OpenLoopRequest { double left_motor_cmd = 1; // 左驱动轮目标转速 (RPM) 或占空比 double right_motor_cmd = 2; // 右驱动轮目标转速 (RPM) 或占空比 double steering_angle = 3; // 针对单/多舵轮底盘的绝对舵角指令 (度,差速轮忽略) // 🚨 极度关键的安全设计:指令超时时间 - // 车端若失去网络连接,超时后必须由底层代码强制将速度归零,严防撞墙! + // 业务潜台词:车端若失去网络连接,超时后必须由底层代码强制将速度归零,严防撞墙! double duration_sec = 4; } +// 💻 [流向]:Linux 发送 -> Windows (组成考卷的一小步) message TrajectoryPoint { double x_m = 1; // 目标点 X 坐标 (米) double y_m = 2; // 目标点 Y 坐标 (米) @@ -91,11 +109,13 @@ message TrajectoryPoint { double curvature = 5; // 该点处的轨迹曲率 (可选项,用于辅助前瞻距离映射) } +// 💻 [流向]:Linux 发送 -> Windows (下发整张考卷) message TrajectoryRequest { string test_case_id = 1; // 考题名称,如 "Bezier_Curve_S_Speed_1.2" repeated TrajectoryPoint path = 2; // 组成考题曲线的稠密坐标点阵列 } +// 💻 [流向]:Linux 发送 -> Windows (制造波峰) message StepResponseRequest { double target_velocity_ms = 1; // 极速阶跃的目标线速度 (如猛烈加速到 1.5 m/s) double duration_sec = 2; // 阶跃维持时间 (极短,如 1~2 秒即可,用于产生绝对波峰) @@ -104,10 +124,13 @@ message StepResponseRequest { // ========================================================= // 3. 待调优运控参数载荷 (支持增量式热更新) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message ControlParams { - // 采用 optional 关键字,允许 Linux 每次只修改需要微调的单个参数,其余保持原样 + // 🚨 业务潜台词:采用 optional 关键字,允许 Linux 每次只下发需要修改的个别参数。 + // 没下发的参数,Windows 必须保持内存中的原样,千万不能清零! - // --- 底盘物理运动学修正系数 (由 4.3 阶段开环算得) --- + // --- 底盘物理运动学修正系数 (由第一阶段开环算得) --- optional double wheel_radius_left_ratio = 1; // 左侧真实有效轮径补偿乘数 (如 1.002) optional double wheel_radius_right_ratio = 2; // 右侧真实有效轮径补偿乘数 (如 0.998) optional double effective_track_width_m = 3; // 有效轮距 (m) @@ -131,26 +154,32 @@ message ControlParams { // ========================================================= // 4. 高频遥测推流载荷 (数字孪生状态汇报) // ========================================================= + +// 🚙 [流向]:Windows 疯狂上报 -> Linux (50Hz) message TelemetryData { // 🚨 互相关对齐的核心依据: // 必须使用 Windows 底层高精度单调时钟 (如 QueryPerformanceCounter) 的绝对微秒数。 // 绝对禁止在车端人为做时序平滑或使用受 NTP 影响的系统时间! int64 hardware_timestamp_us = 1; - // --- 车端推算的内部里程计位姿 (Odom) --- + // --- A. 车端推算的内部里程计位姿 (Odom) --- + // 业务潜台词:Linux 拿这个跟外面上帝视角的雷达真值相减,就算出了算法的实际追踪误差(RMSE) double odom_x_m = 2; double odom_y_m = 3; double odom_yaw_rad = 4; - // --- 底层执行器真实物理反馈 (用于提取波峰) --- + // --- B. 底层执行器真实物理反馈 (用于提取波峰) --- + // 业务潜台词:用于跟指令速度比对,提取波峰,并计算 Jerk (加加速度/平顺性) double feedback_linear_vel_ms = 5; // 编码器解算的真实线速度 (m/s) double feedback_angular_vel_rads = 6;// 陀螺仪或编码器解算的真实角速度 (rad/s) - // --- 硬件健康与功耗监控 (用于 Linux 诊断干涉卡死) --- + // --- C. 硬件健康与功耗监控 (用于 Linux 诊断干涉卡死) --- + // 业务潜台词:如果遇到急弯时电流长期满载,Linux 判定该考题超出了这台车的物理极限。 double left_motor_current_amp = 7; // 左驱动电机实时电流 (A) double right_motor_current_amp = 8; // 右驱动电机实时电流 (A) double steering_motor_current_amp = 9; // 转向舵机实时电流 (A) - // --- 算法控制输出量 (用于 Linux 识别死区或物理饱和) --- + // --- D. 算法控制输出量 (用于 Linux 识别死区或物理饱和) --- + // 业务潜台词:观察 PID 算出的期望舵角,看是否长期顶在软件限幅上 (如打满死舵) double cmd_steering_output = 10; // 控制算法计算出的期望底层舵角指令 (度/弧度) } \ No newline at end of file diff --git a/agv_calib_eu/proto/agv_calib_sensor.proto b/agv_calib_eu/proto/agv_calib_sensor.proto index 2295180..e9d0a40 100644 --- a/agv_calib_eu/proto/agv_calib_sensor.proto +++ b/agv_calib_eu/proto/agv_calib_sensor.proto @@ -1,38 +1,63 @@ syntax = "proto3"; -// 规范包名,防止与其他业务(如底盘运控调优)的接口冲突 +// 规范包名,防止与其他业务(如底盘 chassis 或 运控 control)的接口冲突 +// 设计原则:严格遵循“走-停-拍”防延迟策略与大文件分块流式传输 package agv.calibration.sensor; // ========================================================= -// 核心服务:传感器自动化标定代理服务 -// 部署端:Windows车端 (Server) | 调用端:Linux服务器 (Client) +// 核心服务:多传感器自动化外参标定代理服务 +// [部署端 Server]:Windows车端 (充当带轮子的三脚架与文件下载服务器) +// [调用端 Client]:Linux标定服务器 (掌控状态机、拉取大文件、算 Ceres 矩阵) // ========================================================= service SensorCalibrationService { - // 1. 走位调度:指挥车辆开到特定的观测点并【绝对静止】 + + // --------------------------------------------------------- + // 第一步:物理走位 (走) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:调度车辆开到指定的标定观测点,到达后【绝对刹车静止】 + // 🚙 [Windows 返回 -> Linux]:物理到位抱死刹车后,返回成功回执 + // 🚨 业务潜台词:Linux 收到回执后,必须在代码里强制 sleep(0.5s) 等待避震悬挂平息,冻结物理空间! rpc MoveToObservationPose (PoseRequest) returns (StandardResponse); - // 2. 同步锁存:命令车辆瞬间冻结指定传感器的当前画面/点云到内存 + // --------------------------------------------------------- + // 第二步:防延迟同步锁存 (停与拍) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:命令车辆瞬间将底层相机的显存和雷达的点云冻结到后备内存池 + // 🚙 [Windows 返回 -> Linux]:立刻锁存,并返回高精度硬件时间戳,作为后续拉取大文件的唯一“取件码” rpc TriggerSyncCapture (CaptureRequest) returns (CaptureResponse); - // 3. 大文件下载:通过凭证流式拉取图片和点云(注意:使用 stream 防爆内存) + // --------------------------------------------------------- + // 第三步:大文件流式下载 (传 —— 破解 Windows 网络延迟的绝杀) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:凭“取件码”请求下载巨大的图片/点云原文件 + // 🚙 [Windows 持续流式返回 -> Linux]:将 5MB+ 的无损文件切成小块,像流水一样源源不断传回 Linux + // 🚨 业务潜台词:必须使用 stream 关键字!否则 gRPC 会因为单包超过 4MB 瞬间崩溃! rpc DownloadImage (DataFetchRequest) returns (stream FileChunk); rpc DownloadPointCloud (DataFetchRequest) returns (stream FileChunk); - // 4. 标定闭环:Linux算完矩阵后,下发给车端持久化保存(覆写配置文件) + // --------------------------------------------------------- + // 第四步:标定闭环定稿 (写) + // --------------------------------------------------------- + // 💻 [Linux 发送 -> Windows]:Linux 攒够数据算完复杂的 4x4 外参矩阵后,下发给车端持久化保存 + // 🚙 [Windows 返回 -> Linux]:车端收到后直接覆写 sensor_config.yaml 或注册表,返回成功 rpc CommitCalibrationResults (CalibrationPayload) returns (StandardResponse); } // ========================================================= // 基础响应 // ========================================================= + +// 🚙 [流向]:Windows 返回 -> Linux (通用应答) message StandardResponse { bool success = 1; - string message = 2; // 成功提示或具体的报错原因(如:碰撞急停) + string message = 2; // 成功提示或具体的报错原因(如:标定点坐标越界导致碰撞防线触发) } // ========================================================= // 1. 物理走位请求 (走) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message PoseRequest { double target_x_m = 1; // 目标 X 坐标 (米) double target_y_m = 2; // 目标 Y 坐标 (米) @@ -43,15 +68,19 @@ message PoseRequest { // ========================================================= // 2. 触发同步抓拍请求与响应 (停与拍) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows message CaptureRequest { - // 告诉车端这次要同时拍哪些传感器,例如 ["cam_front", "lidar_top"] + // 业务潜台词:告诉车端这次要同时拍哪些传感器,例如 ["cam_front", "lidar_top"] + // 收到指令的这一微秒,车端底层必须同时将名单里传感器的数据 copy 冻结出来!未点名的不管,节约内存。 repeated string sensor_ids = 1; } +// 🚙 [流向]:Windows 返回 -> Linux message CaptureResponse { bool success = 1; - // 极度关键:车端打上的高精度硬件时间戳(微秒)。 - // 这是提取数据的“取件码”,保证多传感器在物理时间上的绝对对齐! + // 🚨 极度关键:“取件码”!车端打上的高精度硬件时间戳(微秒)。 + // 业务潜台词:这是提取大文件的唯一凭证,无论一会儿 Wi-Fi 传得有多慢,只要凭证一致,保证拿回来的图片和点云在物理空间上是绝对严丝合缝对齐的! int64 capture_timestamp_us = 2; string error_message = 3; } @@ -59,21 +88,30 @@ message CaptureResponse { // ========================================================= // 3. 大文件下载请求与文件流块 (传) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (凭码提货) message DataFetchRequest { - int64 capture_timestamp_us = 1; // 阶段2拿到的取件码 - string sensor_id = 2; // 具体要下载哪个传感器,例如 "cam_front" + int64 capture_timestamp_us = 1; // 阶段2拿到的唯一“取件码” + string sensor_id = 2; // 具体要拉取哪个传感器的数据,例如 "cam_front" } -// 流式文件块 (规避 gRPC 单条消息默认 4MB 的内存限制) +// 🚙 [流向]:Windows 持续流式返回 -> Linux (流水线发货) message FileChunk { - bytes chunk_data = 1; // 文件的二进制分块(建议每次发 512KB - 1MB) - bool is_last_chunk = 2; // 是否为最后一块 - string format_ext = 3; // 格式标注,如 "png", "bmp", "pcd" + // 业务潜台词:规避 gRPC 单条消息默认 4MB 的内存限制,防止传大图片时程序崩溃。 + bytes chunk_data = 1; // 文件的二进制分块(建议车端 C++ 每次切 512KB - 1MB 发送) + bool is_last_chunk = 2; // 标记是否为最后一块,告诉 Linux 停止拼接并保存文件 + + // 🚨 致命防坑潜台词:绝对禁止传 "jpg" 或 "jpeg"! + // 有损压缩的伪影会导致亚像素角点提取出现好几个像素的偏差,毁掉整个 3D 标定精度。 + // 必须是 "png", "bmp", "raw" 或 "pcd"! + string format_ext = 3; } // ========================================================= -// 4. 标定结果载荷(支持内参、外参灵活组合组合发回车端) (写) +// 4. 标定结果载荷(支持内参、外参灵活组合发回车端) (写) // ========================================================= + +// 💻 [流向]:Linux 发送 -> Windows (下发算好的内参,多为离线预标定备用) message CameraIntrinsics { string camera_id = 1; double fx = 2; double fy = 3; @@ -81,24 +119,29 @@ message CameraIntrinsics { repeated double dist_coeffs = 6; // 畸变系数阵列 [k1, k2, p1, p2, k3] } +// 💻 [流向]:Linux 发送 -> Windows (下发算好的 6-DOF 外参矩阵) message SensorExtrinsics { + // 业务潜台词:告诉车端,source 坐标系 相对 target 坐标系,平移和旋转了多少。 string source_frame = 1; // 源坐标系,如 "lidar_top" 或 "cam_left" - string target_frame = 2; // 目标坐标系,如 "cam_front" 或 "base_link" + string target_frame = 2; // 目标坐标系,如 "cam_front" 或 "base_link" (底盘质心) - // 平移向量 (强制规定单位为毫米 mm) + // 平移向量 (强制规定工业制式单位为毫米 mm,消除浮点数歧义) double trans_x_mm = 3; double trans_y_mm = 4; double trans_z_mm = 5; - // 旋转姿态 (强制规定单位为度 degrees) + // 空间旋转姿态 (强制规定工业制式单位为度 degrees,方便人工排错,绝不混用弧度) double roll_deg = 6; double pitch_deg = 7; double yaw_deg = 8; } +// 💻 [流向]:Linux 发送 -> Windows (出厂全量包) message CalibrationPayload { - string task_id = 1; // 标定任务流水号,用于 MES 系统追溯 - // 采用 repeated 数组:Linux 可以一次性下发多个相机的内参和多个外参 + string task_id = 1; // 标定任务流水号,用于 MES 系统的云端溯源 + + // 业务潜台词:采用 repeated 数组,Linux 可以一次性把全车所有的内参、外参一股脑发过去。 + // 车端只需一个 for 循环,把这些矩阵依次写进硬盘即可。 repeated CameraIntrinsics updated_intrinsics = 2; repeated SensorExtrinsics updated_extrinsics = 3; } \ No newline at end of file