diff --git "a/hi-slam/Cartographer\345\256\211\350\243\205\346\225\231\347\250\213.md" "b/hi-slam/Cartographer\345\256\211\350\243\205\346\225\231\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..b45a363ef4e35fe989cb0fd5535cd2ff7c6bde73 --- /dev/null +++ "b/hi-slam/Cartographer\345\256\211\350\243\205\346\225\231\347\250\213.md" @@ -0,0 +1,160 @@ +# Cartographer建图过程介绍 + +这里只给出源码安装方式,若简单apt安装请百度搜索、 + +## 1.源码安装 + +```sh +创建工作间 +mkdir ros2_ws +cd ros2_ws +mkdir src +cd src + +``` + +将下面的源码克隆到ros2_ws的src目录下 + +```sh +git clone https://github.com/ros2/cartographer.git -b ros2 +git clone https://github.com/ros2/cartographer_ros.git -b ros2 +``` + +## 2.依赖安装 + +运行如下命令进行依赖的安装 + +```sh +rosdepc install -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y +``` + +> 如果依赖安装失败或没有rosdepc,使用如下命令先安装rosdepc + +```sh +wget http://fishros.com/install -O fishros && . fishros +``` + +选择一键配置rosdep即可 + +> rosdepc 是小鱼制作的国内版rosdep,是一个用于安装依赖的工具。该工具的安装可以采用[一键安装](https://fishros.org.cn/forum/topic/20)进行,选项编号为3。安装完成后运行一次rodepc update即可使用。 + +## 3.编译 + +```sh +colcon build --packages-up-to cartographer_ros +``` + +> –packages-up-to,意思是其所有依赖后再编译该包 + +## 4.测试安装是否成功 + +```sh +ros2 pkg list | grep cartographer +``` + +能看到下面结果即可 + +```sh +cartographer_ros +cartographer_ros_msgs +``` + +## 5.Cartographer参数配置 + +### 5.1前端参数 + +#### 文件:trajectory_builder_2d + +路径:src/cartographer/configuration_files/trajectory_builder_2d.lua + +```lua + -- 是否使用IMU数据 + use_imu_data = true, + -- 深度数据最小范围 + min_range = 0., + -- 深度数据最大范围 + max_range = 30., + -- 传感器数据超出有效范围最大值时,按此值来处理 + missing_data_ray_length = 5., + -- 是否使用实时回环检测来进行前端的扫描匹配 + use_online_correlative_scan_matching = true + -- 运动过滤,检测运动变化,避免机器人静止时插入数据 + motion_filter.max_angle_radians +``` + +### 5.2后端参数 + +#### 文件:pose_graph.lua + +路径:src/cartographer/configuration_files/pose_graph.lua + +```lua +--Fast csm的最低分数,高于此分数才进行优化。 +constraint_builder.min_score = 0.65 +--全局定位最小分数,低于此分数则认为目前全局定位不准确 +constraint_builder.global_localization_min_score = 0.7 +``` + +### 5.3Carotgrapher_ROS参数配置 + +#### 文件:backpack_2d.lua + +路径:src/cartographer_ros/cartographer_ros/configuration_files/backpack_2d.lua + +```lua +include "map_builder.lua" +include "trajectory_builder.lua" + +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + -- 用来发布子地图的ROS坐标系ID,位姿的父坐标系,通常是map。 + map_frame = "map", + -- SLAM算法跟随的坐标系ID + tracking_frame = "base_link", + -- 将发布map到published_frame之间的tf + published_frame = "base_link", + -- 位于“published_frame ”和“map_frame”之间,用来发布本地SLAM结果(非闭环),通常是“odom” + odom_frame = "odom", + -- 是否提供里程计 + provide_odom_frame = true, + -- 只发布二维位姿态(不包含俯仰角) + publish_frame_projected_to_2d = false, + -- 是否使用里程计数据 + use_odometry = false, + -- 是否使用GPS定位 + use_nav_sat = false, + -- 是否使用路标 + use_landmarks = false, + -- 订阅的laser scan topics的个数 + num_laser_scans = 0, + -- 订阅多回波技术laser scan topics的个数 + num_multi_echo_laser_scans = 1, + -- 分割雷达数据的个数 + num_subdivisions_per_laser_scan = 10, + -- 订阅的点云topics的个数 + num_point_clouds = 0, + -- 使用tf2查找变换的超时秒数 + lookup_transform_timeout_sec = 0.2, + -- 发布submap的周期间隔 + submap_publish_period_sec = 0.3, + -- 发布姿态的周期间隔 + pose_publish_period_sec = 5e-3, + -- 轨迹发布周期间隔 + trajectory_publish_period_sec = 30e-3, + -- 测距仪的采样率 + rangefinder_sampling_ratio = 1., + --里程记数据采样率 + odometry_sampling_ratio = 1., + -- 固定的frame位姿采样率 + fixed_frame_pose_sampling_ratio = 1., + -- IMU数据采样率 + imu_sampling_ratio = 1., + -- 路标采样率 + landmarks_sampling_ratio = 1., +} +``` + +参考文章: + +https://blog.csdn.net/qq_27865227/article/details/132525447?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172481287416800225526597%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=172481287416800225526597&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-132525447-null-null.nonecase&utm_term=Cartographer&spm=1018.2226.3001.4450 \ No newline at end of file diff --git "a/hi-slam/Cartographer\345\273\272\345\233\276\350\277\207\347\250\213\344\273\213\347\273\215.md" "b/hi-slam/Cartographer\345\273\272\345\233\276\350\277\207\347\250\213\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..b45a363ef4e35fe989cb0fd5535cd2ff7c6bde73 --- /dev/null +++ "b/hi-slam/Cartographer\345\273\272\345\233\276\350\277\207\347\250\213\344\273\213\347\273\215.md" @@ -0,0 +1,160 @@ +# Cartographer建图过程介绍 + +这里只给出源码安装方式,若简单apt安装请百度搜索、 + +## 1.源码安装 + +```sh +创建工作间 +mkdir ros2_ws +cd ros2_ws +mkdir src +cd src + +``` + +将下面的源码克隆到ros2_ws的src目录下 + +```sh +git clone https://github.com/ros2/cartographer.git -b ros2 +git clone https://github.com/ros2/cartographer_ros.git -b ros2 +``` + +## 2.依赖安装 + +运行如下命令进行依赖的安装 + +```sh +rosdepc install -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y +``` + +> 如果依赖安装失败或没有rosdepc,使用如下命令先安装rosdepc + +```sh +wget http://fishros.com/install -O fishros && . fishros +``` + +选择一键配置rosdep即可 + +> rosdepc 是小鱼制作的国内版rosdep,是一个用于安装依赖的工具。该工具的安装可以采用[一键安装](https://fishros.org.cn/forum/topic/20)进行,选项编号为3。安装完成后运行一次rodepc update即可使用。 + +## 3.编译 + +```sh +colcon build --packages-up-to cartographer_ros +``` + +> –packages-up-to,意思是其所有依赖后再编译该包 + +## 4.测试安装是否成功 + +```sh +ros2 pkg list | grep cartographer +``` + +能看到下面结果即可 + +```sh +cartographer_ros +cartographer_ros_msgs +``` + +## 5.Cartographer参数配置 + +### 5.1前端参数 + +#### 文件:trajectory_builder_2d + +路径:src/cartographer/configuration_files/trajectory_builder_2d.lua + +```lua + -- 是否使用IMU数据 + use_imu_data = true, + -- 深度数据最小范围 + min_range = 0., + -- 深度数据最大范围 + max_range = 30., + -- 传感器数据超出有效范围最大值时,按此值来处理 + missing_data_ray_length = 5., + -- 是否使用实时回环检测来进行前端的扫描匹配 + use_online_correlative_scan_matching = true + -- 运动过滤,检测运动变化,避免机器人静止时插入数据 + motion_filter.max_angle_radians +``` + +### 5.2后端参数 + +#### 文件:pose_graph.lua + +路径:src/cartographer/configuration_files/pose_graph.lua + +```lua +--Fast csm的最低分数,高于此分数才进行优化。 +constraint_builder.min_score = 0.65 +--全局定位最小分数,低于此分数则认为目前全局定位不准确 +constraint_builder.global_localization_min_score = 0.7 +``` + +### 5.3Carotgrapher_ROS参数配置 + +#### 文件:backpack_2d.lua + +路径:src/cartographer_ros/cartographer_ros/configuration_files/backpack_2d.lua + +```lua +include "map_builder.lua" +include "trajectory_builder.lua" + +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + -- 用来发布子地图的ROS坐标系ID,位姿的父坐标系,通常是map。 + map_frame = "map", + -- SLAM算法跟随的坐标系ID + tracking_frame = "base_link", + -- 将发布map到published_frame之间的tf + published_frame = "base_link", + -- 位于“published_frame ”和“map_frame”之间,用来发布本地SLAM结果(非闭环),通常是“odom” + odom_frame = "odom", + -- 是否提供里程计 + provide_odom_frame = true, + -- 只发布二维位姿态(不包含俯仰角) + publish_frame_projected_to_2d = false, + -- 是否使用里程计数据 + use_odometry = false, + -- 是否使用GPS定位 + use_nav_sat = false, + -- 是否使用路标 + use_landmarks = false, + -- 订阅的laser scan topics的个数 + num_laser_scans = 0, + -- 订阅多回波技术laser scan topics的个数 + num_multi_echo_laser_scans = 1, + -- 分割雷达数据的个数 + num_subdivisions_per_laser_scan = 10, + -- 订阅的点云topics的个数 + num_point_clouds = 0, + -- 使用tf2查找变换的超时秒数 + lookup_transform_timeout_sec = 0.2, + -- 发布submap的周期间隔 + submap_publish_period_sec = 0.3, + -- 发布姿态的周期间隔 + pose_publish_period_sec = 5e-3, + -- 轨迹发布周期间隔 + trajectory_publish_period_sec = 30e-3, + -- 测距仪的采样率 + rangefinder_sampling_ratio = 1., + --里程记数据采样率 + odometry_sampling_ratio = 1., + -- 固定的frame位姿采样率 + fixed_frame_pose_sampling_ratio = 1., + -- IMU数据采样率 + imu_sampling_ratio = 1., + -- 路标采样率 + landmarks_sampling_ratio = 1., +} +``` + +参考文章: + +https://blog.csdn.net/qq_27865227/article/details/132525447?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172481287416800225526597%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=172481287416800225526597&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-132525447-null-null.nonecase&utm_term=Cartographer&spm=1018.2226.3001.4450 \ No newline at end of file diff --git a/hi-slam/PID_change/PID.md b/hi-slam/PID_change/PID.md new file mode 100644 index 0000000000000000000000000000000000000000..7e82c24b019299b7a66dc7e61cb65de8665d05b4 --- /dev/null +++ b/hi-slam/PID_change/PID.md @@ -0,0 +1,56 @@ +# 小车底盘代码修改 + +## 下载代码 + +```shell +git clone https://gitee.com/HiEuler/eulercar_controller.git +``` + +在`HiSpark Studio`中打开工程,此时工程中会有很多报错,将`c_cpp_properties.json`内的`compilerPath`更改到自己电脑中`HiSpark Studio`安装路径下即可解决 + +
image-20240810164937528image-20240810164455488
+ + +修改`Euler_car.hiproj`中选项,删除`ZDU3061MNPICA`前的`ZDU`,`sdk_path`替换成自己电脑上的路径,修改程序烧录端口号和波特率,在`main.c`中选择正确的电机参数 + +
image-20240810162250427image-20240810162410179image-20240810163823546
+ + +为了使用串口进行调参,要使用串口0,首先在`./user/generatecode/main.h`中声明串口0中断服务函数 + +image-20240810170152582 + +打开`./user/generatecode/system_init.c`,定义串口0中断服务函数,修改`UART0_Init()`,设置串口0接收模式为中断接收,接收`fifo`水线设置为1,使能串口接收中断 + +image-20240810170343639 + +打开`./user/eulercar_control.c`,定义串口调参相关变量、串口0下发数据代码 + +
image-20240814130927265image-20240814131022174
+ +添加串口0中断接收函数和协议解析函数 + +image-20240814142126203 + +将串口0数据发送函数添加到定时器0中断内 + +image-20240814162730458 + +串口0接收解析函数,转速执行函数放在`while(1)`中,将按键功能更改为调整目标速度 + +image-20240814164248792 + +改动后的代码工程下载链接: + +>https://github.com/codingnoobwyh/Eulercar_PID_Params_Tuning.git + +# Qt上位机 + +使用欧拉小车上排针引出的串口0连接电脑,在Qt上位机中打开对应串口,波特率选择115200,使用按键调整预期速度。按下`开始转动`按键,小车电机则开始转动;按下`停止转动`按键,电机停止转动,PID积分项清零。输入框中输入对应参数按下`设定参数`可以调整PID参数 + +
image-20240815131303179image-20240814195148168
+如果发现电机总是满转速转动,可能是不同的小车电机驱动引脚连接相反,在代码中将两个大于号替换为小于号 + +image-20240815133719967 + +image-20240815133749789 diff --git a/hi-slam/PID_change/image/image-20240810162250427.png b/hi-slam/PID_change/image/image-20240810162250427.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddd05d94d14f147612346fd86f9a6f9f39fd58b Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810162250427.png differ diff --git a/hi-slam/PID_change/image/image-20240810162410179.png b/hi-slam/PID_change/image/image-20240810162410179.png new file mode 100644 index 0000000000000000000000000000000000000000..5886d682efbab46ba26311966b5fd67d8ea4be08 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810162410179.png differ diff --git a/hi-slam/PID_change/image/image-20240810163823546.png b/hi-slam/PID_change/image/image-20240810163823546.png new file mode 100644 index 0000000000000000000000000000000000000000..0fdd4f6faed072f0fd4d65ef403e995e687834b2 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810163823546.png differ diff --git a/hi-slam/PID_change/image/image-20240810164455488.png b/hi-slam/PID_change/image/image-20240810164455488.png new file mode 100644 index 0000000000000000000000000000000000000000..d510c2ec22e95bdaa4c540c79171668f1683e2a2 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810164455488.png differ diff --git a/hi-slam/PID_change/image/image-20240810164937528.png b/hi-slam/PID_change/image/image-20240810164937528.png new file mode 100644 index 0000000000000000000000000000000000000000..24187a15232fc17de478ec23ae5c972fa73cb834 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810164937528.png differ diff --git a/hi-slam/PID_change/image/image-20240810170152582.png b/hi-slam/PID_change/image/image-20240810170152582.png new file mode 100644 index 0000000000000000000000000000000000000000..327213dac0db5e8743f65facb582742d2942bb44 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810170152582.png differ diff --git a/hi-slam/PID_change/image/image-20240810170343639.png b/hi-slam/PID_change/image/image-20240810170343639.png new file mode 100644 index 0000000000000000000000000000000000000000..50ad26ef3c3afe252b81c983b01203ef50b80df9 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240810170343639.png differ diff --git a/hi-slam/PID_change/image/image-20240814130927265.png b/hi-slam/PID_change/image/image-20240814130927265.png new file mode 100644 index 0000000000000000000000000000000000000000..9344bfebab598c35ce2df2a37bee09b7089cea9b Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814130927265.png differ diff --git a/hi-slam/PID_change/image/image-20240814131020763.png b/hi-slam/PID_change/image/image-20240814131020763.png new file mode 100644 index 0000000000000000000000000000000000000000..a09655b35874ae3f0f76ff3610ee1786e30788c6 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814131020763.png differ diff --git a/hi-slam/PID_change/image/image-20240814131022174.png b/hi-slam/PID_change/image/image-20240814131022174.png new file mode 100644 index 0000000000000000000000000000000000000000..a09655b35874ae3f0f76ff3610ee1786e30788c6 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814131022174.png differ diff --git a/hi-slam/PID_change/image/image-20240814142126203.png b/hi-slam/PID_change/image/image-20240814142126203.png new file mode 100644 index 0000000000000000000000000000000000000000..cfdfbb00e5cc8855248042d593c32560aed0a19b Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814142126203.png differ diff --git a/hi-slam/PID_change/image/image-20240814162730458.png b/hi-slam/PID_change/image/image-20240814162730458.png new file mode 100644 index 0000000000000000000000000000000000000000..a27e9b6aafefed9211347c6056e41da8480ccadb Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814162730458.png differ diff --git a/hi-slam/PID_change/image/image-20240814163540747.png b/hi-slam/PID_change/image/image-20240814163540747.png new file mode 100644 index 0000000000000000000000000000000000000000..006543059b986b722374a27bfc0878d63ffd405a Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814163540747.png differ diff --git a/hi-slam/PID_change/image/image-20240814164248792.png b/hi-slam/PID_change/image/image-20240814164248792.png new file mode 100644 index 0000000000000000000000000000000000000000..5c4abc33427e3a8efd23d96c2dde9c91b868a1d8 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814164248792.png differ diff --git a/hi-slam/PID_change/image/image-20240814195148168.png b/hi-slam/PID_change/image/image-20240814195148168.png new file mode 100644 index 0000000000000000000000000000000000000000..547f63c9a03fa252ffa6bb76afdaa0a75c6bfd2e Binary files /dev/null and b/hi-slam/PID_change/image/image-20240814195148168.png differ diff --git a/hi-slam/PID_change/image/image-20240815131303179.png b/hi-slam/PID_change/image/image-20240815131303179.png new file mode 100644 index 0000000000000000000000000000000000000000..084e4f65ddbe86552a24d1e2359c7af861b30690 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240815131303179.png differ diff --git a/hi-slam/PID_change/image/image-20240815131305888.png b/hi-slam/PID_change/image/image-20240815131305888.png new file mode 100644 index 0000000000000000000000000000000000000000..084e4f65ddbe86552a24d1e2359c7af861b30690 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240815131305888.png differ diff --git a/hi-slam/PID_change/image/image-20240815133719967.png b/hi-slam/PID_change/image/image-20240815133719967.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd7a96d4f86768e007223d0197f9afd85398a0d Binary files /dev/null and b/hi-slam/PID_change/image/image-20240815133719967.png differ diff --git a/hi-slam/PID_change/image/image-20240815133749789.png b/hi-slam/PID_change/image/image-20240815133749789.png new file mode 100644 index 0000000000000000000000000000000000000000..f159b214f158c58309e41482fa7fc404abdac9a7 Binary files /dev/null and b/hi-slam/PID_change/image/image-20240815133749789.png differ diff --git a/hi-slam/REP-105.md b/hi-slam/REP-105.md new file mode 100644 index 0000000000000000000000000000000000000000..ea157a08d2614604d3ddc42d92e1d75ef15b9996 --- /dev/null +++ b/hi-slam/REP-105.md @@ -0,0 +1,57 @@ +# **REP-105** + +REP-105 是一个名为 “Coordinate Frames for Mobile Platforms”(移动平台的坐标系框架)的 ROS Enhancement Proposal(REP)。该提案由 Wim Meeussen 于 2010年10月27日 创建,并处于活动状态。本文将介绍 REP-105 的内容,包括其摘要、动机、规范、坐标系、坐标系之间的关系等。 + +## 1.摘要 + +**REP-105** 规定了用于 **ROS** 的移动平台的坐标系的命名约定和语义含义。 + +## + +## 2.目的 + +开发者需要共享的坐标系约定,以更好地集成和重用驱动程序、模型和库等软件组件。这个共享的坐标系约定可为创建移动基座的驱动程序和模型的开发者提供规范。同样,创建库和应用程序的开发者可以更轻松地将其软件与兼容此规范的多种移动基座一起使用。例如,REP-105 规定了编写新的定位组件所需的坐标系。它还规定了用于引用机器人的移动基座的坐标系。 + + +## 3.规范 + +### 3.1坐标系 + +#### base_link + +名为 *“base_link”* 的坐标系刚性地附加在移动机器人的基座上。可以将 *“base_link”* 以任意的位置或方向附加到基座上;对于每个硬件平台,基座上提供明显参考点的位置可能不同。需要注意的是,**REP-103** 指定了坐标系的首选方向。 + +#### odom + +名为 “odom” 的坐标系是一个世界固定坐标系。在 “odom” 坐标系中,移动平台的姿态随时间可能会漂移,但没有界限。这种漂移使得 “odom” 坐标系作为长期全局参考无用。然而,机器人在 “odom” 坐标系中的姿态保证是连续的,这意味着机器人在 “odom” 坐标系中的姿态始终以平稳的方式演变,没有离散的跳跃。 + +在典型的设置中,基于测距源(如轮式测距、视觉测距或惯性测量单元)计算了 *“odom”* 坐标系。机器人在 *“odom”* 坐标系中的姿态是基于这些测距源计算的。 + +*“odom”* 坐标系作为准确的短期局部参考很有用,但漂移使其成为长期参考的较差坐标系。 + +#### map + +名为 “map” 的坐标系是一个世界固定坐标系,其Z轴指向上方。移动平台相对于 “map” 坐标系的姿态随时间不应显著漂移。但 “map” 坐标系不连续,这意味着移动平台在 “map” 坐标系中的姿态可以在任何时候以离散跳跃的方式发生变化。 + +在典型的设置中,定位组件基于传感器观测不断重新计算机器人在 “map” 坐标系中的姿态,从而消除漂移,但当新的传感器信息到达时会导致离散跳跃。 + +“map” 坐标系作为长期全局参考很有用,但在位置估计器中的离散跳跃使其成为局部感知和操作的较差参考坐标系。 + +### 3.2 Map约定 + +地图坐标系可以全局引用,也可以引用到特定应用程序位置。例如,一个应用程序特定的定位可能是根据EGM1996确定的海平面高度,使得地图坐标系中的Z位置等于海平面上方的米数。不管选择何种方式,最重要的部分是必须清楚地记录参考位置的选择,以避免混淆。 + +当与地球等全球参考一起定义坐标系时: + +默认情况下,应将x轴对齐到东方,y轴对齐到北方,z轴在坐标系原点上方朝上。 +如果没有其他参考,z轴的默认位置应该是在WGS84椭球的高度为零的位置。 +如果存在特定应用程序要求,上述要求无法满足的情况应尽可能满足。 + +一个不能满足上述要求的应用示例是启动时没有外部参考设备(如GPS、罗盘或高度计)的机器人。但如果机器人仍具有加速度计,它可以在当前位置初始化地图,z轴朝上。 + +如果机器人在启动时具有罗盘航向,它还可以初始化东向x轴,北向y轴。 + +如果机器人在启动时具有高度计估计,它可以将高度初始化为MSL。 + +上述约定强烈建议在非结构化环境中使用。 + diff --git a/hi-slam/ROS2_recode/ROS2.md b/hi-slam/ROS2_recode/ROS2.md new file mode 100644 index 0000000000000000000000000000000000000000..32f0790710b8c5b09ebb0a222ece55a2cbdded87 --- /dev/null +++ b/hi-slam/ROS2_recode/ROS2.md @@ -0,0 +1,170 @@ +# ROS2 + +使用humble桌面版 + + + +## ROS2组网 + +在需要组网的设备间命令行输入export ROS_DOMAIN_ID=x(阿拉伯数字)即可 + +> 如果是新板子,自己规定一下ROS_DOMAIN_ID即可 + +海鸥派和Ubuntu共同输入 + + + +## ROS2测试节点组网连接命令 + +虚拟机发出talker话题命令,海鸥派输入listener,看有无接收 + +```sh +ros2 run demo_nodes_cpp talker +ros2 run demo_nodes_cpp listener +``` + + + +## cartographer_ROS(自主建图) + +仓库地址:https://github.com/ros2/cartographer_ros + + + +## 命令行挂载终端(需要自取) + +```sh +export http_proxy=127.0.0.1:7890 +export https_proxy=127.0.0.1:7890 +``` + +127.0.0.1是一般代理的ip,端口上自己软件查看 + +虚拟机一般是走宿主机ip,cmd查看 + + + +## 虚拟机走代理 + +![image-20240627193324303](./image-20240627193324303.png) + +![image-20240627193420557](./image-20240627193420557.png) + +## Cartographer安装教程 + +```shell +wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall +``` + +这里可能会出现ERROR无法访问,是因为被墙了,sudo gedit /etc/hosts + +在最后添加 + +185.199.108.133 raw.githubusercontent.com +185.199.109.133 raw.githubusercontent.com +185.199.110.133 raw.githubusercontent.com +185.199.111.133 raw.githubusercontent.com + +重新打开终端继续运行命令 + +```sh +robot@robot:~/Desktop/catkin_ws$ wstool merge -t src https://raw.githubusercontent.com/cartographer-project/cartographer_ros/master/cartographer_ros.rosinstall + Performing actions: + + Add new elements: + cartographer, cartographer_ros + +Config changed, maybe you need run wstool update to update SCM entries. +Overwriting /home/robot/Desktop/catkin_ws/src/.rosinstall + +update complete. + +``` + +ROS2中,构建工作空间不再试catken,而是colcon + +## + +```sh +sudo gedit rosdistro/__init__.py +/index-v4.yaml +sudo mkdir -p /etc/ros/rosdep/sources.list.d/20-default.list +cd /etc/ros/rosdep/sources.list.d +sudo gedit 20-default.list + +yaml file: /home/robot/Desktop/catkin_ws/rosdistro/rosdep/osx-homebrew.yaml osx +gbpdistro file: /home/robot/Desktop/catkin_ws/rosdistro/releases/fuerte.yaml fuerte +``` + + + +ros2 launch Python、XML 或 YAML文件 + + + +遇到报错 + +```sh +rosdep install +--from-paths src +--ignore-src +--rosdistro=${ROS_DISTRO} -y +``` + +执行时 + +ERROR: the following packages/stacks could not have their rosdep keys resolved +to system dependencies: +cartographer_ros: Cannot locate rosdep definition for [catkin] +cartographer_rviz: Cannot locate rosdep definition for [catkin] +cartographer_ros_msgs: Cannot locate rosdep definition for [catkin] + +已解决,换colcon编译即可,catkin是ROS1的编译方式 + +换成rosdepc install -r --from-paths src --ignore-src --rosdistro $ROS_DISTRO -y即可 + + + +colcon build --packages-up-to cartographer_ros编译时 + +报错 + +``` +error: ‘__gnu_cxx::__alloc_traits, +``` + +应该是包不对,我是Rolling版本的ROS2,此教程是humble版本的ROS2 + + + +发现问题,是依赖的问题 + +![image-20240628121322590](./image-20240628121322590.png) + +```sh +find /home/robot/Desktop/carto_ws/src/cartographer_ros -type f -exec sed -i 's/recv_timestamp/time_stamp/g' {} + +``` + +把所有依赖文件中的recv_timestamp改成time_stamp即可 + +继续执行 + +```sh +colcon build --packages-up-to cartographer_ros +``` + +## 所有需要的链接 + +**[ROS2不同版本的差异](https://blog.csdn.net/zyh821351004/article/details/130180172)** + +**[安装ROS2 humble 和 cartographer](https://blog.csdn.net/NOA_GG/article/details/125977241)** + +**[ROS2 编译运行最新cartographer代码](https://blog.csdn.net/lgh1231/article/details/124939760)** + +**[ROS安装教程 解决raw.github无法访问的问题](https://www.bilibili.com/read/cv13788562/)** + +**[ROS 2 Cartographer教程](https://ros2-industrial-workshop.readthedocs.io/en/latest/_source/navigation/ROS2-Cartographer.html)** + +**[动手学ROS2 Cartographer介绍与安装](https://fishros.com/d2lros2foxy/#/chapt10/10.4Cartographer%E4%BB%8B%E7%BB%8D%E4%B8%8E%E5%AE%89%E8%A3%85)** + +**[ROS2+Cartographer建图并保存](https://blog.csdn.net/scarecrow_sun/article/details/127978254)** \ No newline at end of file diff --git a/hi-slam/ROS2_recode/image-20240627193324303.png b/hi-slam/ROS2_recode/image-20240627193324303.png new file mode 100644 index 0000000000000000000000000000000000000000..425c64f0d3e38238216cd6656c7cfd43bdc93b37 Binary files /dev/null and b/hi-slam/ROS2_recode/image-20240627193324303.png differ diff --git a/hi-slam/ROS2_recode/image-20240627193420557.png b/hi-slam/ROS2_recode/image-20240627193420557.png new file mode 100644 index 0000000000000000000000000000000000000000..04559f2152027fc01e1309596e07882d95f8a557 Binary files /dev/null and b/hi-slam/ROS2_recode/image-20240627193420557.png differ diff --git a/hi-slam/ROS2_recode/image-20240628121322590.png b/hi-slam/ROS2_recode/image-20240628121322590.png new file mode 100644 index 0000000000000000000000000000000000000000..42bf8b48403bfd6aaa7188fc01bba8402b84c9b6 Binary files /dev/null and b/hi-slam/ROS2_recode/image-20240628121322590.png differ diff --git "a/hi-slam/Single_LiDAR_Mapping/ROS2+\345\215\225\346\277\200\345\205\211\351\233\267\350\276\276\345\273\272\345\233\276.md" "b/hi-slam/Single_LiDAR_Mapping/ROS2+\345\215\225\346\277\200\345\205\211\351\233\267\350\276\276\345\273\272\345\233\276.md" new file mode 100644 index 0000000000000000000000000000000000000000..6acc2f88c5201b34cae27117c7b59be2464726df --- /dev/null +++ "b/hi-slam/Single_LiDAR_Mapping/ROS2+\345\215\225\346\277\200\345\205\211\351\233\267\350\276\276\345\273\272\345\233\276.md" @@ -0,0 +1,37 @@ +# ROS2+单激光雷达建图 + +所谓单激光雷达建图指不依靠IMU或者里程计信息,只使用雷达的深度点云进行建图,当我们的机器人在摩擦力较小容易打滑的地面或者没有里程计信息的机器人上,只使用激光雷达进行定位和建图往往可以取得较好的效果。 + +![image-20240831202405218](./image-20240831202405218.png) + +只要从里程计+雷达SLAM,切换成纯雷达SLAM只需要修改Cartographer的参数即可。 + +本代码基于Ubuntu22.04+ROS 2.0 humble版本进行测试。 + +在ROS2的工作空间下拷贝单激光雷达建图cartographer配置文件到src/目录下 + +重点查看src/fishbot_cartographer/config/fishbot_laser_2d.lua + +src/fishbot_cartographer/launch/cartographer_pure_laser.launch.py + +两个主要文件参数根据自己需要的修改 + +其中fishbot_laser_2d.lua + +```lua + -- 跟踪和发布的frame都改成雷达的frameID + tracking_frame = "laser_frame", + published_frame = "laser_frame", + odom_frame = "odom", + -- true改为false,不用提供里程计数据 + provide_odom_frame = true, + -- false改为true,仅发布2D位资 + publish_frame_projected_to_2d = false, + use_pose_extrapolator = true, + -- true改为false,不使用里程计数据 +``` + +cartographer_pure_laser.launch.py不作过大修改 + + + diff --git a/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/CMakeLists.txt b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a6431af3ab63336d6b41c5e4f6f5a556dbc43328 --- /dev/null +++ b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.8) +project(fishbot_cartographer) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +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 cpplint (only works in a git repo) + # comment the line when this package is in a git repo and when + # a copyright and license is added to all source files + set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() + +install( + DIRECTORY config launch rviz + DESTINATION share/${PROJECT_NAME} +) + diff --git a/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/config/fishbot_laser_2d.lua b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/config/fishbot_laser_2d.lua new file mode 100644 index 0000000000000000000000000000000000000000..c67c02fd525d487a1c3348103b1df7e0f7afaab1 --- /dev/null +++ b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/config/fishbot_laser_2d.lua @@ -0,0 +1,63 @@ +include "map_builder.lua" +include "trajectory_builder.lua" +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + map_frame = "map", + -- 跟踪和发布的frame都改成雷达的frameID + tracking_frame = "laser_link", + published_frame = "laser_link", + odom_frame = "odom", + -- true改为false,不用提供里程计数据 + provide_odom_frame = true, + -- false改为true,仅发布2D位资 + publish_frame_projected_to_2d = false, + use_pose_extrapolator = true, + -- true改为false,不使用里程计数据 + use_odometry = false, + use_nav_sat = false, + use_landmarks = false, + -- 0改为1,使用一个雷达 + num_laser_scans = 1, + -- 1改为0,不使用多波雷达 + num_multi_echo_laser_scans = 0, + -- 10改为1,1/1=1等于不分割 + num_subdivisions_per_laser_scan = 1, + num_point_clouds = 0, + lookup_transform_timeout_sec = 0.2, + submap_publish_period_sec = 0.3, + pose_publish_period_sec = 5e-3, + trajectory_publish_period_sec = 30e-3, + rangefinder_sampling_ratio = 1., + odometry_sampling_ratio = 1., + fixed_frame_pose_sampling_ratio = 1., + imu_sampling_ratio = 1., + landmarks_sampling_ratio = 1., +} +-- false改为true,启动2D SLAM +MAP_BUILDER.use_trajectory_builder_2d = true +-- 0改成0.10,比机器人半径小的都忽略 +TRAJECTORY_BUILDER_2D.min_range = 0.10 +-- 30改成3.5,限制在雷达最大扫描范围内,越小一般越精确些 +TRAJECTORY_BUILDER_2D.max_range = 5.5 +-- 5改成3,传感器数据超出有效范围最大值 +TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. +-- true改成false,不使用IMU数据,大家可以开启,然后对比下效果 +TRAJECTORY_BUILDER_2D.use_imu_data = false +-- false改成true,使用实时回环检测来进行前端的扫描匹配 +TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true +-- 1.0改成0.1,提高对运动的敏感度 +-- TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) +-- 0.55改成0.65,Fast csm的最低分数,高于此分数才进行优化。 +POSE_GRAPH.constraint_builder.min_score = 0.65 +--0.6改成0.7,全局定位最小分数,低于此分数则认为目前全局定位不准确 +POSE_GRAPH.constraint_builder.global_localization_min_score = 0.7 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10. +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1 +POSE_GRAPH.optimization_problem.huber_scale = 1e2 +POSE_GRAPH.optimize_every_n_nodes = 35 +-- 设置0可关闭全局SLAM +-- POSE_GRAPH.optimize_every_n_nodes = 0 +return options + diff --git a/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/launch/cartographer_pure_laser.launch.py b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/launch/cartographer_pure_laser.launch.py new file mode 100644 index 0000000000000000000000000000000000000000..7f35c01629911c263a69ae82f8cef356b778c956 --- /dev/null +++ b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/launch/cartographer_pure_laser.launch.py @@ -0,0 +1,51 @@ +import os +from launch import LaunchDescription +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare +def generate_launch_description(): + # 定位到功能包的地址 + pkg_share = FindPackageShare(package='fishbot_cartographer').find('fishbot_cartographer') + + #=====================运行节点需要的配置======================================================================= + # 是否使用仿真时间,我们用gazebo,这里设置成true + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + # 地图的分辨率 + resolution = LaunchConfiguration('resolution', default='0.05') + # 地图的发布周期 + publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0') + # 配置文件夹路径 + configuration_directory = LaunchConfiguration('configuration_directory',default= os.path.join(pkg_share, 'config') ) + # 配置文件 + configuration_basename = LaunchConfiguration('configuration_basename', default='fishbot_laser_2d.lua') + + #=====================声明三个节点,cartographer/occupancy_grid_node/rviz_node================================= + cartographer_node = Node( + package='cartographer_ros', + executable='cartographer_node', + name='cartographer_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-configuration_directory', configuration_directory, + '-configuration_basename', configuration_basename]) + cartographer_occupancy_grid_node = Node( + package='cartographer_ros', + executable='cartographer_occupancy_grid_node', + name='cartographer_occupancy_grid_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec]) + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + # arguments=['-d', rviz_config_dir], + parameters=[{'use_sim_time': use_sim_time}], + output='screen') + #===============================================定义启动文件======================================================== + ld = LaunchDescription() + ld.add_action(cartographer_node) + ld.add_action(cartographer_occupancy_grid_node) + ld.add_action(rviz_node) + return ld + diff --git a/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/package.xml b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/package.xml new file mode 100644 index 0000000000000000000000000000000000000000..2cfe870c984a826f500dcaa4b53b6e0baa41379e --- /dev/null +++ b/hi-slam/Single_LiDAR_Mapping/eulercar_cartographer/package.xml @@ -0,0 +1,18 @@ + + + + fishbot_cartographer + 0.0.0 + TODO: Package description + robot + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/hi-slam/Single_LiDAR_Mapping/image-20240831202405218.png b/hi-slam/Single_LiDAR_Mapping/image-20240831202405218.png new file mode 100644 index 0000000000000000000000000000000000000000..737b272f8b6ed7e22d2766d82e6cc3c16a778e86 Binary files /dev/null and b/hi-slam/Single_LiDAR_Mapping/image-20240831202405218.png differ diff --git a/hi-slam/eulercar_mapping/images/d92db2f25582d385aa1f51958a079a8c.png b/hi-slam/eulercar_mapping/images/d92db2f25582d385aa1f51958a079a8c.png new file mode 100644 index 0000000000000000000000000000000000000000..faa834bf9e4674727d6039c23816786b62ca7ec0 Binary files /dev/null and b/hi-slam/eulercar_mapping/images/d92db2f25582d385aa1f51958a079a8c.png differ diff --git a/hi-slam/eulercar_mapping/images/image-20240826110644076.png b/hi-slam/eulercar_mapping/images/image-20240826110644076.png new file mode 100644 index 0000000000000000000000000000000000000000..737b272f8b6ed7e22d2766d82e6cc3c16a778e86 Binary files /dev/null and b/hi-slam/eulercar_mapping/images/image-20240826110644076.png differ diff --git a/hi-slam/eulercar_mapping/images/image-20240826112043593.png b/hi-slam/eulercar_mapping/images/image-20240826112043593.png new file mode 100644 index 0000000000000000000000000000000000000000..f67a537d5b3317f286526540188cf495ed9b88d4 Binary files /dev/null and b/hi-slam/eulercar_mapping/images/image-20240826112043593.png differ diff --git a/hi-slam/eulercar_mapping/images/image-20240826112204784.png b/hi-slam/eulercar_mapping/images/image-20240826112204784.png new file mode 100644 index 0000000000000000000000000000000000000000..945d89c86eb2298c4055176ebfee95f8322734e1 Binary files /dev/null and b/hi-slam/eulercar_mapping/images/image-20240826112204784.png differ diff --git a/hi-slam/eulercar_mapping/images/image-20240826121123332.png b/hi-slam/eulercar_mapping/images/image-20240826121123332.png new file mode 100644 index 0000000000000000000000000000000000000000..f5399b44b494e7ad14dffc1030e771f3c729ed48 Binary files /dev/null and b/hi-slam/eulercar_mapping/images/image-20240826121123332.png differ diff --git "a/hi-slam/eulercar_mapping/\346\265\267\351\270\245\346\264\276\345\273\272\345\233\276\350\277\207\347\250\213.md" "b/hi-slam/eulercar_mapping/\346\265\267\351\270\245\346\264\276\345\273\272\345\233\276\350\277\207\347\250\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..febd2cba12bf3f7170c7f88e76f39e2e6f8975f4 --- /dev/null +++ "b/hi-slam/eulercar_mapping/\346\265\267\351\270\245\346\264\276\345\273\272\345\233\276\350\277\207\347\250\213.md" @@ -0,0 +1,251 @@ +# 海鸥派建图过程 + +重要的东西:底盘节点、键盘控制、激光雷达开启、IMU开启 + +已编写好一键启动脚本,无需复杂命令 + + + +## 配置文件 + +在ros2的工作空间下新建cartographer配置文件 src/eular_cartographer/config/eulercar_laser_2d.lua,新建launch文件:src/eular_cartographer/launch/cartographer_pure_laser.launch.py + + + +```sh +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + map_frame = "map", + -- 跟踪和发布的frame都改成雷达的frameID + tracking_frame = "laser_frame", + published_frame = "laser_frame", + odom_frame = "odom", + -- true 提供里程计数据 + provide_odom_frame = true, + -- false改为true,仅发布2D位资 + publish_frame_projected_to_2d = false, + use_pose_extrapolator = true, + -- true 使用里程计数据 + use_odometry = true, + use_nav_sat = true, + use_landmarks = true, + -- 0改为1,使用一个雷达 + num_laser_scans = 1, +``` + + + +```sh +#加载环境变量 +source /etc/profile.d/ros/setup.bash +source ~/install/setup.sh +``` + +```sh +#IMU启动节点 +ros2 launch fdilink_ahrs ahrs_driver.launch.py +#IMU查看话题 +ros2 topic echo /odom +``` + +```sh +#底盘打开 +ros2 launch robot_bringup robot_bringup.launch.py +#键盘打开 +ros2 run hieuler_teleop teleop_keyboard +#激光雷达打开 +ros2 launch bluesea2 LDS-E120-R.launch +#上位机开启Cartographer +ros2 launch eulercar_cartographer cartographer.launch.py +``` + +![image-20240826110644076](images/image-20240826110644076.png) + + + + + +一键启动脚本如下 + +![image-20240826112043593](images/image-20240826112043593.png) + + + + + +在/root/install目录下有我们在虚拟机交叉编译好的所有包,在虚拟机里修改好相应参数编译好再移植到海鸥派上 + +![image-20240826112204784](images/image-20240826112204784.png) + +## 虚拟机编译过程 + +进入/home/robot/hieuler/build_3403/build/sd3403 + +> 此处是docker容器目录 + +```sh +oebuild bitbake #进入交叉编译环境 +``` + +加载编译SDK(注意"."后面的空格) + +```sh +. /opt/openeuler/oecore-x86_64/environment-setup-aarch64-openeuler-linux +``` + +我们编译的eulercar-master + +```sh +cd eulercar +colcon build +``` + +编译完成后,生成的可执行文件在install目录中,如下图: + +![image-20240826121123332](images/image-20240826121123332.png) + +退出exit + +再将编译好的文件打开,进入install里,把编译好的包拷贝到海鸥派小车中 + +```sh +#加载环境变量 +source /etc/profile.d/ros/setup.bash +source ~/install/setup.sh +``` + +即可正常使用 + + + + + +## 发布Odom的TF + +运行建图算法时,会得到 map 到 odom 之间的TF,base_link 到 雷达或者IMU 之间的坐标关系一般使用URDF进行描述,然后使用 robot_state_publisher 进行发布,也可以使用静态TF直接发布。 + +而 odom 到 base_link 之间的TF就需要我们从里程计中提取并发布,本节我们主要的工作就是订阅 里程计话题 发布 odom 到 base_link 之间的 TF 变换。 + + +> 关于base_link和base_footprint 的区别 +> +> 在机器人领域中,"base_link"和"base_footprint"是ROS(Robot Operating System)中两个常用的坐标系(frames)名称。它们用于表示机器人的基本参考坐标系,但在某些情况下,它们可能会有一些微妙的区别。 +> +> base_link: +> "base_link"通常用于表示机器人的实际底盘或主体的坐标系。这个坐标系通常与机器人的物理结构直接相关,它可能位于机器人底盘的中心或者其他适当的位置。例如,对于一个移动机器人,"base_link"的原点可能位于机器人的几何中心或底盘的旋转中心,这取决于机器人的设计。 +> +> base_footprint: +> "base_footprint"则更多地被用作机器人在地面上的一个虚拟平面的参考点,通常是机器人底盘的投影点。这个坐标系通常位于机器人底盘底部,用于表示机器人与地面的接触点。它可以被认为是机器人底部的一个虚拟标记,用来执行路径规划、避障和定位等任务。 +> +> 在许多情况下,“base_link"和"base_footprint"的坐标原点可能是相同的,但它们的用途和表示方式略有不同。例如,在路径规划中,可能更常用"base_footprint”,因为它更接近机器人在地面上的实际位置,有助于避免碰撞。而在其他情况下,如控制机器人的运动,使用"base_link"可能更合适,因为它更直接地与机器人的物理结构相联系。 +> +> + +在 src/fishbot_bringup/src/ 下新建 fishbot_bringup.cpp + +```cpp +#include +#include +#include +#include + +class TopicSubscribe01 : public rclcpp::Node +{ +public: + TopicSubscribe01(std::string name) : Node(name) + { + // 创建一个订阅者,订阅"odom"话题的nav_msgs::msg::Odometry类型消息 + odom_subscribe_ = this->create_subscription( + "odom", rclcpp::SensorDataQoS(), + std::bind(&TopicSubscribe01::odom_callback, this, std::placeholders::_1)); + + // 创建一个tf2_ros::TransformBroadcaster用于广播坐标变换 + tf_broadcaster_ = std::make_unique(this); + } + +private: + rclcpp::Subscription::SharedPtr odom_subscribe_; + std::unique_ptr tf_broadcaster_; + nav_msgs::msg::Odometry odom_msg_; + + // 回调函数,处理接收到的odom消息 + void odom_callback(const nav_msgs::msg::Odometry::SharedPtr msg) + { + (void)msg; + RCLCPP_INFO(this->get_logger(), "接收到里程计信息->底盘坐标系 tf :(%f,%f)", + msg->pose.pose.position.x, msg->pose.pose.position.y); + + // 更新odom_msg_的姿态信息 + odom_msg_.pose.pose.position.x = msg->pose.pose.position.x; + odom_msg_.pose.pose.position.y = msg->pose.pose.position.y; + odom_msg_.pose.pose.position.z = msg->pose.pose.position.z; + + odom_msg_.pose.pose.orientation.x = msg->pose.pose.orientation.x; + odom_msg_.pose.pose.orientation.y = msg->pose.pose.orientation.y; + odom_msg_.pose.pose.orientation.z = msg->pose.pose.orientation.z; + odom_msg_.pose.pose.orientation.w = msg->pose.pose.orientation.w; + }; + +public: + // 发布坐标变换信息 + void publish_tf() + { + geometry_msgs::msg::TransformStamped transform; + double seconds = this->now().seconds(); + transform.header.stamp = rclcpp::Time(static_cast(seconds * 1e9)); + transform.header.frame_id = "odom"; + transform.child_frame_id = "base_footprint"; + + transform.transform.translation.x = odom_msg_.pose.pose.position.x; + transform.transform.translation.y = odom_msg_.pose.pose.position.y; + transform.transform.translation.z = odom_msg_.pose.pose.position.z; + transform.transform.rotation.x = odom_msg_.pose.pose.orientation.x; + transform.transform.rotation.y = odom_msg_.pose.pose.orientation.y; + transform.transform.rotation.z = odom_msg_.pose.pose.orientation.z; + transform.transform.rotation.w = odom_msg_.pose.pose.orientation.w; + + // 广播坐标变换信息 + tf_broadcaster_->sendTransform(transform); + } +}; + +int main(int argc, char **argv) +{ + // 初始化ROS节点 + rclcpp::init(argc, argv); + + // 创建一个TopicSubscribe01节点 + auto node = std::make_shared("fishbot_bringup"); + + // 设置循环频率 + rclcpp::WallRate loop_rate(20.0); + while (rclcpp::ok()) + { + // 处理回调函数 + rclcpp::spin_some(node); + + // 发布坐标变换信息 + node->publish_tf(); + + // 控制循环频率 + loop_rate.sleep(); + } + + // 关闭ROS节点 + rclcpp::shutdown(); + return 0; +} + + +``` + +编译好之后查看TF + +```sh +ros2 run rqt_tf_tree rqt_tf_tree +``` + +![在这里插入图片描述](images/d92db2f25582d385aa1f51958a079a8c.png) + +有了 odom 到 base_link/base_footprint 之间的变换,接下来我们来搞定 base_link 到机器人各个组件之间的变换。 \ No newline at end of file diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/config/euler_laser_2d.lua" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/config/euler_laser_2d.lua" new file mode 100644 index 0000000000000000000000000000000000000000..b03dc755727f0eccd5abea42f78fdb2db5306649 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/config/euler_laser_2d.lua" @@ -0,0 +1,64 @@ +include "map_builder.lua" +include "trajectory_builder.lua" +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + map_frame = "map", + -- 跟踪和发布的frame都改成雷达的frameID + tracking_frame = "laser_link", + published_frame = "laser_link", + odom_frame = "odom", + -- true改为false,不用提供里程计数据 + provide_odom_frame = false, + -- false改为true,仅发布2D位资 lidar-only=false + publish_frame_projected_to_2d = false, + -- 使用融合里程计和IMU,推测出一个位姿 + use_pose_extrapolator = true, + -- true改为false,不使用里程计数据 lidar-only=false + use_odometry = false, + use_nav_sat = false, + use_landmarks = false, + -- 0改为1,使用一个雷达 + num_laser_scans = 1, + -- 1改为0,不使用多波雷达 + num_multi_echo_laser_scans = 0, + -- 10改为1,1/1=1等于不分割 + num_subdivisions_per_laser_scan = 1, + num_point_clouds = 0, + lookup_transform_timeout_sec = 0.2, + submap_publish_period_sec = 0.3, + pose_publish_period_sec = 5e-3, + trajectory_publish_period_sec = 30e-3, + rangefinder_sampling_ratio = 1., + odometry_sampling_ratio = 1., + fixed_frame_pose_sampling_ratio = 1., + imu_sampling_ratio = 1., + landmarks_sampling_ratio = 1., +} +-- false改为true,启动2D SLAM +MAP_BUILDER.use_trajectory_builder_2d = true +-- 0改成0.10,比机器人半径小的都忽略,根据雷达参数设定 +TRAJECTORY_BUILDER_2D.min_range = 0.10 +-- 30改成50,限制在雷达最大扫描范围内,根据雷达参数设定 +TRAJECTORY_BUILDER_2D.max_range = 50 +-- 5改成3,传感器数据超出有效范围最大值 +TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. +-- true改成false,不使用IMU数据,大家可以开启,然后对比下效果 +TRAJECTORY_BUILDER_2D.use_imu_data = true +-- false改成true,使用实时回环检测来进行前端的扫描匹配 +TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true +-- 1.0改成0.1,提高对运动的敏感度 +TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) +-- Fast csm的最低分数,高于此分数才进行优化。 +POSE_GRAPH.constraint_builder.min_score = 0.55 +--全局定位最小分数,低于此分数则认为目前全局定位不准确 +POSE_GRAPH.constraint_builder.global_localization_min_score = 0.6 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 1e-1 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1 +POSE_GRAPH.optimization_problem.huber_scale = 1e2 +POSE_GRAPH.optimize_every_n_nodes = 35 +-- 设置0可关闭全局SLAM +-- POSE_GRAPH.optimize_every_n_nodes = 0 +return options + diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/include/node_options.h" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/include/node_options.h" new file mode 100644 index 0000000000000000000000000000000000000000..3a3e9d0aba9bee8dad7948eb150004eb8451c977 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/include/node_options.h" @@ -0,0 +1,51 @@ +/* + * Copyright 2016 The Cartographer Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CARTOGRAPHER_ROS_CARTOGRAPHER_ROS_NODE_OPTIONS_H +#define CARTOGRAPHER_ROS_CARTOGRAPHER_ROS_NODE_OPTIONS_H + +#include +#include + +#include "cartographer/common/lua_parameter_dictionary.h" +#include "cartographer/common/port.h" +#include "cartographer/mapping/proto/map_builder_options.pb.h" +#include "cartographer_ros/trajectory_options.h" + +namespace cartographer_ros { + +// 重新修改cartographer的基本变量,使得小车更加准确建图 +struct NodeOptions { + ::cartographer::mapping::proto::MapBuilderOptions map_builder_options; + std::string map_frame; + double lookup_transform_timeout_sec; + double submap_publish_period_sec; + double pose_publish_period_sec; + double trajectory_publish_period_sec; + bool publish_to_tf = true; + bool publish_tracked_pose = true; + bool use_pose_extrapolator = true; +}; + +NodeOptions CreateNodeOptions( + ::cartographer::common::LuaParameterDictionary* lua_parameter_dictionary); + +std::tuple LoadOptions( + const std::string& configuration_directory, + const std::string& configuration_basename); +} // namespace cartographer_ros + +#endif // CARTOGRAPHER_ROS_CARTOGRAPHER_ROS_NODE_OPTIONS_H diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/launch/cartographer_laser.launch.py" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/launch/cartographer_laser.launch.py" new file mode 100644 index 0000000000000000000000000000000000000000..a27e277d3bd181edc5ac5d9083ac1814d0e20f05 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/launch/cartographer_laser.launch.py" @@ -0,0 +1,63 @@ +import os +from launch import LaunchDescription +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare +def generate_launch_description(): + # 定位到功能包的地址 + pkg_share = FindPackageShare(package='euler_cartographer').find('euler_cartographer') + + #=====================运行节点需要的配置======================================================================= + # 是否使用仿真时间,我们不用gazebo,这里设置成false + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + # 地图的分辨率 + resolution = LaunchConfiguration('resolution', default='0.05') + # 地图的发布周期 + publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0') + # 配置文件夹路径 + configuration_directory = LaunchConfiguration('configuration_directory',default= os.path.join(pkg_share, 'config') ) + # 配置文件 + configuration_basename = LaunchConfiguration('configuration_basename', default='euler_laser_2d.lua') + + #=====================声明三个节点,cartographer/occupancy_grid_node/rviz_node================================= + cartographer_node = Node( + package='cartographer_ros', + executable='cartographer_node', + name='cartographer_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-configuration_directory', configuration_directory, + '-configuration_basename', configuration_basename]) + cartographer_occupancy_grid_node = Node( + package='cartographer_ros', + executable='cartographer_occupancy_grid_node', + name='cartographer_occupancy_grid_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec]) + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + # arguments=['-d', rviz_config_dir], + parameters=[{'use_sim_time': use_sim_time}], + output='screen') + tf2_laser_pub = Node( + package='tf2_ros', + executable='static_transform_publisher', + arguments = ['0', '0', '1', '0', '0', '0', 'base_footprint', 'laser_link'] + ) + tf2_imu_pub = Node( + package='tf2_ros', + executable='static_transform_publisher', + arguments = ['0', '0', '0', '0', '0', '0', 'laser_link', 'gyro_link'] #此处使用的是作者外接的imu,请根据自身修改imu的fram_id和tf树 + ) + #===============================================定义启动文件======================================================== + ld = LaunchDescription() + ld.add_action(cartographer_node) + ld.add_action(cartographer_occupancy_grid_node) + ld.add_action(rviz_node) + ld.add_action(tf2_laser_pub) + ld.add_action(tf2_imu_pub) + return ld + diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/readme.md" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/readme.md" new file mode 100644 index 0000000000000000000000000000000000000000..1302acee8e61a26a48512e3fdc25f7ceac8fd345 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Mapping/readme.md" @@ -0,0 +1,53 @@ +1. 先下载cartographer源码,并将**cartographer_ros/cartographer_ros/include/cartographer_ros/node_options.h**文件替换成 + +本文件**cartographer_ros_include_fixed**下的**node_options.h** + + + +2. 在工作间下,创建一个名为euler_cartographer的功能包 + +```shell +cd src +ros2 pkg create euler_cartographer +``` + +2.1 接着创建配置文件夹、launch文件夹 + +``` +cd euler_cartographer +mkdir config +mkdir launch +``` + +2.2 将本目录下的config、launch文件放入其中 + +2.3 添加安装指令 + +```cmake +install( + DIRECTORY config launch rviz + DESTINATION share/${PROJECT_NAME} +) +``` + +2.4 编译 + +```shell +colcon build --packages-select euler_cartographer +``` + +2.5 启动 + +```shell +source install/setup.bash +ros2 launch euler_cartographer cartographer.launch.py +``` + +2.6 建完图保存 + +```shell +# 先将地图保存到src/euler_cartographer/map目录下 +cd src/euler_cartographer/ && mkdir map && cd map +ros2 run nav2_map_server map_saver_cli -t map -f map +``` + diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/launch/euler_nav2_launch.py" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/launch/euler_nav2_launch.py" new file mode 100644 index 0000000000000000000000000000000000000000..acf4d5c193ea8e7c4feb99c035467630d6344d6f --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/launch/euler_nav2_launch.py" @@ -0,0 +1,39 @@ +import os +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + #=============================1.定位到包的地址============================================================= + euler_navigation2_dir = get_package_share_directory('euler_navigation2') + nav2_bringup_dir = get_package_share_directory('nav2_bringup') + + + #=============================2.声明参数,获取配置文件路径=================================================== + # use_sim_time 这里要设置成false,未使用仿真 + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + map_yaml_path = LaunchConfiguration('map',default=os.path.join(euler_navigation2_dir,'maps','map.yaml')) + nav2_param_path = LaunchConfiguration('params_file',default=os.path.join(euler_navigation2_dir,'param','nav2_params.yaml')) + rviz_config_dir = os.path.join(nav2_bringup_dir,'rviz','nav2_default_view.rviz') + + #=============================3.声明启动launch文件,传入:地图路径、是否使用仿真时间以及nav2参数文件============== + nav2_bringup_launch = IncludeLaunchDescription( + PythonLaunchDescriptionSource([nav2_bringup_dir,'/launch','/bringup_launch.py']), + launch_arguments={ + 'map': map_yaml_path, + 'use_sim_time': use_sim_time, + 'params_file': nav2_param_path}.items(), + ) + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config_dir], + parameters=[{'use_sim_time': use_sim_time}], + output='screen') + + return LaunchDescription([nav2_bringup_launch,rviz_node]) diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/param/nav2_params.yaml" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/param/nav2_params.yaml" new file mode 100644 index 0000000000000000000000000000000000000000..abaf9dc9fa0c187f5a55cc2518c085246821ce5c --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/param/nav2_params.yaml" @@ -0,0 +1,356 @@ +#AMCL使用自适应蒙特卡罗定位器(Adaptive Monte-Carlo Localizer)实现了基于静态地图对机器人进行定位的服务器。 +amcl: + ros__parameters: + #未使用仿真,则不使用仿真时间 + use_sim_time: False + #alpha1 来自旋转的里程计旋转估计的预期过程噪声,由于自带的odom数据旋转角噪声过大,可适当调整噪声 + alpha1: 0.5 + alpha2: 0.4 + alpha3: 0.2 + alpha4: 0.2 + alpha5: 0.2 + base_frame_id: "base_footprint" + beam_skip_distance: 0.5 + beam_skip_error_threshold: 0.9 + beam_skip_threshold: 0.3 + do_beamskip: false + global_frame_id: "map" + lambda_short: 0.1 + laser_likelihood_max_dist: 2.0 + laser_max_range: 100.0 + laser_min_range: -1.0 + laser_model_type: "likelihood_field" + max_beams: 60 + max_particles: 2000 + min_particles: 500 + odom_frame_id: "odom" + pf_err: 0.05 + pf_z: 0.99 + recovery_alpha_fast: 0.0 + recovery_alpha_slow: 0.0 + resample_interval: 1 + robot_model_type: "nav2_amcl::DifferentialMotionModel" + save_pose_rate: 0.5 + sigma_hit: 0.2 + tf_broadcast: true + transform_tolerance: 1.0 + update_min_a: 0.2 + update_min_d: 0.25 + z_hit: 0.5 + z_max: 0.05 + z_rand: 0.5 + z_short: 0.05 + scan_topic: scan +#行为树导航器,它是一种基于行为树的导航实现,旨在允许导航任务的灵活性,并提供一种简便的方式来指定复杂的机器人行为,包括恢复操作。 +bt_navigator: + ros__parameters: + use_sim_time: False + global_frame: map + #urdf中建立的tf树是从base_footprint到base_link,所以这里设置为base_link + robot_base_frame: base_link + odom_topic: /odom + bt_loop_duration: 10 + default_server_timeout: 20 + wait_for_service_timeout: 1000 + # 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults: + # nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml + # nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml + # They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2. + plugin_lib_names: + - nav2_compute_path_to_pose_action_bt_node + - nav2_compute_path_through_poses_action_bt_node + - nav2_smooth_path_action_bt_node + - nav2_follow_path_action_bt_node + - nav2_spin_action_bt_node + - nav2_wait_action_bt_node + - nav2_assisted_teleop_action_bt_node + - nav2_back_up_action_bt_node + - nav2_drive_on_heading_bt_node + - nav2_clear_costmap_service_bt_node + - nav2_is_stuck_condition_bt_node + - nav2_goal_reached_condition_bt_node + - nav2_goal_updated_condition_bt_node + - nav2_globally_updated_goal_condition_bt_node + - nav2_is_path_valid_condition_bt_node + - nav2_initial_pose_received_condition_bt_node + - nav2_reinitialize_global_localization_service_bt_node + - nav2_rate_controller_bt_node + - nav2_distance_controller_bt_node + - nav2_speed_controller_bt_node + - nav2_truncate_path_action_bt_node + - nav2_truncate_path_local_action_bt_node + - nav2_goal_updater_node_bt_node + - nav2_recovery_node_bt_node + - nav2_pipeline_sequence_bt_node + - nav2_round_robin_node_bt_node + - nav2_transform_available_condition_bt_node + - nav2_time_expired_condition_bt_node + - nav2_path_expiring_timer_condition + - nav2_distance_traveled_condition_bt_node + - nav2_single_trigger_bt_node + - nav2_goal_updated_controller_bt_node + - nav2_is_battery_low_condition_bt_node + - nav2_navigate_through_poses_action_bt_node + - nav2_navigate_to_pose_action_bt_node + - nav2_remove_passed_goals_action_bt_node + - nav2_planner_selector_bt_node + - nav2_controller_selector_bt_node + - nav2_goal_checker_selector_bt_node + - nav2_controller_cancel_bt_node + - nav2_path_longer_on_approach_bt_node + - nav2_wait_cancel_bt_node + - nav2_spin_cancel_bt_node + - nav2_back_up_cancel_bt_node + - nav2_assisted_teleop_cancel_bt_node + - nav2_drive_on_heading_cancel_bt_node + - nav2_is_battery_charging_condition_bt_node + +bt_navigator_navigate_through_poses_rclcpp_node: + ros__parameters: + use_sim_time: False + +bt_navigator_navigate_to_pose_rclcpp_node: + ros__parameters: + use_sim_time: False + +controller_server: + ros__parameters: + use_sim_time: False + controller_frequency: 20.0 + min_x_velocity_threshold: 0.001 + min_y_velocity_threshold: 0.5 + min_theta_velocity_threshold: 0.001 + failure_tolerance: 0.3 + progress_checker_plugin: "progress_checker" + goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker" + controller_plugins: ["FollowPath"] + + # Progress checker parameters + progress_checker: + plugin: "nav2_controller::SimpleProgressChecker" + required_movement_radius: 0.5 + movement_time_allowance: 10.0 + # Goal checker parameters + #precise_goal_checker: + # plugin: "nav2_controller::SimpleGoalChecker" + # xy_goal_tolerance: 0.25 + # yaw_goal_tolerance: 0.25 + # stateful: True + general_goal_checker: + stateful: True + plugin: "nav2_controller::SimpleGoalChecker" + xy_goal_tolerance: 0.25 + yaw_goal_tolerance: 0.25 + # DWB parameters + FollowPath: + plugin: "dwb_core::DWBLocalPlanner" + debug_trajectory_details: True + min_vel_x: 0.0 + min_vel_y: 0.0 + max_vel_x: 0.26 + max_vel_y: 0.0 + max_vel_theta: 1.0 + min_speed_xy: 0.0 + max_speed_xy: 0.26 + min_speed_theta: 0.0 + # Add high threshold velocity for turtlebot 3 issue. + # https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75 + acc_lim_x: 2.5 + acc_lim_y: 0.0 + acc_lim_theta: 3.2 + decel_lim_x: -2.5 + decel_lim_y: 0.0 + decel_lim_theta: -3.2 + vx_samples: 20 + vy_samples: 5 + vtheta_samples: 20 + sim_time: 1.7 + linear_granularity: 0.05 + angular_granularity: 0.025 + transform_tolerance: 0.2 + xy_goal_tolerance: 0.25 + trans_stopped_velocity: 0.25 + short_circuit_trajectory_evaluation: True + stateful: True + critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"] + BaseObstacle.scale: 0.02 + PathAlign.scale: 32.0 + PathAlign.forward_point_distance: 0.1 + GoalAlign.scale: 24.0 + GoalAlign.forward_point_distance: 0.1 + PathDist.scale: 32.0 + GoalDist.scale: 24.0 + RotateToGoal.scale: 32.0 + RotateToGoal.slowing_factor: 5.0 + RotateToGoal.lookahead_time: -1.0 + +local_costmap: + local_costmap: + ros__parameters: + update_frequency: 5.0 + publish_frequency: 2.0 + global_frame: odom + robot_base_frame: base_link + use_sim_time: True + rolling_window: true + width: 3 + height: 3 + resolution: 0.05 + robot_radius: 0.22 + plugins: ["voxel_layer", "inflation_layer"] + inflation_layer: + plugin: "nav2_costmap_2d::InflationLayer" + cost_scaling_factor: 3.0 + # 由于小车车身较小,可根据场地大小调整地图膨胀系数,避免碰撞到障碍物 + inflation_radius: 0.08 + voxel_layer: + plugin: "nav2_costmap_2d::VoxelLayer" + enabled: True + publish_voxel_map: True + origin_z: 0.0 + z_resolution: 0.05 + z_voxels: 16 + max_obstacle_height: 2.0 + mark_threshold: 0 + observation_sources: scan + scan: + topic: /scan + max_obstacle_height: 2.0 + clearing: True + marking: True + data_type: "LaserScan" + raytrace_max_range: 3.0 + raytrace_min_range: 0.0 + obstacle_max_range: 2.5 + obstacle_min_range: 0.0 + static_layer: + plugin: "nav2_costmap_2d::StaticLayer" + map_subscribe_transient_local: True + always_send_full_costmap: True + +global_costmap: + global_costmap: + ros__parameters: + update_frequency: 1.0 + publish_frequency: 1.0 + global_frame: map + robot_base_frame: base_link + use_sim_time: True + robot_radius: 0.22 + resolution: 0.05 + track_unknown_space: true + plugins: ["static_layer", "obstacle_layer", "inflation_layer"] + obstacle_layer: + plugin: "nav2_costmap_2d::ObstacleLayer" + enabled: True + observation_sources: scan + scan: + topic: /scan + max_obstacle_height: 2.0 + clearing: True + marking: True + data_type: "LaserScan" + raytrace_max_range: 3.0 + raytrace_min_range: 0.0 + obstacle_max_range: 2.5 + obstacle_min_range: 0.0 + static_layer: + plugin: "nav2_costmap_2d::StaticLayer" + map_subscribe_transient_local: True + inflation_layer: + plugin: "nav2_costmap_2d::InflationLayer" + cost_scaling_factor: 3.0 + # 由于小车车身较小,可根据场地大小调整地图膨胀系数,避免碰撞到障碍物 + inflation_radius: 0.08 + always_send_full_costmap: True + +map_server: + ros__parameters: + use_sim_time: False + # Overridden in launch by the "map" launch configuration or provided default value. + # To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below. + yaml_filename: "" + +map_saver: + ros__parameters: + use_sim_time: False + save_map_timeout: 5.0 + free_thresh_default: 0.25 + occupied_thresh_default: 0.65 + map_subscribe_transient_local: True + +planner_server: + ros__parameters: + expected_planner_frequency: 20.0 + use_sim_time: False + planner_plugins: ["GridBased"] + GridBased: + plugin: "nav2_navfn_planner/NavfnPlanner" + tolerance: 0.5 + use_astar: false + allow_unknown: true + +smoother_server: + ros__parameters: + use_sim_time: False + smoother_plugins: ["simple_smoother"] + simple_smoother: + plugin: "nav2_smoother::SimpleSmoother" + tolerance: 1.0e-10 + max_its: 1000 + do_refinement: True + +behavior_server: + ros__parameters: + costmap_topic: local_costmap/costmap_raw + footprint_topic: local_costmap/published_footprint + cycle_frequency: 10.0 + behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"] + spin: + plugin: "nav2_behaviors/Spin" + backup: + plugin: "nav2_behaviors/BackUp" + drive_on_heading: + plugin: "nav2_behaviors/DriveOnHeading" + wait: + plugin: "nav2_behaviors/Wait" + assisted_teleop: + plugin: "nav2_behaviors/AssistedTeleop" + global_frame: odom + robot_base_frame: base_link + transform_tolerance: 0.1 + use_sim_time: true + simulate_ahead_time: 2.0 + max_rotational_vel: 1.0 + min_rotational_vel: 0.4 + rotational_acc_lim: 3.2 + +robot_state_publisher: + ros__parameters: + use_sim_time: False + +waypoint_follower: + ros__parameters: + use_sim_time: False + loop_rate: 20 + stop_on_failure: false + waypoint_task_executor_plugin: "wait_at_waypoint" + wait_at_waypoint: + plugin: "nav2_waypoint_follower::WaitAtWaypoint" + enabled: True + waypoint_pause_duration: 200 + +velocity_smoother: + ros__parameters: + use_sim_time: False + smoothing_frequency: 20.0 + scale_velocities: False + feedback: "OPEN_LOOP" + max_velocity: [0.26, 0.0, 1.0] + min_velocity: [-0.26, 0.0, -1.0] + max_accel: [2.5, 0.0, 3.2] + max_decel: [-2.5, 0.0, -3.2] + odom_topic: "odom" + odom_duration: 0.1 + deadband_velocity: [0.0, 0.0, 0.0] + velocity_timeout: 1.0 diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/readme.md" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/readme.md" new file mode 100644 index 0000000000000000000000000000000000000000..03eae3c4ea470d46170fe1ef799c64c0fd846c21 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/Navigation/readme.md" @@ -0,0 +1,39 @@ +1. 创建功能包euler_navigation2 + +```shell +ros2 pkg create fishbot_navigation2 --dependencies nav2_bringup +``` + +2. 创建maps + +```shell +cd src/fishbot_navigation2 +mkdir launch maps param +``` + +3. 将保存好的地图文件放入maps中,文件有map.yaml以及map.pgm + + + +4. 编译 + + + +5. 先启动tf树 + +```shell + ros2 launch euler_bot_description display.launch.py +``` + + + +6. 启动navigation2 + +```shell +ros2 launch nav2_bringup bringup_launch.py +``` + + + + + diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/launch/display.launch.py" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/launch/display.launch.py" new file mode 100644 index 0000000000000000000000000000000000000000..af13dad07377e560c57ccf98f5e19e2a928ad6e0 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/launch/display.launch.py" @@ -0,0 +1,47 @@ +import launch +from launch.substitutions import Command, LaunchConfiguration +import launch_ros +import os + +def generate_launch_description(): + pkg_share = launch_ros.substitutions.FindPackageShare(package='euler_bot_description').find('euler_bot_description') + default_model_path = os.path.join(pkg_share, 'src/description/euler_bot_description.urdf') + #default_rviz_config_path = os.path.join(pkg_share, 'rviz/urdf_config.rviz') + + robot_state_publisher_node = launch_ros.actions.Node( + package='robot_state_publisher', + executable='robot_state_publisher', + parameters=[{'robot_description': Command(['xacro ', LaunchConfiguration('model')])}] + ) + '''joint_state_publisher_node = launch_ros.actions.Node( + package='joint_state_publisher', + executable='joint_state_publisher', + name='joint_state_publisher', + condition=launch.conditions.UnlessCondition(LaunchConfiguration('gui')) + ) + joint_state_publisher_gui_node = launch_ros.actions.Node( + package='joint_state_publisher_gui', + executable='joint_state_publisher_gui', + name='joint_state_publisher_gui', + condition=launch.conditions.IfCondition(LaunchConfiguration('gui')) + ) + rviz_node = launch_ros.actions.Node( + package='rviz2', + executable='rviz2', + name='rviz2', + output='screen', + arguments=['-d', LaunchConfiguration('rvizconfig')], + )''' + + return launch.LaunchDescription([ + #launch.actions.DeclareLaunchArgument(name='gui', default_value='True', + #description='Flag to enable joint_state_publisher_gui'), + launch.actions.DeclareLaunchArgument(name='model', default_value=default_model_path, + description='Absolute path to robot urdf file'), + #launch.actions.DeclareLaunchArgument(name='rvizconfig', default_value=default_rviz_config_path, + #description='Absolute path to rviz config file'), + #joint_state_publisher_node, + #joint_state_publisher_gui_node, + robot_state_publisher_node, + #rviz_node + ]) diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/readme.md" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/readme.md" new file mode 100644 index 0000000000000000000000000000000000000000..c9c9ed79a1adbac13a8df3cf93bde1a1a754fb11 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/readme.md" @@ -0,0 +1,33 @@ +1. 创建功能包 + +```shell +ros2 pkg create --build-type ament_cmake euler_bot_description +``` + +在src/description目录下创建一个名为euler_bot_description,根据自己小车状况建立自己的模型。 + + + +2. 编写完urdf后,构建依赖项 + +并将以下内容添加到您的``package.xml``文件中(最好是在````标签之后) + +```xml +joint_state_publisher +joint_state_publisher_gui +robot_state_publisher +rviz +xacro +``` + + + +3. 接下来编写launch文件 + +根据是否需要可视化,编写launch文件。作者在使用过程中把可视化给注释了,不需要。 + +创建launch文件夹,将编写好的launch文件放入其中。 + + + +4. 编译 \ No newline at end of file diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/src/description/euler_bot_description.urdf" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/src/description/euler_bot_description.urdf" new file mode 100644 index 0000000000000000000000000000000000000000..090a92b6d59dcf00d95f56244c6af6450c39d464 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/euler_bot_description/src/description/euler_bot_description.urdf" @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/lidar.jpg" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/lidar.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..7d30ad0bea913cd20a1b76a2f67f43a10ee01af9 Binary files /dev/null and "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/lidar.jpg" differ diff --git "a/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/\351\227\256\351\242\230\346\242\263\347\220\206.md" "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/\351\227\256\351\242\230\346\242\263\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..2efb3d51c2d8ebfc7f9a57dbb87e0a799993d1d2 --- /dev/null +++ "b/hi-slam/eulercar_submit/\346\254\247\346\213\211\345\260\217\350\275\246\346\217\220\344\272\244\346\226\207\344\273\266/\351\227\256\351\242\230\346\242\263\347\220\206.md" @@ -0,0 +1,298 @@ +# Cartographer:使用bluesea雷达建图 + +## google-cartographer建图原理 + +cartographer利用闭环检测消除构图中的累积误差。 + +闭环检测的基本单元是submap + +submap有一定数量的laser scan构成,或者加入imu和odometry数据 + +第一个submap做基准,后来的submap加入闭环检测 + +闭环检测就是新的submap中的laser scan与先前的submap中的laser scan位姿匹配的话就会match形成闭环。 + +其原理可划分为两部分: + +Local SLAM: + +- 利用里程计(Odometry)和IMU数据进行轨迹推算,给出小车位姿估计值 +- 将位姿估计值作为初值,对雷达数据进行匹配,并更新位姿估计器的值 +- 雷达一帧帧数据经过运动滤波后,进行叠加,形成子图(submap) + +Global SLAM: + +- 回环检测 +- 后端优化,全部子图形成一张完整可用的地图 + +## 实践 + +首先cartographer_ros源码下载 + +然后对配置文件进行配置—lua文件配置 + +```lua +include "map_builder.lua" +include "trajectory_builder.lua" +options = { + map_builder = MAP_BUILDER, + trajectory_builder = TRAJECTORY_BUILDER, + map_frame = "map", + -- 跟踪和发布的frame都改成雷达的frameID + tracking_frame = "laser_link", + published_frame = "laser_link", + odom_frame = "odom", + -- true改为false,不用提供里程计数据 + provide_odom_frame = false, + -- false改为true,仅发布2D位资 + publish_frame_projected_to_2d = false, + use_pose_extrapolator = true, + -- true改为false,不使用里程计数据 + use_odometry = false, + use_nav_sat = false, + use_landmarks = false, + -- 0改为1,使用一个雷达 + num_laser_scans = 1, + -- 1改为0,不使用多波雷达 + num_multi_echo_laser_scans = 0, + -- 10改为1,1/1=1等于不分割 + num_subdivisions_per_laser_scan = 1, + num_point_clouds = 0, + lookup_transform_timeout_sec = 0.2, + submap_publish_period_sec = 0.3, + pose_publish_period_sec = 5e-3, + trajectory_publish_period_sec = 30e-3, + rangefinder_sampling_ratio = 1., + odometry_sampling_ratio = 1., + fixed_frame_pose_sampling_ratio = 1., + imu_sampling_ratio = 1., + landmarks_sampling_ratio = 1., +} +-- false改为true,启动2D SLAM +MAP_BUILDER.use_trajectory_builder_2d = true +-- 0改成0.10,比机器人半径小的都忽略 +TRAJECTORY_BUILDER_2D.min_range = 0.11 +-- 30改成3.5,限制在雷达最大扫描范围内,越小一般越精确些 +TRAJECTORY_BUILDER_2D.max_range = 50 +-- 5改成3,传感器数据超出有效范围最大值 +TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. +-- true改成false,不使用IMU数据,大家可以开启,然后对比下效果 +TRAJECTORY_BUILDER_2D.use_imu_data = false +-- false改成true,使用实时回环检测来进行前端的扫描匹配 +TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true +-- 1.0改成0.1,提高对运动的敏感度 +-- TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) +-- 0.55改成0.65,Fast csm的最低分数,高于此分数才进行优化。 +POSE_GRAPH.constraint_builder.min_score = 0.55 +--0.6改成0.7,全局定位最小分数,低于此分数则认为目前全局定位不准确 +POSE_GRAPH.constraint_builder.global_localization_min_score = 0.6 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.linear_search_window = 0.1 +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.translation_delta_cost_weight = 10. +TRAJECTORY_BUILDER_2D.real_time_correlative_scan_matcher.rotation_delta_cost_weight = 1e-1 +POSE_GRAPH.optimization_problem.huber_scale = 1e2 +POSE_GRAPH.optimize_every_n_nodes = 35 +-- 设置0可关闭全局SLAM +-- POSE_GRAPH.optimize_every_n_nodes = 0 +return options + +``` + +launch文件 + +```python +import os +from launch import LaunchDescription +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node +from launch_ros.substitutions import FindPackageShare +def generate_launch_description(): + # 定位到功能包的地址 + pkg_share = FindPackageShare(package='fishbot_cartographer').find('fishbot_cartographer') + + #=====================运行节点需要的配置======================================================================= + # 是否使用仿真时间,我们用gazebo,这里设置成true + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + # 地图的分辨率 + resolution = LaunchConfiguration('resolution', default='0.05') + # 地图的发布周期 + publish_period_sec = LaunchConfiguration('publish_period_sec', default='1.0') + # 配置文件夹路径 + configuration_directory = LaunchConfiguration('configuration_directory',default= os.path.join(pkg_share, 'config') ) + # 配置文件 + configuration_basename = LaunchConfiguration('configuration_basename', default='fishbot_laser_2d.lua') + + #=====================声明三个节点,cartographer/occupancy_grid_node/rviz_node================================= + cartographer_node = Node( + package='cartographer_ros', + executable='cartographer_node', + name='cartographer_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-configuration_directory', configuration_directory, + '-configuration_basename', configuration_basename]) + cartographer_occupancy_grid_node = Node( + package='cartographer_ros', + executable='cartographer_occupancy_grid_node', + name='cartographer_occupancy_grid_node', + output='screen', + parameters=[{'use_sim_time': use_sim_time}], + arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec]) + rviz_node = Node( + package='rviz2', + executable='rviz2', + name='rviz2', + # arguments=['-d', rviz_config_dir], + parameters=[{'use_sim_time': use_sim_time}], + output='screen') + #===============================================定义启动文件======================================================== + ld = LaunchDescription() + ld.add_action(cartographer_node) + ld.add_action(cartographer_occupancy_grid_node) + ld.add_action(rviz_node) + return ld +``` + +## 遇到的问题 + +漂移严重,排查出配置文件的数据问题laser的扫描范围TRAJECTORY_BUILDER_2D.max_range = 5.5 + +实际为50 + +也可能是因为发布了实时的track_pose——结论是发布了实时姿态,配置文件中的实时姿态失效了。 + + + +在接入odom数据建立TF树时,TF树可以静态发布,命令或者写入launch文件或者写入urdf中 + + + +# Navigation2 建图 + +## 建立小车模型(即TF树,很重要) + +每个节点都是与父节点相连,构建TF树 + +```urdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +**xyz**代表是相对于父节点的位置,**rpy**是绕轴旋转的角度。 + +### 遇到问题即解决思路 + +使用建好的图过程中使用2D Estimate初始化小车点时,存在地图与小车雷达不重叠,形成90度。 + +![](./lidar.jpg) + +所以调整**rpy**来使得雷达和地图重叠。将雷达的rpy=“0 0 4.71” + + + diff --git a/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/ahrs_driver_node b/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/ahrs_driver_node new file mode 100644 index 0000000000000000000000000000000000000000..bec00ab49430aa0ea2ac57c5fa37f5ac0fee06a3 Binary files /dev/null and b/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/ahrs_driver_node differ diff --git a/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/imu_tf_node b/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/imu_tf_node new file mode 100644 index 0000000000000000000000000000000000000000..30a5a5455c23ca696e2706c32bfb6467d4e35f96 Binary files /dev/null and b/hi-slam/fdilink_ahrs/lib/fdilink_ahrs/imu_tf_node differ diff --git a/hi-slam/fdilink_ahrs/share/ament_index/resource_index/package_run_dependencies/fdilink_ahrs b/hi-slam/fdilink_ahrs/share/ament_index/resource_index/package_run_dependencies/fdilink_ahrs new file mode 100644 index 0000000000000000000000000000000000000000..562d42553b90b73e89d871d3afd8a25eb180a57a --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/ament_index/resource_index/package_run_dependencies/fdilink_ahrs @@ -0,0 +1 @@ +rclcpp;rclpy;sensor_msgs;std_msgs;tf2;tf2_ros;nav_msgs;geometry_msgs;ament_lint_auto;ament_lint_common \ No newline at end of file diff --git a/hi-slam/fdilink_ahrs/share/ament_index/resource_index/packages/fdilink_ahrs b/hi-slam/fdilink_ahrs/share/ament_index/resource_index/packages/fdilink_ahrs new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/hi-slam/fdilink_ahrs/share/ament_index/resource_index/parent_prefix_path/fdilink_ahrs b/hi-slam/fdilink_ahrs/share/ament_index/resource_index/parent_prefix_path/fdilink_ahrs new file mode 100644 index 0000000000000000000000000000000000000000..52dcc6851961188670b623b77f19505e8fa41bb3 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/ament_index/resource_index/parent_prefix_path/fdilink_ahrs @@ -0,0 +1 @@ +/opt/openeuler/oecore-x86_64/sysroots/aarch64-openeuler-linux/usr \ No newline at end of file diff --git a/hi-slam/fdilink_ahrs/share/colcon-core/packages/fdilink_ahrs b/hi-slam/fdilink_ahrs/share/colcon-core/packages/fdilink_ahrs new file mode 100644 index 0000000000000000000000000000000000000000..8921a69798006752fc752542ce7c7245202ce0a7 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/colcon-core/packages/fdilink_ahrs @@ -0,0 +1 @@ +geometry_msgs:nav_msgs:rclcpp:rclpy:sensor_msgs:std_msgs:tf2:tf2_ros \ No newline at end of file diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig-version.cmake b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig-version.cmake new file mode 100644 index 0000000000000000000000000000000000000000..7beb732887ac12a8da14fe26db26abe3359cdbd8 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig-version.cmake @@ -0,0 +1,14 @@ +# generated from ament/cmake/core/templates/nameConfig-version.cmake.in +set(PACKAGE_VERSION "0.0.0") + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if("${PACKAGE_FIND_VERSION}" VERSION_EQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if("${PACKAGE_FIND_VERSION}" VERSION_LESS "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig.cmake b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig.cmake new file mode 100644 index 0000000000000000000000000000000000000000..788e34aaa6b524d46831aec5cc8e6aaf5c0c0f0b --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/cmake/fdilink_ahrsConfig.cmake @@ -0,0 +1,42 @@ +# generated from ament/cmake/core/templates/nameConfig.cmake.in + +# prevent multiple inclusion +if(_fdilink_ahrs_CONFIG_INCLUDED) + # ensure to keep the found flag the same + if(NOT DEFINED fdilink_ahrs_FOUND) + # explicitly set it to FALSE, otherwise CMake will set it to TRUE + set(fdilink_ahrs_FOUND FALSE) + elseif(NOT fdilink_ahrs_FOUND) + # use separate condition to avoid uninitialized variable warning + set(fdilink_ahrs_FOUND FALSE) + endif() + return() +endif() +set(_fdilink_ahrs_CONFIG_INCLUDED TRUE) + +# output package information +if(NOT fdilink_ahrs_FIND_QUIETLY) + message(STATUS "Found fdilink_ahrs: 0.0.0 (${fdilink_ahrs_DIR})") +endif() + +# warn when using a deprecated package +if(NOT "" STREQUAL "") + set(_msg "Package 'fdilink_ahrs' is deprecated") + # append custom deprecation text if available + if(NOT "" STREQUAL "TRUE") + set(_msg "${_msg} ()") + endif() + # optionally quiet the deprecation message + if(NOT ${fdilink_ahrs_DEPRECATED_QUIET}) + message(DEPRECATION "${_msg}") + endif() +endif() + +# flag package as ament-based to distinguish it after being find_package()-ed +set(fdilink_ahrs_FOUND_AMENT_PACKAGE TRUE) + +# include all config extra files +set(_extras "") +foreach(_extra ${_extras}) + include("${fdilink_ahrs_DIR}/${_extra}") +endforeach() diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.dsv b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.dsv new file mode 100644 index 0000000000000000000000000000000000000000..79d4c95b55cb72a17c9be498c3758478e2c7bb8d --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.dsv @@ -0,0 +1 @@ +prepend-non-duplicate;AMENT_PREFIX_PATH; diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.sh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.sh new file mode 100644 index 0000000000000000000000000000000000000000..02e441b753539b4cf0c89e115f69b00b1dbf8460 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/ament_prefix_path.sh @@ -0,0 +1,4 @@ +# copied from +# ament_cmake_core/cmake/environment_hooks/environment/ament_prefix_path.sh + +ament_prepend_unique_value AMENT_PREFIX_PATH "$AMENT_CURRENT_PREFIX" diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.dsv b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.dsv new file mode 100644 index 0000000000000000000000000000000000000000..b94426af08131a4ff58f8cc1caa47697427d6bd4 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.dsv @@ -0,0 +1 @@ +prepend-non-duplicate-if-exists;PATH;bin diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.sh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.sh new file mode 100644 index 0000000000000000000000000000000000000000..e59b749a890ded9c46e9eaae2b9b6e42a1df1584 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/environment/path.sh @@ -0,0 +1,5 @@ +# copied from ament_cmake_core/cmake/environment_hooks/environment/path.sh + +if [ -d "$AMENT_CURRENT_PREFIX/bin" ]; then + ament_prepend_unique_value PATH "$AMENT_CURRENT_PREFIX/bin" +fi diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.dsv b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.dsv new file mode 100644 index 0000000000000000000000000000000000000000..e119f32cba928c962cb0e9e25ca919bfce4c3e76 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.dsv @@ -0,0 +1 @@ +prepend-non-duplicate;CMAKE_PREFIX_PATH; diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.sh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.sh new file mode 100644 index 0000000000000000000000000000000000000000..a948e685ba5b63fd771736a77f467ddc57aed5a6 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/hook/cmake_prefix_path.sh @@ -0,0 +1,3 @@ +# generated from colcon_core/shell/template/hook_prepend_value.sh.em + +_colcon_prepend_unique_value CMAKE_PREFIX_PATH "$COLCON_CURRENT_PREFIX" diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/ahrs_driver.launch.py b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/ahrs_driver.launch.py new file mode 100644 index 0000000000000000000000000000000000000000..30cc26397fe9ccf52e294d91f17247c2e0b7b135 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/ahrs_driver.launch.py @@ -0,0 +1,36 @@ +import os +from pathlib import Path +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import (DeclareLaunchArgument, GroupAction, + IncludeLaunchDescription, SetEnvironmentVariable) +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch_ros.actions import Node +#bringup_dir = get_package_share_directory('fdilink_ahrs') +#launch_dir = os.path.join(bringup_dir, 'launch') +#imu_tf = IncludeLaunchDescription( +# PythonLaunchDescriptionSource(os.path.join(launch_dir, 'imu_tf.launch.py')), +#) +def generate_launch_description(): + ahrs_driver=Node( + package="fdilink_ahrs", + executable="ahrs_driver_node", + parameters=[{'if_debug_': False, + 'serial_port_':'/dev/ttyUSB0', + 'serial_baud_':921600, + 'imu_topic':'/imu', + 'imu_frame_id_':'gyro_link', + 'mag_pose_2d_topic':'/mag_pose_2d', + 'Magnetic_topic':'/magnetic', + 'Euler_angles_topic':'/euler_angles', + 'gps_topic':'/gps/fix', + 'twist_topic':'/system_speed', + 'NED_odom_topic':'/NED_odometry', + 'device_type_':1}], + output="screen" + ) + + launch_description =LaunchDescription() + launch_description.add_action(ahrs_driver) +# launch_description.add_action(imu_tf) + return launch_description diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/imu_tf.launch.py b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/imu_tf.launch.py new file mode 100644 index 0000000000000000000000000000000000000000..46dd488b4f1ae6afa7b649c4982cb5532cf199cd --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/launch/imu_tf.launch.py @@ -0,0 +1,18 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + imu_tf=Node( + package="fdilink_ahrs", + #node_executable="imu_tf_node", + parameters=[{'imu_topic':'/imu', + 'world_frame_id':'/world', + 'imu_frame_id':'/gyro_link', + 'position_x':1, + 'position_y':1, + 'position_z':1, + }], + ) + + launch_description =LaunchDescription([imu_tf]) + return launch_description diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.bash b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.bash new file mode 100644 index 0000000000000000000000000000000000000000..49782f2461df73f0adf9a3089784ec3e9e5edfb0 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.bash @@ -0,0 +1,46 @@ +# generated from ament_package/template/package_level/local_setup.bash.in + +# source local_setup.sh from same directory as this file +_this_path=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" && pwd) +# provide AMENT_CURRENT_PREFIX to shell script +AMENT_CURRENT_PREFIX=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`/../.." && pwd) +# store AMENT_CURRENT_PREFIX to restore it before each environment hook +_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX + +# trace output +if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then + echo "# . \"$_this_path/local_setup.sh\"" +fi +. "$_this_path/local_setup.sh" +unset _this_path + +# unset AMENT_ENVIRONMENT_HOOKS +# if not appending to them for return +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + unset AMENT_ENVIRONMENT_HOOKS +fi + +# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks +AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX +# list all environment hooks of this package + +# source all shell-specific environment hooks of this package +# if not returning them +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + _package_local_setup_IFS=$IFS + IFS=":" + for _hook in $AMENT_ENVIRONMENT_HOOKS; do + # restore AMENT_CURRENT_PREFIX for each environment hook + AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX + # restore IFS before sourcing other files + IFS=$_package_local_setup_IFS + . "$_hook" + done + unset _hook + IFS=$_package_local_setup_IFS + unset _package_local_setup_IFS + unset AMENT_ENVIRONMENT_HOOKS +fi + +unset _package_local_setup_AMENT_CURRENT_PREFIX +unset AMENT_CURRENT_PREFIX diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.dsv b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.dsv new file mode 100644 index 0000000000000000000000000000000000000000..2bb3e2d3127c34d002cdfeecdd4cf77c0c4568e4 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.dsv @@ -0,0 +1,2 @@ +source;share/fdilink_ahrs/environment/ament_prefix_path.sh +source;share/fdilink_ahrs/environment/path.sh diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.sh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.sh new file mode 100644 index 0000000000000000000000000000000000000000..c5198673cba4257201b106ed5f5711d140f2c7da --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.sh @@ -0,0 +1,184 @@ +# generated from ament_package/template/package_level/local_setup.sh.in + +# since this file is sourced use either the provided AMENT_CURRENT_PREFIX +# or fall back to the destination set at configure time +: ${AMENT_CURRENT_PREFIX:="/home/openeuler/build/sd3403/fdilink_ahrs_ROS2/install/fdilink_ahrs"} +if [ ! -d "$AMENT_CURRENT_PREFIX" ]; then + if [ -z "$COLCON_CURRENT_PREFIX" ]; then + echo "The compile time prefix path '$AMENT_CURRENT_PREFIX' doesn't " \ + "exist. Consider sourcing a different extension than '.sh'." 1>&2 + else + AMENT_CURRENT_PREFIX="$COLCON_CURRENT_PREFIX" + fi +fi + +# function to append values to environment variables +# using colons as separators and avoiding leading separators +ament_append_value() { + # arguments + _listname="$1" + _value="$2" + #echo "listname $_listname" + #eval echo "list value \$$_listname" + #echo "value $_value" + + # avoid leading separator + eval _values=\"\$$_listname\" + if [ -z "$_values" ]; then + eval export $_listname=\"$_value\" + #eval echo "set list \$$_listname" + else + # field separator must not be a colon + _ament_append_value_IFS=$IFS + unset IFS + eval export $_listname=\"\$$_listname:$_value\" + #eval echo "append list \$$_listname" + IFS=$_ament_append_value_IFS + unset _ament_append_value_IFS + fi + unset _values + + unset _value + unset _listname +} + +# function to append non-duplicate values to environment variables +# using colons as separators and avoiding leading separators +ament_append_unique_value() { + # arguments + _listname=$1 + _value=$2 + #echo "listname $_listname" + #eval echo "list value \$$_listname" + #echo "value $_value" + + # check if the list contains the value + eval _values=\$$_listname + _duplicate= + _ament_append_unique_value_IFS=$IFS + IFS=":" + if [ "$AMENT_SHELL" = "zsh" ]; then + ament_zsh_to_array _values + fi + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + if [ $_item = $_value ]; then + _duplicate=1 + fi + done + unset _item + + # append only non-duplicates + if [ -z "$_duplicate" ]; then + # avoid leading separator + if [ -z "$_values" ]; then + eval $_listname=\"$_value\" + #eval echo "set list \$$_listname" + else + # field separator must not be a colon + unset IFS + eval $_listname=\"\$$_listname:$_value\" + #eval echo "append list \$$_listname" + fi + fi + IFS=$_ament_append_unique_value_IFS + unset _ament_append_unique_value_IFS + unset _duplicate + unset _values + + unset _value + unset _listname +} + +# function to prepend non-duplicate values to environment variables +# using colons as separators and avoiding trailing separators +ament_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + #echo "listname $_listname" + #eval echo "list value \$$_listname" + #echo "value $_value" + + # check if the list contains the value + eval _values=\"\$$_listname\" + _duplicate= + _ament_prepend_unique_value_IFS=$IFS + IFS=":" + if [ "$AMENT_SHELL" = "zsh" ]; then + ament_zsh_to_array _values + fi + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + if [ "$_item" = "$_value" ]; then + _duplicate=1 + fi + done + unset _item + + # prepend only non-duplicates + if [ -z "$_duplicate" ]; then + # avoid trailing separator + if [ -z "$_values" ]; then + eval export $_listname=\"$_value\" + #eval echo "set list \$$_listname" + else + # field separator must not be a colon + unset IFS + eval export $_listname=\"$_value:\$$_listname\" + #eval echo "prepend list \$$_listname" + fi + fi + IFS=$_ament_prepend_unique_value_IFS + unset _ament_prepend_unique_value_IFS + unset _duplicate + unset _values + + unset _value + unset _listname +} + +# unset AMENT_ENVIRONMENT_HOOKS +# if not appending to them for return +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + unset AMENT_ENVIRONMENT_HOOKS +fi + +# list all environment hooks of this package +ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/fdilink_ahrs/environment/ament_prefix_path.sh" +ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/fdilink_ahrs/environment/path.sh" + +# source all shell-specific environment hooks of this package +# if not returning them +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + _package_local_setup_IFS=$IFS + IFS=":" + if [ "$AMENT_SHELL" = "zsh" ]; then + ament_zsh_to_array AMENT_ENVIRONMENT_HOOKS + fi + for _hook in $AMENT_ENVIRONMENT_HOOKS; do + if [ -f "$_hook" ]; then + # restore IFS before sourcing other files + IFS=$_package_local_setup_IFS + # trace output + if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then + echo "# . \"$_hook\"" + fi + . "$_hook" + fi + done + unset _hook + IFS=$_package_local_setup_IFS + unset _package_local_setup_IFS + unset AMENT_ENVIRONMENT_HOOKS +fi + +# reset AMENT_CURRENT_PREFIX after each package +# allowing to source multiple package-level setup files +unset AMENT_CURRENT_PREFIX diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.zsh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.zsh new file mode 100644 index 0000000000000000000000000000000000000000..fe161be53dc8e564d26ad9387d7259807986dc51 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/local_setup.zsh @@ -0,0 +1,59 @@ +# generated from ament_package/template/package_level/local_setup.zsh.in + +AMENT_SHELL=zsh + +# source local_setup.sh from same directory as this file +_this_path=$(builtin cd -q "`dirname "${(%):-%N}"`" > /dev/null && pwd) +# provide AMENT_CURRENT_PREFIX to shell script +AMENT_CURRENT_PREFIX=$(builtin cd -q "`dirname "${(%):-%N}"`/../.." > /dev/null && pwd) +# store AMENT_CURRENT_PREFIX to restore it before each environment hook +_package_local_setup_AMENT_CURRENT_PREFIX=$AMENT_CURRENT_PREFIX + +# function to convert array-like strings into arrays +# to wordaround SH_WORD_SPLIT not being set +ament_zsh_to_array() { + local _listname=$1 + local _dollar="$" + local _split="{=" + local _to_array="(\"$_dollar$_split$_listname}\")" + eval $_listname=$_to_array +} + +# trace output +if [ -n "$AMENT_TRACE_SETUP_FILES" ]; then + echo "# . \"$_this_path/local_setup.sh\"" +fi +# the package-level local_setup file unsets AMENT_CURRENT_PREFIX +. "$_this_path/local_setup.sh" +unset _this_path + +# unset AMENT_ENVIRONMENT_HOOKS +# if not appending to them for return +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + unset AMENT_ENVIRONMENT_HOOKS +fi + +# restore AMENT_CURRENT_PREFIX before evaluating the environment hooks +AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX +# list all environment hooks of this package + +# source all shell-specific environment hooks of this package +# if not returning them +if [ -z "$AMENT_RETURN_ENVIRONMENT_HOOKS" ]; then + _package_local_setup_IFS=$IFS + IFS=":" + for _hook in $AMENT_ENVIRONMENT_HOOKS; do + # restore AMENT_CURRENT_PREFIX for each environment hook + AMENT_CURRENT_PREFIX=$_package_local_setup_AMENT_CURRENT_PREFIX + # restore IFS before sourcing other files + IFS=$_package_local_setup_IFS + . "$_hook" + done + unset _hook + IFS=$_package_local_setup_IFS + unset _package_local_setup_IFS + unset AMENT_ENVIRONMENT_HOOKS +fi + +unset _package_local_setup_AMENT_CURRENT_PREFIX +unset AMENT_CURRENT_PREFIX diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.dsv b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.dsv new file mode 100644 index 0000000000000000000000000000000000000000..46f3eb326987d349ab3c06f9502cf619c4a3362b --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.dsv @@ -0,0 +1,4 @@ +source;share/fdilink_ahrs/hook/cmake_prefix_path.dsv +source;share/fdilink_ahrs/hook/cmake_prefix_path.sh +source;share/fdilink_ahrs/local_setup.dsv +source;share/fdilink_ahrs/local_setup.sh diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.sh b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.sh new file mode 100644 index 0000000000000000000000000000000000000000..91150284d990036b21fd1beb8048445a0b585fe5 --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.sh @@ -0,0 +1,87 @@ +# generated from colcon_core/shell/template/package.sh.em + +# This script extends the environment for this package. + +# function to prepend a value to a variable +# which uses colons as separators +# duplicates as well as trailing separators are avoided +# first argument: the name of the result variable +# second argument: the value to be prepended +_colcon_prepend_unique_value() { + # arguments + _listname="$1" + _value="$2" + + # get values from variable + eval _values=\"\$$_listname\" + # backup the field separator + _colcon_prepend_unique_value_IFS=$IFS + IFS=":" + # start with the new value + _all_values="$_value" + # workaround SH_WORD_SPLIT not being set in zsh + if [ "$(command -v colcon_zsh_convert_to_array)" ]; then + colcon_zsh_convert_to_array _values + fi + # iterate over existing values in the variable + for _item in $_values; do + # ignore empty strings + if [ -z "$_item" ]; then + continue + fi + # ignore duplicates of _value + if [ "$_item" = "$_value" ]; then + continue + fi + # keep non-duplicate values + _all_values="$_all_values:$_item" + done + unset _item + # restore the field separator + IFS=$_colcon_prepend_unique_value_IFS + unset _colcon_prepend_unique_value_IFS + # export the updated variable + eval export $_listname=\"$_all_values\" + unset _all_values + unset _values + + unset _value + unset _listname +} + +# since a plain shell script can't determine its own path when being sourced +# either use the provided COLCON_CURRENT_PREFIX +# or fall back to the build time prefix (if it exists) +_colcon_package_sh_COLCON_CURRENT_PREFIX="/home/openeuler/build/sd3403/fdilink_ahrs_ROS2/install/fdilink_ahrs" +if [ -z "$COLCON_CURRENT_PREFIX" ]; then + if [ ! -d "$_colcon_package_sh_COLCON_CURRENT_PREFIX" ]; then + echo "The build time path \"$_colcon_package_sh_COLCON_CURRENT_PREFIX\" doesn't exist. Either source a script for a different shell or set the environment variable \"COLCON_CURRENT_PREFIX\" explicitly." 1>&2 + unset _colcon_package_sh_COLCON_CURRENT_PREFIX + return 1 + fi + COLCON_CURRENT_PREFIX="$_colcon_package_sh_COLCON_CURRENT_PREFIX" +fi +unset _colcon_package_sh_COLCON_CURRENT_PREFIX + +# function to source another script with conditional trace output +# first argument: the path of the script +# additional arguments: arguments to the script +_colcon_package_sh_source_script() { + if [ -f "$1" ]; then + if [ -n "$COLCON_TRACE" ]; then + echo "# . \"$1\"" + fi + . "$@" + else + echo "not found: \"$1\"" 1>&2 + fi +} + +# source sh hooks +_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/fdilink_ahrs/hook/cmake_prefix_path.sh" +_colcon_package_sh_source_script "$COLCON_CURRENT_PREFIX/share/fdilink_ahrs/local_setup.sh" + +unset _colcon_package_sh_source_script +unset COLCON_CURRENT_PREFIX + +# do not unset _colcon_prepend_unique_value since it might be used by non-primary shell hooks diff --git a/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.xml b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.xml new file mode 100644 index 0000000000000000000000000000000000000000..fa6885c60674109633575c0cdcd4e13daa464fee --- /dev/null +++ b/hi-slam/fdilink_ahrs/share/fdilink_ahrs/package.xml @@ -0,0 +1,27 @@ + + + + fdilink_ahrs + 0.0.0 + TODO: Package description + noah + TODO: License declaration + + ament_cmake + + rclcpp + rclpy + sensor_msgs + std_msgs + tf2 + tf2_ros + nav_msgs + geometry_msgs + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/hi-slam/images/Mind Map.jpg b/hi-slam/images/Mind Map.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b4b4894247ddc2a5fe6345c770900ade9d182218 Binary files /dev/null and b/hi-slam/images/Mind Map.jpg differ diff --git a/hi-slam/images/image-20240827102427288.png b/hi-slam/images/image-20240827102427288.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0634fbe443ee305bca732ee24ac4a203e83b1b Binary files /dev/null and b/hi-slam/images/image-20240827102427288.png differ diff --git a/hi-slam/images/image-20240827102935627.png b/hi-slam/images/image-20240827102935627.png new file mode 100644 index 0000000000000000000000000000000000000000..f5399b44b494e7ad14dffc1030e771f3c729ed48 Binary files /dev/null and b/hi-slam/images/image-20240827102935627.png differ diff --git a/hi-slam/images/image-20240827103404295.png b/hi-slam/images/image-20240827103404295.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7c543f08e0ef1364f828cf0a63fff46638b226 Binary files /dev/null and b/hi-slam/images/image-20240827103404295.png differ diff --git a/hi-slam/images/image-20240827103432147.png b/hi-slam/images/image-20240827103432147.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7c543f08e0ef1364f828cf0a63fff46638b226 Binary files /dev/null and b/hi-slam/images/image-20240827103432147.png differ diff --git a/hi-slam/images/image-20240827103535836.png b/hi-slam/images/image-20240827103535836.png new file mode 100644 index 0000000000000000000000000000000000000000..1f9c2528f76bb6978fd6f1aa0c8de7825e7300c7 Binary files /dev/null and b/hi-slam/images/image-20240827103535836.png differ diff --git a/hi-slam/odom_ekf.md b/hi-slam/odom_ekf.md new file mode 100644 index 0000000000000000000000000000000000000000..c0d9bf7c177e41b5a4d9c47a0da1c033a37b5c87 --- /dev/null +++ b/hi-slam/odom_ekf.md @@ -0,0 +1,205 @@ +```yaml +###ekf配置文件### +ekf_filter_node: + ros__parameters: + + +# 滤波器输出位置估计的频率,单位为Hz。请注意,过滤器在从其中一个输入接收到至少一条消息之前不会开始计算。 +# 然后,无论是否接收到更多的测量值,它都将以此处指定的频率连续运行。如果未指定,则默认为30。 + frequency: 30.0 + +# 我们认为传感器超时的时间段(以秒为单位)。在这种情况下,我们在EKF上执行一个预测周期,而不进行校正。 +# 这个参数可以被认为是滤波器产生新输出的最小频率。如果未指定,则默认为1/频率。 + sensor_timeout: 0.1 + +# ekf_localization_node and ukf_localization_node都使用3D全向运动模型。 +# 如果此参数设置为true,则不会在状态估计中使用任何三维信息。 +# 如果您在平面环境中操作,并且希望忽略地平面中可能检测到的微小变化的影响,请使用此选项 +# 例如通过IMU。如果未指定,则默认为false。 + two_d_mode: true + +# 使用此参数可以为ekf_location_node生成的变换提供偏移。这可以用于未来的日期转换,这是与其他一些包交互所必需的。 +# 如果未指定,则默认为0.0。 + transform_time_offset: 0.0 + +#使用此参数可以指定tf侦听器应等待转换可用的时间。 +#如果未指定,则默认为0.0。 + transform_timeout: 0.0 + +#如果遇到问题,请尝试将其设置为true,然后echo the /diagnostics_agg主题,查看节点是否对任何设置或数据不满意 + print_diagnostics: true + +# 调试设置。不适合胆小的人。向debug_out_file指定的文件输出数量惊人的信息。我希望你喜欢矩阵! +# 请注意,将此设置为true将对节点的性能产生严重的有害影响。如果未指定,则默认为false。 + debug: false + +#如果未指定,则默认为“robot_location_debug.txt”。请指定完整路径。 + debug_out_file: /path/to/debug/file.txt + +# 我们是否允许旧的测量结果导致更新状态的重新发布 + permit_corrected_publication: false + + #是否发布加速状态。如果未指定,则默认为false。 + publish_acceleration: false + +#是否在/tf主题上广播转换。如果未指定,则默认为true。 + publish_tf: false + +# REP-105(http://www.ros.org/reps/rep-0105.html)指定四个主要坐标系:base_link、odom、map和earth。 +# base_link是固定在机器人上的坐标系。odom和map都是world-fixed frames。 +# 机器人在odom框架中的位置会随着时间的推移而漂移,但在短期内是准确的,应该是连续的。因此,odom帧是用于执行局部运动计划的最佳帧。 +# 与odom框架一样,map框架是一个世界固定的坐标框架,虽然它包含了机器人最全局准确的位置估计,但它会受到离散跳跃的影响, +# 例如,由于GPS数据的融合或基于地图的定位节点的校正。地球坐标系用于通过给多个地图坐标系提供一个公共参考坐标系来关联它们。 +# ekf_location_node和ukf_localization_node与map帧无关。 + +#以下是如何使用以下设置: + +# odom_frame. +# 1.将map_frame、odom_frame和base_link帧设置为系统的适当帧名称。 +# 1a. 如果您的系统没有map_frame,只需将其删除,并确保“world_frame”设置为odom_frame的值。 +# 2. 如果要融合连续位置数据,如车轮编码器里程计、视觉里程计或IMU数据,请将“world_frame”设置为odom_frame值。这是robot_location的状态估计节点的默认行为。 +# 3. 如果您正在融合受离散跳跃影响的全球绝对位置数据(例如,GPS或地标的位置更新观察),然后: +# 3a. 将“world_frame”设置为map_frame值 +# 3b. 确保其他东西正在生成odom->base_link变换。请注意,这甚至可以是robot_location的另一个状态估计节点!但是,该实例不应该融合全局数据。 + + map_frame: map # 如果未指定,则默认为“map” + odom_frame: odom # 如果未指定,则默认为"odom" + base_link_frame: base_link # 如果未指定,则默认为"base_link" + world_frame: odom # 如果未指定,则默认为"odom" + +# 过滤器接受来自每个输入消息类型的任意数量的输入(nav_msgs/Odometry、geometry_msgs/PoseWithCovarianceStamped、 +#要添加输入,只需将序列中的下一个数字附加到其“base”名称,例如odom0、odom1、twist0、twist1、imu0、imu1、imu2等。 +#该值应为topic名称。这些参数显然没有默认值,必须指定。 + odom0: /odom_diff + +# 每个传感器读数都会更新过滤器的部分或全部状态。这些选项使您能够更好地控制将每个测量值输入到过滤器的值。 +# 例如,如果您有里程计消息作为输入,但只想使用其Z位置值,则将整个矢量设置为false,第三个条目除外。 +# 值的顺序为x、y、z、roll、pitch、yaw、vx、vy、vz、vroll、vpitch、vyaw、ax、ay、az。 +# 请注意,并非某些消息类型不提供过滤器估计的某些状态变量。例如,TwistWithCovarianceStamped消息没有姿势信息, +# 因此在这种情况下,前六个值将毫无意义。如果未指定,则每个向量默认为全假,从而有效地使每个传感器都需要此参数。 + odom0_config: [false, false, false, #x-y-z坐标系的坐标(机器人位置) + false, false, false, #绕x/y/z轴的角度(机器人方向)、 + true, false, false, #沿x/y/z轴的线速度、 + false, false, true, #绕x/y/z轴的角速度、 + false, false, false] #沿x/y/z轴的加速度。 + +#如果您有高频数据或使用低频参数值运行,则可能需要增加订阅队列的大小,以便融合更多的测量值。 + odom0_queue_size: 20 + +# [高级]ROS中的大消息在高频到达时会表现出奇怪的行为。这是Nagle算法的结果。 +# 此选项告诉ROS订户使用tcpNoDelay选项,该选项禁用Nagle的算法。 + odom0_nodelay: false + +# [高级]当用两个传感器测量一个姿态变量时,可能会出现两个传感器都报告不足的情况。这可能导致滤波器在每次测量到达时快速来回跳跃。 +# 在这些情况下,(a)校正测量协变量,或者(b)如果其中一个传感器也测量速度,则让一个传感器测量姿态,而另一个传感器则测量速度, +# 这通常是有意义的。然而,做(a)或(b)并不总是可行的,因此我们公开了微分参数。启用差分模式时,通过对绝对姿态测量值进行微分, +# 将所有绝对姿态数据转换为速度数据。然后像往常一样对这些速度进行积分。注:这仅适用于提供姿态测量的传感器; +# 将twist测量的微分设置为true没有效果。 + odom0_differential: false + +# [ADVANCED]当节点启动时,如果此参数为真,则第一次测量将被视为所有未来测量的“零点”。虽然你可以用微分参数计获得同样的效果, +# 但关键的区别在于,相对参数不会导致测量在积分之前转换为速度。如果你只是想让给定传感器的测量从0开始,请将其设置为true。 + odom0_relative: false + +# [ADVANCED]如果您的数据存在异常值,请使用这些阈值设置(表示为Mahalanobis距离)来控制允许传感器测量距离当前车辆状态的距离。 +# 如果未指定,则每个阈值都默认为numeric_limits<double>::max()。如果不需要,强烈建议删除这些参数。 +# 数据是在姿势和扭曲变量级别指定的,而不是单独为每个变量指定的。对于同时具有姿势和扭曲数据的消息, +# 该参数指定我们将阈值应用于消息的哪一部分。 + odom0_pose_rejection_threshold: 5.0 + odom0_twist_rejection_threshold: 1.0 + + imu0: /imu_data + + imu0_config: [false, false, false, #x-y-z坐标系的坐标(机器人位置) + false, false, false, #绕x/y/z轴的角度(机器人方向) + false, false, false, #沿x/y/z轴的线速度 + false, false, true, #绕x/y/z轴的角速度 + true, true, false] #沿x/y/z轴的加速度 + imu0_nodelay: false + imu0_differential: false + imu0_relative: false + imu0_queue_size: 20 + imu0_pose_rejection_threshold: 0.8 # 注意参数名称的差异 + imu0_twist_rejection_threshold: 0.8 + imu0_linear_acceleration_rejection_threshold: 0.8 + +# [高级]一些IMU会自动消除重力造成的加速度,而另一些则不会。如果您的数据不符合,请将其设置为true, +# 并*确保*您的数据符合REP-103,特别是数据在ENU框架中。 + imu0_remove_gravitational_acceleration: false + +# [高级]EKF和UKF模型遵循标准的预测/校正周期。在预测期间,如果没有加速度参考,则简单地将时间t+1处的速度预测为与时间t处的速度相同。 +# 在校正期间,将该预测值与测量值融合以产生新的速度估计。这可能是有问题的,因为最终速度实际上是旧速度和新速度的加权平均值。 +# 当这个速度被整合到一个新的姿势中时,结果可能是缓慢的隐蔽。这种效果在旋转过程中的激光雷达数据中尤为明显。为了解决这个问题, +# 用户可以尝试为有问题的速度变量增加process_noise_covariance,或者在测量本身中减少有问题的变量的方差。 +# 此外,用户还可以利用在我们进行预测时向机器人发出的控制命令。如果使用控制,它将被转换为加速项,该加速项将在预测过程中使用。 +# 请注意,如果从其中一个输入中可以获得有关变量的加速度测量值,则控制项将被忽略。 +# 无论我们是否在预测期间使用控制输入。默认为false。 + use_control: false + +#输入(假定为cmd_vel)是geometry_msgs/Twist还是geometry_msgs/TwistStamped消息。默认为false。 + stamped_control: false + +#最后发布的控制命令将用于该时段的预测。默认值为0.2。 + control_timeout: 0.2 + +#正在控制哪些速度。顺序是vx、vy、vz、vroll、vpitch、vyaw。 + control_config: [true, false, false, false, false, true] + +# 限制加速度项的大小。应与机器人的运动学相匹配。 + acceleration_limits: [1.3, 0.0, 0.0, 0.0, 0.0, 3.4] + +#机器人的加速和减速限制并不总是相同的。 + deceleration_limits: [1.3, 0.0, 0.0, 0.0, 0.0, 4.5] + +#如果你的机器人不能立即达到其加速度极限,那么可以通过这些增益来控制允许的变化 + acceleration_gains: [0.8, 0.0, 0.0, 0.0, 0.0, 0.9] + +# 如果你的机器人不能立即达到减速极限,那么允许的变化可以用这些增益来控制 + deceleration_gains: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0] + +# [ADVANCED]过程噪声协方差矩阵可能很难调整,并且可能因每个应用而变化,因此它被公开为配置参数。 +# 这个矩阵表示我们在每个预测步骤之后添加到总误差中的噪声。全向运动模型与系统匹配得越好,这些值就越小。 +# 然而,如果用户发现给定的变量收敛较慢,一种方法是增加该变量的process_noise_covariance对角值,这将导致滤波器的预测误差更大, +# 这将使得滤波器在校正期间更加信任传入的测量。值的顺序为x、y、z、滚转、俯仰、偏航、vx、vy、vz、vroll、vpitch、vyaw、ax、ay、az。 +# 如果未指定,则默认为以下矩阵。 + process_noise_covariance: [0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.06, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.025, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.015] + +# [ADVANCED]这表示状态估计误差协方差矩阵的初始值。将对角线值(方差)设置为大值将导致所讨论变量的初始测量的快速收敛。 +# 用户应注意不要对不会直接测量的变量使用大值。 +# 用户应注意不要对不会直接测量的变量使用大值。 +# 值的顺序为x、y、z、滚转、俯仰、偏航、vx、vy、vz、vroll、vpitch、vyaw、ax、ay、az。 +# 如果未指定,则默认为以下矩阵。 + initial_estimate_covariance: [1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-9] + +``` + + + diff --git "a/hi-slam/\351\241\271\347\233\256\350\207\252\346\265\213\346\212\245\345\221\212.md" "b/hi-slam/\351\241\271\347\233\256\350\207\252\346\265\213\346\212\245\345\221\212.md" new file mode 100644 index 0000000000000000000000000000000000000000..a310b7ab2227d2b68dcdab0fac2d7cefa631bd3a --- /dev/null +++ "b/hi-slam/\351\241\271\347\233\256\350\207\252\346\265\213\346\212\245\345\221\212.md" @@ -0,0 +1,247 @@ +# 项目自测报告 + +## 1.软硬件环境 + +### 硬件环境 + +- 架构:ARM64 + +### 软件环境 + +- 操作系统:OpenEuler 24.03 +- 虚拟机操作系统:Ubuntu 22.04 + +## 2.上手部署方式 + +### 2.1 下载项目代码: + +这里使用gitee网站上,【eulercar项目】举例,网址为:https://gitee.com/HiEuler/eulercar + +先从gitee网站上,将项目代码下载到到ubuntu环境,普通目录/home/robot下: + +```sh +cd /home/robot git clone https://gitee.com/HiEuler/eulercar.git +``` + +然后将项目代码,拷贝到docker容器目录中: + +```sh +cp -rf eulercar /home/robot/hieuler/build_3403/build/sd3403 + +``` + + + +### 2.2 下载安装SDK: + +进入docker容器目录: + +```sh +cd /home/robot/hieuler/build_3403/build/sd3403 +``` + +下载SDK(**下边的wget** **网址是一行命令,放到一行执行**): + +```sh +wget https://mirrors.dotsrc.org/openeuler/openEuler-24.03-LTS/embedded_img/aarch64/hieulerpi1-ros/openeuler-glibc-x86_64-openeuler-image-aarch64-hieulerpi1-toolchain-24.03-LTS.sh +``` + +查看下载的文件,增加可执行权限: + +```sh +ls -l chmod +x openeuler-glibc-x86_64-openeuler-image-aarch64-hieulerpi1-toolchain-24.03-LTS.sh +``` + +执行下面命令,切换到openEuler交互环境,用户切换为openeuler: + +```bash +oebuild bitbake +``` + +安装刚刚下载的SDK: + +```bash +./openeuler-glibc-x86_64-openeuler-image-aarch64-hieulerpi1-toolchain-24.03-LTS.sh +``` + +回车;输入y,回车;使SDK生效(**注意.后面的空格)**: + +```sh +. /opt/openeuler/oecore-x86_64/environment-setup-aarch64-openeuler-linux +``` + +退出openEuler交互环境 + +```sh +exit +``` + + + +### 2.3 编译项目代码 + + 进入docker容器目录,切换到openEuler交互环境,用户切换为openeuler: + +```sh + cd /home/robot/hieuler/build_3403/build/sd3403 + oebuild bitbake +``` + +加载SDK(**注意.后面的空格)** + +```sh + . /opt/openeuler/oecore-x86_64/environment-setup-aarch64-openeuler-linux +``` + + 编译eulercar项目(禁止BUILD_TESTING): + +```sh +cd eulercar +colcon build --cmake-args -DBUILD_TESTING=False +``` + + 编译完成后,生成的可执行文件在install目录中,如下图: + +![image-20240827102935627](images/image-20240827102935627.png) + +退出exit cd到编译出来的install目录中,打开这个文件。 + +```sh +vi hieuler_teleop/lib/hieuler_teleop/teleop_keyboard +``` + + 修改文件第一行为: #!/usr/bin/python3 + + + + + +### 2.4 下载 + +(1)将编译生成的install目录,tar包后下载到开发板上。 + + 这里只需要将压缩包上传至windows共享目录下,再通过MobaXterm导入到欧拉派上即可 + +(2)Vmware-Ubuntu和windows设置共享目录的方法: + +1.打开虚拟机设置,右键点击虚拟机,点击设置 + +![image-20240827103404295](images/image-20240827103404295.png) + +2.选择共享文件夹选项,在设置窗口,点击“选项”标签 + +![image-20240827103535836](images/image-20240827103535836.png) + +3.添加共享文件夹的目录,自己选择一个路径即可,并把上面的文件夹共享变为“总是启用” + +4.完成虚拟机操作后,虚拟机的目录/mnt/hgfs/目录下即是和windows共享的目录,两边文件共享 + +> 如果进入虚拟机/mnt/hgfs/并没有共享文件夹,说明没有挂载成功 + +终端输入 + +```sh +sudo vmhgfs-fuse .host:/ /mnt/hgfs -o subtype=vmhgfs-fuse,allow_other +``` + +手动挂载共享目录就可以了 + + + +(3)用MobaXterm连接小车的时候,IP也许是不对的,进入Windows网络适配器,找到以太网,打开IPV4修改ip为192.168.10.8,子网掩码为255.255.255.0,修改完之后用MobaXterm Session 输入192.168.10.8,login输入root(不要输入123456),密码为ebaina@2024。登录即可使用。 + + + +(4)开发板的ubuntu环境中,修改目录名 + + + +在开发板的ubuntu环境,进入install目录,查看setup.sh: + +```sh +cd install +cat setup.sh +``` + +第十行为colcon的编译目录名, + +```sh +_colcon_prefix_chain_sh_COLCON_CURRENT_PREFIX=/home/openeuler/build/sd3403/eulercar/install +``` + +我们需要将install目录下的所有文件中,该目录名,替换为,开发板的工作目录名/root/install。 + +可以在install目录下,执行下面命令批量修改: + +```sh +find ./ -type f -exec sed -i 's@/home/openeuler/build/sd3403/eulercar/install@/root/install@g' {} + + + +``` + + + +### 2.5 运行 + +加载环境变量 + +```sh +source /etc/profile.d/ros/setup.bash +source ~/install/setup.sh + +# 打开imu节点 +$ros2 launch fdilink_ahrs ahrs_driver.launch.py +# 查看里程计 +ros2 topic echo /odom + +# 底盘节点小车打开终端窗口1 +$ros2 launch robot_bringup robot_bringup.launch.py +# 打开终端窗口2键盘控制小车 +$ros2 run hieuler_teleop teleop_keyboard +``` + + + +## 3.未来可能的改进: + +- 自动化部署与持续集成 + + **改进方向:** + + - **自动化脚本:** 编写自动化脚本,将部署过程自动化,减少手动操作的错误和时间成本。 + - **持续集成(CI):** 集成CI工具(如Jenkins、GitLab CI),实现代码提交后自动触发编译、测试和部署流程,提高开发效率和代码质量。 + + **具体措施:** + + - 编写Shell脚本或Python脚本,将下载代码、安装SDK、编译项目等步骤自动化。 + - 配置CI工具,设置触发条件(如代码提交、PR合并),自动执行编译、测试和部署流程。 + +- 提升用户体验 + + **改进方向:** + + - **图形化界面:** 开发图形化界面,简化操作流程,降低用户使用门槛。 + - **文档完善:** 完善项目文档,包括安装、配置、使用指南等,方便用户快速上手。 + - **错误提示优化:** 优化错误提示信息,提供详细的错误原因和解决方案,帮助用户快速定位和解决问题。 + + **具体措施:** + + - 使用Qt或Electron开发图形化界面,提供友好的操作界面。 + - 编写详细的README文档,包括安装步骤、配置说明、常见问题解答等。 + - 在代码中添加详细的日志输出,帮助用户和开发者快速定位问题。 + +- 夹爪功能集成 + + **改进方向:** + + - **硬件集成:** 在小车上集成夹爪硬件,确保夹爪能够稳定、可靠地工作。 + - **软件控制:** 开发软件模块,实现对夹爪的精确控制,包括夹取、释放、力度调节等功能。 + - **传感器集成:** 集成传感器(如力传感器、距离传感器),实时监测夹爪状态,确保操作的安全性和准确性。 + + **具体措施:** + + - **硬件选型与安装:** 选择适合的夹爪硬件(如电动夹爪、气动夹爪),并进行安装和调试,确保夹爪能够与小车底盘协调工作。 + - **驱动程序开发:** 开发夹爪的驱动程序,实现对夹爪的底层控制,包括电机控制、气压调节等。 + - **ROS节点开发:** 开发ROS节点,实现夹爪的ROS接口,方便与其他ROS节点进行通信和协同工作。 + - **控制算法实现:** 实现夹爪的控制算法,包括夹取力度控制、位置控制、速度控制等,确保夹爪能够精确执行任务。 + - **传感器数据处理:** 集成力传感器、距离传感器等,实时采集夹爪状态数据,并通过ROS发布相关话题,供其他节点使用。 \ No newline at end of file