feat:完善了自动标定车间的环境
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(agv_calib_core)
|
||||
|
||||
# 1. 寻找 ROS 2 依赖
|
||||
find_package(ament_cmake REQUIRED)
|
||||
find_package(rclcpp REQUIRED)
|
||||
|
||||
# 2. 寻找 gRPC 和 Protobuf 依赖
|
||||
find_package(Protobuf REQUIRED)
|
||||
find_package(gRPC REQUIRED)
|
||||
|
||||
# 3. 设置 Proto 文件路径与自动生成的源码输出路径
|
||||
set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/proto")
|
||||
set(PROTO_FILE "${PROTO_DIR}/agv_calib_control.proto")
|
||||
set(PROTO_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/grpc_gen")
|
||||
file(MAKE_DIRECTORY ${PROTO_OUT_DIR})
|
||||
|
||||
# 4. 自动生成 gRPC C++ 源码 (每次 colcon build 自动执行)
|
||||
find_program(GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
|
||||
add_custom_command(
|
||||
OUTPUT "${PROTO_OUT_DIR}/agv_calib_control.pb.cc"
|
||||
"${PROTO_OUT_DIR}/agv_calib_control.pb.h"
|
||||
"${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.cc"
|
||||
"${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.h"
|
||||
COMMAND protoc
|
||||
ARGS --proto_path="${PROTO_DIR}"
|
||||
--cpp_out="${PROTO_OUT_DIR}"
|
||||
--grpc_out="${PROTO_OUT_DIR}"
|
||||
--plugin=protoc-gen-grpc="${GRPC_CPP_PLUGIN_EXECUTABLE}"
|
||||
"${PROTO_FILE}"
|
||||
DEPENDS "${PROTO_FILE}"
|
||||
)
|
||||
|
||||
# 5. 将生成的网络源码打包成独立的 C++ 库
|
||||
add_library(agv_grpc_proto_lib SHARED
|
||||
"${PROTO_OUT_DIR}/agv_calib_control.pb.cc"
|
||||
"${PROTO_OUT_DIR}/agv_calib_control.grpc.pb.cc"
|
||||
)
|
||||
target_include_directories(agv_grpc_proto_lib PUBLIC "${PROTO_OUT_DIR}")
|
||||
target_link_libraries(agv_grpc_proto_lib gRPC::grpc++ protobuf::libprotobuf)
|
||||
|
||||
# 6. 编译您的 ROS 2 节点主程序
|
||||
add_executable(brain_node src/brain_node.cpp)
|
||||
ament_target_dependencies(brain_node rclcpp)
|
||||
# 🚨 必须链接刚才生成的 gRPC 库
|
||||
target_link_libraries(brain_node agv_grpc_proto_lib)
|
||||
|
||||
install(TARGETS brain_node DESTINATION lib/${PROJECT_NAME})
|
||||
ament_package()
|
||||
@@ -0,0 +1,94 @@
|
||||
# 🧠 AGV 标定中央大脑
|
||||
|
||||
**环境**: Ubuntu 22.04 + ROS 2 Humble | **语言**: C++ | **通信**: gRPC over Wi-Fi 6
|
||||
|
||||
> 标定车间的"发令大脑",通过局域网跨平台遥控 Windows 车端执行动作并拉取遥测数据。
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
|
||||
1. [系统依赖安装](#1-系统依赖一键安装)
|
||||
2. [VS Code 插件配置](#2-vs-code-核心插件配置)
|
||||
3. [解决 IntelliSense 报错](#3-解决-vs-code-红色波浪线)
|
||||
4. [编译与运行](#4-编译与运行)
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统依赖一键安装
|
||||
|
||||
在 Ubuntu 22.04 终端执行以下命令:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential cmake pkg-config gdb
|
||||
sudo apt install -y protobuf-compiler-grpc libgrpc++-dev libprotobuf-dev protobuf-compiler
|
||||
```
|
||||
|
||||
> ⚠️ **警告**: 严禁自行去 GitHub 源码编译 gRPC,直接使用 Ubuntu 官方 APT 源即可,避免浪费时间与报错。
|
||||
|
||||
---
|
||||
|
||||
## 2. VS Code 核心插件配置
|
||||
|
||||
打开 VS Code → 扩展商店 (Extensions),**必须安装**以下 4 个插件:
|
||||
|
||||
| 插件名称 | 开发者 | 用途 |
|
||||
|---------|--------|------|
|
||||
| **C/C++** | Microsoft | 代码补全与 GDB 调试 |
|
||||
| **CMake Tools** | Microsoft | 底部快速构建状态栏 |
|
||||
| **ROS** | Microsoft | 自动识别 `colcon` 工作空间 |
|
||||
| **vscode-proto3** | zxh404 | `.proto` 文件语法高亮 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 解决 VS Code 红色波浪线 (IntelliSense 报错)
|
||||
|
||||
**问题原因**: gRPC 生成的 `.pb.h` 文件在 `colcon build` 阶段动态生成于 `build/` 目录,VS Code 初始无法识别。
|
||||
|
||||
**修复步骤**:
|
||||
|
||||
1. 按 `Ctrl+Shift+P` → 输入 `C/C++: Edit Configurations (JSON)`
|
||||
2. 确保 `c_cpp_properties.json` 包含以下配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "ROS2",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/opt/ros/humble/include/**",
|
||||
"${workspaceFolder}/build/agv_calib_brain/grpc_gen/**"
|
||||
],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "linux-gcc-x64"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> 💡 **提示**: `grpc_gen` 是 CMakeLists 中配置的自动生成源码路径,请根据实际情况微调。
|
||||
|
||||
---
|
||||
|
||||
## 4. 编译与运行 (CMake 自动化)
|
||||
|
||||
> ✨ **无需手动执行 `protoc`** —— CMakeLists.txt 已配置自动化脚本,编译时自动生成 C++ 网络源码。
|
||||
|
||||
### 4.1 编译
|
||||
|
||||
```bash
|
||||
# 回到工作空间根目录(如 ~/agv_ws)
|
||||
source /opt/ros/humble/setup.bash
|
||||
colcon build --packages-select agv_calib_brain --symlink-install
|
||||
```
|
||||
|
||||
### 4.2 运行
|
||||
|
||||
```bash
|
||||
source install/setup.bash
|
||||
ros2 run agv_calib_brain brain_node
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>agv_calib_core</name>
|
||||
<version>0.0.0</version>
|
||||
<description>TODO: Package description</description>
|
||||
<maintainer email="2469171725@qq.com">nvidia</maintainer>
|
||||
<license>TODO: License declaration</license>
|
||||
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
|
||||
<test_depend>ament_lint_auto</test_depend>
|
||||
<test_depend>ament_lint_common</test_depend>
|
||||
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
</package>
|
||||
@@ -0,0 +1,143 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// 规范包名,确保与运控调优(control)和传感器外参(sensor)在逻辑上严格物理隔离
|
||||
package agv.calibration.chassis;
|
||||
|
||||
// =========================================================
|
||||
// 核心服务:AGV 底盘底层硬件自诊与物理运动学标定代理服务
|
||||
// 部署端:Windows车端 (直连底层电机驱动器/PLC 的网关层)
|
||||
// 调用端:Linux标定服务器 (掌控外部高精雷达真值)
|
||||
// =========================================================
|
||||
service AgvCalibChassisService {
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1. 底层硬件接管与安全熔断
|
||||
// ---------------------------------------------------------
|
||||
// 强制接管底层驱动器。注意:这里不仅要切断避障,还要切断底盘的“运动学正逆解算法”
|
||||
rpc SetDiagnosticMode(DiagnosticModeRequest) returns (StandardResponse);
|
||||
|
||||
// 硬件级绝对急停 (直接向驱动器下发 Safe Torque Off / 机械抱死指令,无视任何上层状态)
|
||||
rpc HardwareEmergencyBrake(Empty) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2. 原始物理开环指令下发 (对应方案 4.2 诊断 与 4.3 物理标定)
|
||||
// ---------------------------------------------------------
|
||||
// 允许 Linux 越过底盘协同模型,直接对指定驱动轮下发最原始的转速(RPM)或占空比
|
||||
// 核心用途:暴露真实的机械阻力差、诊断减速机卡死、测试轮胎滑移率
|
||||
rpc ExecuteRawDriveCommand(RawDriveRequest) returns (StandardResponse);
|
||||
|
||||
// 允许 Linux 直接对转向机构下发绝对物理角度或往复扫频
|
||||
// 核心用途:测定舵机机械死区、往复间隙(Backlash)与静态机械零位偏差
|
||||
rpc ExecuteRawSteerCommand(RawSteerRequest) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 3. 物理运动学本底参数持久化 (出厂定稿写值)
|
||||
// ---------------------------------------------------------
|
||||
// Linux 结合外部真值算出真实的物理机械参数后,下发并直接覆写到底盘驱动板 EEPROM 或底层配置中
|
||||
rpc CommitKinematicParameters(KinematicParams) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4. 原始硬件级高频遥测 (数字孪生健康诊断的唯一依据)
|
||||
// ---------------------------------------------------------
|
||||
// 🚨 严禁推流经过滤波后的数据!必须是最底层的“原始编码器 Tick”和“绝对相电流”!
|
||||
rpc StreamHardwareTelemetry(Empty) returns (stream HardwareState);
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 基础通用消息结构
|
||||
// =========================================================
|
||||
message Empty {}
|
||||
|
||||
message StandardResponse {
|
||||
bool success = 1;
|
||||
string message = 2; // 异常时返回驱动器底层故障码 (如 "ERR_MOTOR_OVERCURRENT")
|
||||
}
|
||||
|
||||
message DiagnosticModeRequest {
|
||||
enum Mode {
|
||||
NORMAL_KINEMATICS = 0; // 正常模式 (底盘接收 V_x, Omega,由底层执行运动学逆解分配)
|
||||
DIRECT_RAW_DRIVE = 1; // 直驱模式 (切断逆解,允许 Linux 直接独立控制左/右轮转速)
|
||||
}
|
||||
Mode target_mode = 1;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 2. 原始驱动指令 (发考题:逼迫底盘暴露出机械缺陷)
|
||||
// =========================================================
|
||||
message RawDriveRequest {
|
||||
string test_case_id = 1; // 测试用例 (如 "Slip_Test_0.5m", "Straight_Friction_Test")
|
||||
|
||||
// 直接下发给电机的原始指令 (若是两驱车,后轮填 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)
|
||||
|
||||
double duration_sec = 6; // 动作维持时间,断网防飞车底线:超时底层必须自动刹车
|
||||
}
|
||||
|
||||
message RawSteerRequest {
|
||||
string test_case_id = 1; // 测试用例 (如 "Deadzone_Sweep_5deg")
|
||||
|
||||
// 针对舵机/转向推杆的绝对物理指令 (度)
|
||||
double front_steer_angle_deg = 2;
|
||||
double rear_steer_angle_deg = 3;
|
||||
|
||||
// 专门用于 4.2节 测定机械间隙的扫频参数
|
||||
optional double sweep_amplitude_deg = 4; // 往复抖动幅度 (度)
|
||||
optional double sweep_frequency_hz = 5; // 抖动频率 (Hz)
|
||||
|
||||
double duration_sec = 6;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 3. 运动学本底参数定稿载荷 (纯物理修正系数)
|
||||
// =========================================================
|
||||
message KinematicParams {
|
||||
// --- 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度但车子斜着跑”) ---
|
||||
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; // 有效轴距 (前后轮真实物理间距)
|
||||
|
||||
// 针对四驱四转等多舵轮底盘:瞬时旋转中心(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=过热等
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// 规范包名,确保与传感器外参标定业务(agv.calibration.sensor)严格物理与逻辑隔离
|
||||
package agv.calibration.control;
|
||||
|
||||
// =========================================================
|
||||
// 核心服务:AGV 底盘运动学标定与运控参数调优代理服务
|
||||
// 部署端:Windows车端 (作为 gRPC Server)
|
||||
// 调用端:Linux标定服务器 (作为 gRPC Client)
|
||||
// =========================================================
|
||||
service AgvCalibControlService {
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 1. 权限接管与生命周期安全管控
|
||||
// ---------------------------------------------------------
|
||||
// 夺取车辆控制权,强制剥夺车端原生的激光避障与自主导航逻辑
|
||||
rpc SetControlMode(ModeRequest) returns (StandardResponse);
|
||||
|
||||
// 软件级最高优看门狗急停(应对网络断连、越界飞车等紧急状况,底层必须无条件抱死电机)
|
||||
rpc EmergencyStop(Empty) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 2. 运动考题下发 (开环排雷 / 闭环寻优 / 波峰对齐)
|
||||
// ---------------------------------------------------------
|
||||
// 【场景A: 纯物理开环】要求车端切断所有PID/运动学逆解,直接将转速/PWM透传给底层电机
|
||||
rpc ExecuteOpenLoopCmd(OpenLoopRequest) returns (StandardResponse);
|
||||
|
||||
// 【场景B: 算法闭环调优】下发测试轨迹,要求车端用"它自带的"运控算法(PID/MPC)去努力追踪
|
||||
rpc FollowTestTrajectory(TrajectoryRequest) returns (StandardResponse);
|
||||
|
||||
// 【场景C: 波峰时序对齐】下发极短促的阶跃加速指令,人为制造绝对速度波峰,供Linux提取Time Offset
|
||||
rpc ExecuteStepResponse(StepResponseRequest) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 3. 运控参数 AI 寻优:动态热注入与最终固化
|
||||
// ---------------------------------------------------------
|
||||
// 寻优核心:将 Linux 算出的临时参数瞬间写入车端内存并立刻生效,准许开始下一圈测试
|
||||
rpc InjectTuningParameters(ControlParams) returns (StandardResponse);
|
||||
|
||||
// 调优结束:通知车端将目前内存中的最高分参数,永久覆写进硬盘的 config.yaml 或注册表
|
||||
rpc CommitControlParameters(Empty) returns (StandardResponse);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4. 高频数字孪生体感上报 (50Hz)
|
||||
// ---------------------------------------------------------
|
||||
// 注意: 使用 server-streaming 服务端持续推流。车端被调用一次后,
|
||||
// 需以 50Hz 频率疯狂向外广播自身底层状态,供 Linux 提取波峰并比对真值打分。
|
||||
rpc StreamTelemetry(Empty) returns (stream TelemetryData);
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 基础通用消息结构
|
||||
// =========================================================
|
||||
message Empty {}
|
||||
|
||||
message StandardResponse {
|
||||
bool success = 1;
|
||||
string message = 2; // 包含执行成功的回执,或底盘卡死/驱动器报错等异常原因
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 1. 模式控制结构体
|
||||
// =========================================================
|
||||
message ModeRequest {
|
||||
enum Mode {
|
||||
NORMAL_MODE = 0; // 正常业务模式(打开避障和导航,出厂默认状态)
|
||||
OPEN_LOOP_MODE = 1; // 物理开环标定模式(切断所有算法纠偏,提线木偶状态)
|
||||
TUNING_MODE = 2; // 闭环调优模式(切断环境避障,但保留原生 PID/MPC 追踪算法)
|
||||
}
|
||||
Mode target_mode = 1;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 2. 动作指令请求载荷
|
||||
// =========================================================
|
||||
message OpenLoopRequest {
|
||||
double left_motor_cmd = 1; // 左驱动轮目标转速 (RPM) 或占空比
|
||||
double right_motor_cmd = 2; // 右驱动轮目标转速 (RPM) 或占空比
|
||||
double steering_angle = 3; // 针对单/多舵轮底盘的绝对舵角指令 (度,差速轮忽略)
|
||||
|
||||
// 🚨 极度关键的安全设计:指令超时时间
|
||||
// 车端若失去网络连接,超时后必须由底层代码强制将速度归零,严防撞墙!
|
||||
double duration_sec = 4;
|
||||
}
|
||||
|
||||
message TrajectoryPoint {
|
||||
double x_m = 1; // 目标点 X 坐标 (米)
|
||||
double y_m = 2; // 目标点 Y 坐标 (米)
|
||||
double yaw_rad = 3; // 目标点 偏航角 (弧度)
|
||||
double target_speed_ms = 4; // 到达该点时的期望线速度 (米/秒)
|
||||
double curvature = 5; // 该点处的轨迹曲率 (可选项,用于辅助前瞻距离映射)
|
||||
}
|
||||
|
||||
message TrajectoryRequest {
|
||||
string test_case_id = 1; // 考题名称,如 "Bezier_Curve_S_Speed_1.2"
|
||||
repeated TrajectoryPoint path = 2; // 组成考题曲线的稠密坐标点阵列
|
||||
}
|
||||
|
||||
message StepResponseRequest {
|
||||
double target_velocity_ms = 1; // 极速阶跃的目标线速度 (如猛烈加速到 1.5 m/s)
|
||||
double duration_sec = 2; // 阶跃维持时间 (极短,如 1~2 秒即可,用于产生绝对波峰)
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 3. 待调优运控参数载荷 (支持增量式热更新)
|
||||
// =========================================================
|
||||
message ControlParams {
|
||||
// 采用 optional 关键字,允许 Linux 每次只修改需要微调的单个参数,其余保持原样
|
||||
|
||||
// --- 底盘物理运动学修正系数 (由 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)
|
||||
optional double steering_zero_offset_deg = 4; // 舵角机械零位静态偏差 (度)
|
||||
|
||||
// --- 经典 PID 控制增益 ---
|
||||
optional double pid_kp_lateral = 5;
|
||||
optional double pid_ki_lateral = 6;
|
||||
optional double pid_kd_lateral = 7; // 用于提供阻尼,抑制高频画龙震荡
|
||||
|
||||
optional double pid_kp_heading = 8;
|
||||
optional double pid_ki_heading = 9;
|
||||
optional double pid_kd_heading = 10;
|
||||
|
||||
// --- 先进算法核心参数 ---
|
||||
optional double pure_pursuit_lookahead_m = 11; // 纯追踪前瞻距离 Ld (m)
|
||||
optional double mpc_weight_q_lateral = 12; // MPC Q矩阵:对横向误差的惩罚权重
|
||||
optional double mpc_weight_r_steering = 13; // MPC R矩阵:对转向电机发力剧烈度的惩罚权重 (控制平顺性)
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 4. 高频遥测推流载荷 (数字孪生状态汇报)
|
||||
// =========================================================
|
||||
message TelemetryData {
|
||||
// 🚨 互相关对齐的核心依据:
|
||||
// 必须使用 Windows 底层高精度单调时钟 (如 QueryPerformanceCounter) 的绝对微秒数。
|
||||
// 绝对禁止在车端人为做时序平滑或使用受 NTP 影响的系统时间!
|
||||
int64 hardware_timestamp_us = 1;
|
||||
|
||||
// --- 车端推算的内部里程计位姿 (Odom) ---
|
||||
double odom_x_m = 2;
|
||||
double odom_y_m = 3;
|
||||
double odom_yaw_rad = 4;
|
||||
|
||||
// --- 底层执行器真实物理反馈 (用于提取波峰) ---
|
||||
double feedback_linear_vel_ms = 5; // 编码器解算的真实线速度 (m/s)
|
||||
double feedback_angular_vel_rads = 6;// 陀螺仪或编码器解算的真实角速度 (rad/s)
|
||||
|
||||
// --- 硬件健康与功耗监控 (用于 Linux 诊断干涉卡死) ---
|
||||
double left_motor_current_amp = 7; // 左驱动电机实时电流 (A)
|
||||
double right_motor_current_amp = 8; // 右驱动电机实时电流 (A)
|
||||
double steering_motor_current_amp = 9; // 转向舵机实时电流 (A)
|
||||
|
||||
// --- 算法控制输出量 (用于 Linux 识别死区或物理饱和) ---
|
||||
double cmd_steering_output = 10; // 控制算法计算出的期望底层舵角指令 (度/弧度)
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// 规范包名,防止与其他业务(如底盘运控调优)的接口冲突
|
||||
package agv.calibration.sensor;
|
||||
|
||||
// =========================================================
|
||||
// 核心服务:传感器自动化标定代理服务
|
||||
// 部署端:Windows车端 (Server) | 调用端:Linux服务器 (Client)
|
||||
// =========================================================
|
||||
service SensorCalibrationService {
|
||||
// 1. 走位调度:指挥车辆开到特定的观测点并【绝对静止】
|
||||
rpc MoveToObservationPose (PoseRequest) returns (StandardResponse);
|
||||
|
||||
// 2. 同步锁存:命令车辆瞬间冻结指定传感器的当前画面/点云到内存
|
||||
rpc TriggerSyncCapture (CaptureRequest) returns (CaptureResponse);
|
||||
|
||||
// 3. 大文件下载:通过凭证流式拉取图片和点云(注意:使用 stream 防爆内存)
|
||||
rpc DownloadImage (DataFetchRequest) returns (stream FileChunk);
|
||||
rpc DownloadPointCloud (DataFetchRequest) returns (stream FileChunk);
|
||||
|
||||
// 4. 标定闭环:Linux算完矩阵后,下发给车端持久化保存(覆写配置文件)
|
||||
rpc CommitCalibrationResults (CalibrationPayload) returns (StandardResponse);
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 基础响应
|
||||
// =========================================================
|
||||
message StandardResponse {
|
||||
bool success = 1;
|
||||
string message = 2; // 成功提示或具体的报错原因(如:碰撞急停)
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 1. 物理走位请求 (走)
|
||||
// =========================================================
|
||||
message PoseRequest {
|
||||
double target_x_m = 1; // 目标 X 坐标 (米)
|
||||
double target_y_m = 2; // 目标 Y 坐标 (米)
|
||||
double target_yaw_deg = 3; // 目标偏航角 (度)
|
||||
bool is_relative = 4; // true: 相对当前位置移动; false: 绝对世界坐标
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 2. 触发同步抓拍请求与响应 (停与拍)
|
||||
// =========================================================
|
||||
message CaptureRequest {
|
||||
// 告诉车端这次要同时拍哪些传感器,例如 ["cam_front", "lidar_top"]
|
||||
repeated string sensor_ids = 1;
|
||||
}
|
||||
|
||||
message CaptureResponse {
|
||||
bool success = 1;
|
||||
// 极度关键:车端打上的高精度硬件时间戳(微秒)。
|
||||
// 这是提取数据的“取件码”,保证多传感器在物理时间上的绝对对齐!
|
||||
int64 capture_timestamp_us = 2;
|
||||
string error_message = 3;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 3. 大文件下载请求与文件流块 (传)
|
||||
// =========================================================
|
||||
message DataFetchRequest {
|
||||
int64 capture_timestamp_us = 1; // 阶段2拿到的取件码
|
||||
string sensor_id = 2; // 具体要下载哪个传感器,例如 "cam_front"
|
||||
}
|
||||
|
||||
// 流式文件块 (规避 gRPC 单条消息默认 4MB 的内存限制)
|
||||
message FileChunk {
|
||||
bytes chunk_data = 1; // 文件的二进制分块(建议每次发 512KB - 1MB)
|
||||
bool is_last_chunk = 2; // 是否为最后一块
|
||||
string format_ext = 3; // 格式标注,如 "png", "bmp", "pcd"
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// 4. 标定结果载荷(支持内参、外参灵活组合组合发回车端) (写)
|
||||
// =========================================================
|
||||
message CameraIntrinsics {
|
||||
string camera_id = 1;
|
||||
double fx = 2; double fy = 3;
|
||||
double cx = 4; double cy = 5;
|
||||
repeated double dist_coeffs = 6; // 畸变系数阵列 [k1, k2, p1, p2, k3]
|
||||
}
|
||||
|
||||
message SensorExtrinsics {
|
||||
string source_frame = 1; // 源坐标系,如 "lidar_top" 或 "cam_left"
|
||||
string target_frame = 2; // 目标坐标系,如 "cam_front" 或 "base_link"
|
||||
|
||||
// 平移向量 (强制规定单位为毫米 mm)
|
||||
double trans_x_mm = 3;
|
||||
double trans_y_mm = 4;
|
||||
double trans_z_mm = 5;
|
||||
|
||||
// 旋转姿态 (强制规定单位为度 degrees)
|
||||
double roll_deg = 6;
|
||||
double pitch_deg = 7;
|
||||
double yaw_deg = 8;
|
||||
}
|
||||
|
||||
message CalibrationPayload {
|
||||
string task_id = 1; // 标定任务流水号,用于 MES 系统追溯
|
||||
// 采用 repeated 数组:Linux 可以一次性下发多个相机的内参和多个外参
|
||||
repeated CameraIntrinsics updated_intrinsics = 2;
|
||||
repeated SensorExtrinsics updated_extrinsics = 3;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(calibration_sim)
|
||||
|
||||
# 1. 基础编译设置
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_compile_options(-Wall -Wextra -Wpedantic)
|
||||
endif()
|
||||
|
||||
# 2. 寻找依赖库
|
||||
find_package(ament_cmake REQUIRED)
|
||||
find_package(rclcpp REQUIRED)
|
||||
find_package(std_msgs REQUIRED)
|
||||
find_package(sensor_msgs REQUIRED) # 用于 PointCloud2
|
||||
find_package(geometry_msgs REQUIRED) # 用于坐标变换
|
||||
find_package(tf2_ros REQUIRED) # 坐标变换工具
|
||||
find_package(tf2_geometry_msgs REQUIRED)
|
||||
find_package(pcl_conversions REQUIRED)# ROS <-> PCL 转换桥梁
|
||||
|
||||
# 寻找系统级安装的 PCL 库 (非 ROS 包)
|
||||
find_package(PCL REQUIRED COMPONENTS common io visualization filters registration segmentation)
|
||||
|
||||
# 3. 定义可执行文件 (你的核心 C++ 节点)
|
||||
# 假设你将来会写一个 lidar_fusion_node.cpp
|
||||
#add_executable(lidar_fusion_node src/lidar_fusion_node.cpp)
|
||||
|
||||
# 4. 配置头文件路径
|
||||
#target_include_directories(lidar_fusion_node PUBLIC
|
||||
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
# $<INSTALL_INTERFACE:include>
|
||||
# ${PCL_INCLUDE_DIRS} # 必须包含 PCL 的头文件
|
||||
#)
|
||||
|
||||
# 5. 链接库文件
|
||||
# 链接 ROS 相关的依赖
|
||||
#ament_target_dependencies(lidar_fusion_node
|
||||
# rclcpp
|
||||
# std_msgs
|
||||
#sensor_msgs
|
||||
#geometry_msgs
|
||||
# tf2_ros
|
||||
# tf2_geometry_msgs
|
||||
# pcl_conversions
|
||||
#)
|
||||
|
||||
# 链接 PCL 相关的依赖 (PCL 不是 ament 包,需要单独链接)
|
||||
#target_link_libraries(lidar_fusion_node
|
||||
# ${PCL_LIBRARIES}
|
||||
#)
|
||||
|
||||
# 6. 安装规则 (至关重要!)
|
||||
|
||||
# 安装可执行文件 (C++ 节点)
|
||||
#install(TARGETS
|
||||
# lidar_fusion_node
|
||||
# DESTINATION lib/${PROJECT_NAME}
|
||||
#)
|
||||
|
||||
# 安装脚本文件 (如果你有 Python 节点)
|
||||
# install(PROGRAMS
|
||||
# scripts/my_python_script.py
|
||||
# DESTINATION lib/${PROJECT_NAME}
|
||||
# )
|
||||
|
||||
# 安装资源目录 (Launch, URDF, RViz, Worlds)
|
||||
# 如果没有这步,你的 ros2 launch 命令会找不到文件
|
||||
install(DIRECTORY
|
||||
launch
|
||||
urdf
|
||||
rviz
|
||||
worlds
|
||||
config
|
||||
DESTINATION share/${PROJECT_NAME}
|
||||
)
|
||||
|
||||
# 7. 导出依赖与生成包
|
||||
if(BUILD_TESTING)
|
||||
find_package(ament_lint_auto REQUIRED)
|
||||
# the following line skips the linter which checks for copyrights
|
||||
# comment the line when a copyright and license is added to all source files
|
||||
set(ament_cmake_copyright_FOUND TRUE)
|
||||
# the following line skips the linter which checks for eccentric indentation
|
||||
# comment the line when it conforms to defaults
|
||||
set(ament_cmake_cpplint_FOUND TRUE)
|
||||
ament_lint_auto_find_test_dependencies()
|
||||
endif()
|
||||
|
||||
ament_package()
|
||||
@@ -0,0 +1,73 @@
|
||||
import os
|
||||
from ament_index_python.packages import get_package_share_directory
|
||||
from launch import LaunchDescription
|
||||
from launch.actions import IncludeLaunchDescription, ExecuteProcess
|
||||
from launch.launch_description_sources import PythonLaunchDescriptionSource
|
||||
from launch_ros.actions import Node
|
||||
import xacro
|
||||
|
||||
def generate_launch_description():
|
||||
pkg_name = 'calibration_sim'
|
||||
|
||||
# 1. 解析 URDF
|
||||
infra_xacro = os.path.join(get_package_share_directory(pkg_name), 'urdf', 'workshop_sensors.xacro')
|
||||
infra_doc = xacro.process_file(infra_xacro)
|
||||
infra_xml = infra_doc.toxml()
|
||||
|
||||
agv_xacro = os.path.join(get_package_share_directory(pkg_name), 'urdf', 'agv.xacro')
|
||||
agv_doc = xacro.process_file(agv_xacro)
|
||||
agv_xml = agv_doc.toxml()
|
||||
|
||||
world_path = os.path.join(
|
||||
get_package_share_directory('calibration_sim'),
|
||||
'worlds',
|
||||
'calibration_room.world'
|
||||
)
|
||||
|
||||
# 2. 启动 Gazebo
|
||||
gazebo = IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource([os.path.join(
|
||||
get_package_share_directory('gazebo_ros'), 'launch', 'gazebo.launch.py')]),
|
||||
launch_arguments={'world': world_path}.items(), # 【关键】指定 world 参数
|
||||
)
|
||||
|
||||
# 3. 生成基础设施 (4个雷达)
|
||||
spawn_infra = Node(
|
||||
package='gazebo_ros', executable='spawn_entity.py',
|
||||
arguments=['-topic', 'robot_description_infra', '-entity', 'workshop_sensors'],
|
||||
output='screen'
|
||||
)
|
||||
|
||||
# 发布基础设施的 State Publisher (为了TF树)
|
||||
infra_state_publisher = Node(
|
||||
package='robot_state_publisher',
|
||||
executable='robot_state_publisher',
|
||||
name='infra_state_publisher',
|
||||
parameters=[{'robot_description': infra_xml}],
|
||||
remappings=[('robot_description', 'robot_description_infra')]
|
||||
)
|
||||
|
||||
# 4. 生成 AGV
|
||||
spawn_agv = Node(
|
||||
package='gazebo_ros', executable='spawn_entity.py',
|
||||
arguments=['-topic', 'robot_description_agv', '-entity', 'my_agv', '-z', '0.1'],
|
||||
output='screen'
|
||||
)
|
||||
|
||||
# 发布 AGV 的 State Publisher
|
||||
agv_state_publisher = Node(
|
||||
package='robot_state_publisher',
|
||||
executable='robot_state_publisher',
|
||||
name='agv_state_publisher',
|
||||
parameters=[{'robot_description': agv_xml}],
|
||||
remappings=[('robot_description', 'robot_description_agv')]
|
||||
)
|
||||
|
||||
return LaunchDescription([
|
||||
gazebo,
|
||||
infra_state_publisher,
|
||||
spawn_infra,
|
||||
agv_state_publisher,
|
||||
spawn_agv,
|
||||
# 这里还可以加上 RViz 的节点
|
||||
])
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>calibration_sim</name>
|
||||
<version>0.0.0</version>
|
||||
<description>Simulated environment for workshop calibration project</description>
|
||||
<maintainer email="user@todo.todo">User</maintainer>
|
||||
<license>TODO: License declaration</license>
|
||||
|
||||
<buildtool_depend>ament_cmake</buildtool_depend>
|
||||
|
||||
<depend>rclcpp</depend>
|
||||
<depend>std_msgs</depend>
|
||||
<depend>sensor_msgs</depend>
|
||||
<depend>geometry_msgs</depend>
|
||||
<depend>tf2_ros</depend>
|
||||
<depend>tf2_geometry_msgs</depend>
|
||||
<depend>pcl_conversions</depend>
|
||||
|
||||
<depend>gazebo_ros</depend> <test_depend>ament_lint_auto</test_depend>
|
||||
<test_depend>ament_lint_common</test_depend>
|
||||
|
||||
<export>
|
||||
<build_type>ament_cmake</build_type>
|
||||
</export>
|
||||
</package>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0"?>
|
||||
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="my_agv">
|
||||
|
||||
<link name="base_footprint"/>
|
||||
|
||||
<joint name="base_joint" type="fixed">
|
||||
<parent link="base_footprint"/>
|
||||
<child link="base_link"/>
|
||||
<origin xyz="0 0 0.1" rpy="0 0 0"/>
|
||||
</joint>
|
||||
|
||||
<link name="base_link">
|
||||
<visual>
|
||||
<geometry><box size="0.5 0.3 0.1"/></geometry>
|
||||
<material name="blue">
|
||||
<color rgba="0 0 1 1"/>
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<geometry><box size="0.5 0.3 0.1"/></geometry>
|
||||
</collision>
|
||||
<inertial>
|
||||
<mass value="5.0"/>
|
||||
<inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.1"/>
|
||||
</inertial>
|
||||
</link>
|
||||
|
||||
<xacro:macro name="wheel" params="prefix y_offset">
|
||||
<link name="${prefix}_wheel">
|
||||
<visual>
|
||||
<geometry><cylinder radius="0.1" length="0.05"/></geometry>
|
||||
<material name="black">
|
||||
<color rgba="0 0 0 1"/>
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<geometry><cylinder radius="0.1" length="0.05"/></geometry>
|
||||
</collision>
|
||||
<inertial>
|
||||
<mass value="1.0"/>
|
||||
<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
|
||||
</inertial>
|
||||
</link>
|
||||
|
||||
<joint name="${prefix}_wheel_joint" type="continuous">
|
||||
<parent link="base_link"/>
|
||||
<child link="${prefix}_wheel"/>
|
||||
<origin xyz="0 ${y_offset} -0.05" rpy="-1.57 0 0"/>
|
||||
<axis xyz="0 0 1"/>
|
||||
</joint>
|
||||
</xacro:macro>
|
||||
|
||||
<xacro:wheel prefix="left" y_offset="0.2"/>
|
||||
<xacro:wheel prefix="right" y_offset="-0.2"/>
|
||||
|
||||
<gazebo>
|
||||
<plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
|
||||
<ros>
|
||||
<namespace>/</namespace>
|
||||
</ros>
|
||||
<left_joint>left_wheel_joint</left_joint>
|
||||
<right_joint>right_wheel_joint</right_joint>
|
||||
<wheel_separation>0.4</wheel_separation>
|
||||
<wheel_diameter>0.2</wheel_diameter>
|
||||
<publish_odom>true</publish_odom>
|
||||
<publish_odom_tf>true</publish_odom_tf>
|
||||
<odometry_frame>odom</odometry_frame>
|
||||
<robot_base_frame>base_footprint</robot_base_frame>
|
||||
</plugin>
|
||||
</gazebo>
|
||||
|
||||
</robot>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0"?>
|
||||
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="calibration_board">
|
||||
|
||||
<link name="board_link">
|
||||
<visual>
|
||||
<geometry>
|
||||
<box size="1.0 1.0 0.02"/>
|
||||
</geometry>
|
||||
<material name="white">
|
||||
<color rgba="1 1 1 1"/>
|
||||
</material>
|
||||
</visual>
|
||||
<collision>
|
||||
<geometry>
|
||||
<box size="1.0 1.0 0.02"/>
|
||||
</geometry>
|
||||
</collision>
|
||||
<inertial>
|
||||
<mass value="1.0"/>
|
||||
<inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.1"/>
|
||||
</inertial>
|
||||
</link>
|
||||
|
||||
<gazebo reference="board_link">
|
||||
<material>Gazebo/Checkerboard</material>
|
||||
</gazebo>
|
||||
|
||||
<gazebo>
|
||||
<static>true</static>
|
||||
</gazebo>
|
||||
|
||||
</robot>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0"?>
|
||||
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="workshop_infrastructure">
|
||||
|
||||
<gazebo> <static>true</static> </gazebo>
|
||||
|
||||
<link name="workshop_anchor">
|
||||
<visual> <geometry><sphere radius="0.01"/></geometry> </visual>
|
||||
<inertial>
|
||||
<mass value="100"/>
|
||||
<inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1"/>
|
||||
</inertial>
|
||||
</link>
|
||||
|
||||
<material name="lidar_black"> <color rgba="0.1 0.1 0.1 1"/> </material>
|
||||
|
||||
<xacro:macro name="solid_state_lidar" params="name x y z yaw">
|
||||
<joint name="${name}_joint" type="fixed">
|
||||
<parent link="workshop_anchor"/>
|
||||
<child link="${name}_link"/>
|
||||
<origin xyz="${x} ${y} ${z}" rpy="0 0.35 ${yaw}"/>
|
||||
</joint>
|
||||
|
||||
<link name="${name}_link">
|
||||
<inertial>
|
||||
<mass value="0.5"/> <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
|
||||
</inertial>
|
||||
<visual>
|
||||
<geometry><box size="0.114 0.136 0.049"/></geometry>
|
||||
<material name="lidar_black"/>
|
||||
</visual>
|
||||
<collision>
|
||||
<geometry><box size="0.114 0.136 0.049"/></geometry>
|
||||
</collision>
|
||||
</link>
|
||||
|
||||
<gazebo reference="${name}_link">
|
||||
<material>Gazebo/FlatBlack</material>
|
||||
|
||||
<sensor type="gpu_ray" name="${name}_sensor">
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
<visualize>false</visualize>
|
||||
<update_rate>10</update_rate> <ray>
|
||||
<scan>
|
||||
<horizontal>
|
||||
<samples>600</samples>
|
||||
<resolution>1</resolution>
|
||||
<min_angle>-0.7854</min_angle>
|
||||
<max_angle>0.7854</max_angle>
|
||||
</horizontal>
|
||||
|
||||
<vertical>
|
||||
<samples>128</samples>
|
||||
<resolution>1</resolution>
|
||||
<min_angle>-0.2181</min_angle>
|
||||
<max_angle>0.2251</max_angle>
|
||||
</vertical>
|
||||
</scan>
|
||||
|
||||
<range>
|
||||
<min>0.5</min> <max>210.0</max>
|
||||
</range>
|
||||
|
||||
<noise>
|
||||
<type>gaussian</type>
|
||||
<mean>0.0</mean>
|
||||
<stddev>0.03</stddev>
|
||||
</noise>
|
||||
</ray>
|
||||
|
||||
<plugin name="${name}_controller" filename="libgazebo_ros_ray_sensor.so">
|
||||
<ros>
|
||||
<namespace>/infrastructure</namespace>
|
||||
<remapping>~/out:=${name}/points</remapping>
|
||||
</ros>
|
||||
<output_type>sensor_msgs/PointCloud2</output_type>
|
||||
<frame_name>${name}_link</frame_name>
|
||||
</plugin>
|
||||
</sensor>
|
||||
</gazebo>
|
||||
</xacro:macro>
|
||||
|
||||
<xacro:solid_state_lidar name="lidar_fl" x="4.8" y="4.8" z="2.4" yaw="-2.356"/>
|
||||
<xacro:solid_state_lidar name="lidar_fr" x="4.8" y="-4.8" z="2.4" yaw="2.356"/>
|
||||
<xacro:solid_state_lidar name="lidar_bl" x="-4.8" y="4.8" z="2.4" yaw="-0.785"/>
|
||||
<xacro:solid_state_lidar name="lidar_br" x="-4.8" y="-4.8" z="2.4" yaw="0.785"/>
|
||||
|
||||
</robot>
|
||||
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" ?>
|
||||
<sdf version="1.6">
|
||||
<world name="calibration_world">
|
||||
|
||||
<scene>
|
||||
<ambient>0.6 0.6 0.6 1.0</ambient>
|
||||
<background>0.7 0.7 0.7 1.0</background>
|
||||
<shadows>true</shadows>
|
||||
</scene>
|
||||
|
||||
<include><uri>model://ground_plane</uri></include>
|
||||
|
||||
<model name="calibration_room_structure">
|
||||
<static>true</static>
|
||||
<pose>0 0 0 0 0 0</pose>
|
||||
<link name="wall_north"><pose>0 5 1.25 0 0 0</pose><collision name="c"><geometry><box><size>10.2 0.2 2.5</size></box></geometry></collision><visual name="v"><geometry><box><size>10.2 0.2 2.5</size></box></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/Grey</name></script></material></visual></link>
|
||||
<link name="wall_south"><pose>0 -5 1.25 0 0 0</pose><collision name="c"><geometry><box><size>10.2 0.2 2.5</size></box></geometry></collision><visual name="v"><geometry><box><size>10.2 0.2 2.5</size></box></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/Grey</name></script></material></visual></link>
|
||||
<link name="wall_east"><pose>5 0 1.25 0 0 0</pose><collision name="c"><geometry><box><size>0.2 10.0 2.5</size></box></geometry></collision><visual name="v"><geometry><box><size>0.2 10.0 2.5</size></box></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/Grey</name></script></material></visual></link>
|
||||
<link name="wall_west"><pose>-5 0 1.25 0 0 0</pose><collision name="c"><geometry><box><size>0.2 10.0 2.5</size></box></geometry></collision><visual name="v"><geometry><box><size>0.2 10.0 2.5</size></box></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/Grey</name></script></material></visual></link>
|
||||
</model>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_n1</name><pose>-3.75 4.89 1.25 1.57 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_n2</name><pose>-1.25 4.89 1.25 1.57 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_n3</name><pose> 1.25 4.89 1.25 1.57 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_n4</name><pose> 3.75 4.89 1.25 1.57 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_s1</name><pose>-3.75 -4.89 1.25 1.57 0 3.14159</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_s2</name><pose>-1.25 -4.89 1.25 1.57 0 3.14159</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_s3</name><pose> 1.25 -4.89 1.25 1.57 0 3.14159</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_s4</name><pose> 3.75 -4.89 1.25 1.57 0 3.14159</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_e1</name><pose>4.89 -3.75 1.25 1.57 0 -1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_e2</name><pose>4.89 -1.25 1.25 1.57 0 -1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_e3</name><pose>4.89 1.25 1.25 1.57 0 -1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_e4</name><pose>4.89 3.75 1.25 1.57 0 -1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_w1</name><pose>-4.89 -3.75 1.25 1.57 0 1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_w2</name><pose>-4.89 -1.25 1.25 1.57 0 1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_w3</name><pose>-4.89 1.25 1.25 1.57 0 1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>board_w4</name><pose>-4.89 3.75 1.25 1.57 0 1.57</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
|
||||
<model name="ceiling_lights_4x4">
|
||||
<static>true</static>
|
||||
<pose>0 0 2.5 0 0 0</pose>
|
||||
<link name="link">
|
||||
<visual name="v1_1"><cast_shadows>0</cast_shadows><pose>-4.5 -4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v1_2"><cast_shadows>0</cast_shadows><pose>-1.5 -4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v1_3"><cast_shadows>0</cast_shadows><pose> 1.5 -4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v1_4"><cast_shadows>0</cast_shadows><pose> 4.5 -4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v2_1"><cast_shadows>0</cast_shadows><pose>-4.5 -1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v2_2"><cast_shadows>0</cast_shadows><pose>-1.5 -1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v2_3"><cast_shadows>0</cast_shadows><pose> 1.5 -1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v2_4"><cast_shadows>0</cast_shadows><pose> 4.5 -1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v3_1"><cast_shadows>0</cast_shadows><pose>-4.5 1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v3_2"><cast_shadows>0</cast_shadows><pose>-1.5 1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v3_3"><cast_shadows>0</cast_shadows><pose> 1.5 1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v3_4"><cast_shadows>0</cast_shadows><pose> 4.5 1.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v4_1"><cast_shadows>0</cast_shadows><pose>-4.5 4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v4_2"><cast_shadows>0</cast_shadows><pose>-1.5 4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v4_3"><cast_shadows>0</cast_shadows><pose> 1.5 4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
<visual name="v4_4"><cast_shadows>0</cast_shadows><pose> 4.5 4.5 0 0 0 0</pose><geometry><cylinder><radius>0.1</radius><length>0.05</length></cylinder></geometry><material><script><uri>file://media/materials/scripts/gazebo.material</uri><name>Gazebo/WhiteGlow</name></script><emissive>0.5 0.5 0.5 1</emissive></material></visual>
|
||||
</link>
|
||||
</model>
|
||||
|
||||
<light name='l1_1' type='point'><pose>-4.5 -4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l1_2' type='point'><pose>-1.5 -4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l1_3' type='point'><pose> 1.5 -4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l1_4' type='point'><pose> 4.5 -4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l2_1' type='point'><pose>-4.5 -1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l2_2' type='point'><pose>-1.5 -1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l2_3' type='point'><pose> 1.5 -1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l2_4' type='point'><pose> 4.5 -1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l3_1' type='point'><pose>-4.5 1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l3_2' type='point'><pose>-1.5 1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l3_3' type='point'><pose> 1.5 1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l3_4' type='point'><pose> 4.5 1.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l4_1' type='point'><pose>-4.5 4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l4_2' type='point'><pose>-1.5 4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l4_3' type='point'><pose> 1.5 4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
<light name='l4_4' type='point'><pose> 4.5 4.5 2.45 0 0 0</pose><diffuse>0.3 0.3 0.3 1</diffuse><specular>0.1 0.1 0.1 1</specular><attenuation><range>6</range><constant>0.2</constant><linear>0.05</linear><quadratic>0.1</quadratic></attenuation><cast_shadows>0</cast_shadows></light>
|
||||
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_n1</name><pose>-3.75 3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_n2</name><pose>-1.25 3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_n3</name><pose> 1.25 3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_n4</name><pose> 3.75 3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_s1</name><pose>-3.75 -3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_s2</name><pose>-1.25 -3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_s3</name><pose> 1.25 -3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_s4</name><pose> 3.75 -3.75 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_e1</name><pose>3.75 -1.25 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_e2</name><pose>3.75 1.25 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_w1</name><pose>-3.75 -1.25 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
<include><uri>model://checkerboard_plane</uri><name>floor_w2</name><pose>-3.75 1.25 0.01 0 0 0</pose><scale>0.3125 0.3125 1</scale></include>
|
||||
|
||||
</world>
|
||||
</sdf>
|
||||
Reference in New Issue
Block a user