1. 项目设计

嘉立创星火计划对此项目的需求如下。

项目需求

这里因为需要一个人完成软硬件的设计、开发和制作,将项目分为以下部分。

1.1 结构设计

产品设计,结构先行

结构设计软件采用工业上常用的SoildWorks软件进行设计。

综合考虑结构设计水平和开发成本,尽可能简化结构设计并控制3D打印零件数量,经过多次迭代,最终得到的结构外观如下。

结构图

结构支撑大多采用铜柱进行支撑,仅在固定摄像头出由外壳进行支撑。

因此,仅需一个3D打印外壳即可完成所有的结构工作,外壳内部效果如下图所示。

透明结构

1.2 硬件设计

PCB的硬件设计需要结合结构和软件进行考虑,将PCB共设计为两块。

PCB1:小车底盘控制板

处于成本和外壳设计难度考虑,底盘控制板即提供电机支撑,还完成了底盘的控制电路。

  1. 提供电源:锂电池、电池充电电路、电源转换电路、电源开关;
  2. 底盘控制:驱动两个N20电机进行旋转,使用常见的TB6612进行驱动;
  3. MCU控制:此处对性能和资源要求一般,采用最常用的STM32F103C8;
  4. 其他:LED状态灯、程序烧录口、通信串口。

PCB2:上位机接口扩展板

  1. 引出端口:将泰山派的通信端口引出,下位机通信串口雷达通信串口
  2. 风扇和雷达电源控制:使用IO通过三极管完成对散热风扇和雷达电源的控制。

原理图设计相对简单,参考原理图即可,开发过程中主要PCB外形和结构配合上走了些弯路,耽误了不少时间。

1.3 软件设计

根据项目需求和PCB设计,软件主要需要包含三个部分:

  1. 下位机地盘STM32程序:
    1. 通过串口接收小车电机目标旋转速度;
    2. PID控制小车电机速度按照目标速度旋转;
    3. 周期上报小车电机编码器变化数据;
    4. 长时间为收到上位机命令后停止移动,使用状态灯变化进行提示。
  2. 泰山派ROS程序:
    1. 和QT上位机通信,接收目标运行模式(手动控制模式、目标跟随模式、自动导航模式等);
    2. 根据上位机的不同命令,完成不同算法动作
      1. 手动控制模式下,接收小车速度话题;
      2. 目标跟随模式下,获取摄像头画面,识别目标位置,并计算小车所需的跟踪速度;
      3. 自动导航模式下,接收上位机发送的目标位置,将目标位置发送给导航节点,由导航节点控制小车速度进行移动。
  3. QT上位机程序:
    1. 和ROS程序进行通信,显示小车当前状态,并给小车发送目标指令。

这里上位机其实就像是一个低配的Rviz

2. 项目部署

复刻请按照以下步骤进行操作。

2.1 烧录镜像

从官方资料中下载Ubuntu20系统镜像ubuntu20.04_hdmi_20231130_update.img,并按照官方教程烧录。

镜像地址:https://wiki.lckfb.com/zh-hans/tspi-rk3566/download-center.html

烧录完成后,板子上就有Ubuntu系统了。

2.2 内核修改

需要自己编译,比较占电脑空间,开源广场资料有提供编译好的内核。

默认镜像中仅引出一个用户可以使用的串口,上位机需要的端口如下:

  • 下位机通信,串口
  • 雷达通信,串口

最基础的功能,控制下位机控制、雷达通信还差一个串口。

因此需要修改内核配置:

编译过程参考:https://wiki.lckfb.com/zh-hans/tspi-rk3566/project-case/fat-little-cell-phone/sdk-compile.html

文件需要做的修改如下:

  1. 调试串口波特率修改(非必须)

找到下面这个文件

1
tsp/kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-core-v10.dtsi

修改下面这段,把调试串口波特率从1500000修改位115200。非必须。

1
2
3
4
5
6
7
8
9
10
11
12
fiq-debugger {
compatible = "rockchip,fiq-debugger";
rockchip,serial-id = <2>;
rockchip,wake-irq = <0>;
/* If enable uart uses irq instead of fiq */
rockchip,irq-mode-enable = <1>;
rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */
interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&uart2m0_xfer>;
status = "okay";
};
  1. 添加一个串口(必须)

板子上引出的排针功能定义如下,选择一个合适的串口使用,此处使用串口5

IO引脚分配

引脚定义:https://wiki.lckfb.com/zh-hans/tspi-rk3566/documentation/io-allocation-table.html

找到下面这个文件

1
tsp/kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-user-v10-linux.dts

找到串口3的位置,将其复制一份,然后将3修改为5即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
//用户串口3
&uart3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart3m1_xfer>;
};

//用户串口5(新添加的)
&uart5 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart5m1_xfer>;
};

然后按照教程中的步骤,只编译内核,生成boot.img文件即可,然后单独将boot.img烧录进板子,烧录方法同样参考官方资料,比较简单。

烧录完成之后,板子上就的串口5就也可以用了,可以先接个串口工具试试能不能使用串口5收发数据。

2.3 空间分配

镜像烧录后,16G的EMMC空间有很大一部分都是空闲的,不能被直接使用,可用的空间还不够安装ROS的,因此需要将空闲的空间重新分配一下。

以下步骤需要将泰山派连接屏幕,下面的图片是最早的时候拍的,如果你按照我的流程生成的镜像,用户名可能不是这个。

在shell窗口中安装分配工具

1
sudo apt-get install gparted

gparted工具安装

使用下面命令启动磁盘分配工具,将磁盘oemuserdata右键取消挂载,再右键删除

1
sudo gparted

空间分配1

将删除掉的空间分配给rootfs,右键选择Resize。

空间分配2

完成之后,即可看到效果,点击对号应用即可。

空间分配3

查看磁盘空间,已分配完成。

空间分配4

2.4 安装SSH

更新包

1
sudo apt-get update

安装SSH1

安装服务

1
sudo apt-get install openssh-server

提示依赖关系不对时,提示需要哪个版本就安装哪个版本。

安装SSH2

安装完成之后,将泰山派连接一个WIFI,使用ifconfig命令查看一下板子的IP地址,并记录一下。

1
ifconfig

2.5 安装ROS

这里使用小鱼的一键安装,方便省力。

1
wget http://fishros.com/install -O fishros && bash fishros
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
lckfb@MiWiFi-R3GV2-srv:~$
lckfb@MiWiFi-R3GV2-srv:~$ wget http://fishros.com/install -O fishros && bash fishros
--2025-05-24 16:05:00-- http://fishros.com/install

# 省略一堆文字
# 等待弹出选项

ROS相关:
[1]:一键安装(推荐):ROS(支持ROS/ROS2,树莓派Jetson)
[3]:一键安装:rosdep(小鱼的rosdepc,又快又好用)
[4]:一键配置:ROS环境(快速更新ROS环境设置,自动生成环境选择)
[9]:一键安装:Cartographer(18 20测试通过,16未测. updateTime 20240125)
[11]:一键安装:ROS Docker版(支持所有版本ROS/ROS2)
[16]:一键安装:系统自带ROS (!!警告!!仅供特殊情况下使用)

常用软件:
[2]:一键安装:github桌面版(小鱼常用的github客户端)
[6]:一键安装:NodeJS环境
[7]:一键安装:VsCode开发工具
[8]:一键安装:Docker
[10]:一键安装:微信(可以在Linux上使用的微信)
[12]:一键安装:PlateformIO MicroROS开发环境(支持Fishbot)
[15]:一键安装:QQ for Linux

配置工具:
[5]:一键配置:系统源(更换系统源,支持全版本Ubuntu系统)
[13]:一键配置:python国内源
[17]:一键配置: Docker代理(支持VPN+代理服务两种模式)

[0]:quit

请输入[]内的数字以选择:1

# 输入1 选择安装ros

# 省略一堆文字
# 等待弹出选项

RUN Choose Task:[请输入括号内的数字]
新手或首次安装一定要一定要一定要换源并清理三方源,换源!!!系统默认国外源容易失败!!
[1]:更换系统源再继续安装
[2]:不更换继续安装
[0]:quit
请输入[]内的数字以选择:1
RUN Choose Task:[请输入括号内的数字]
请选择换源方式,如果不知道选什么请选2
[1]:仅更换系统源
[2]:更换系统源并清理第三方源
[0]:quit
请输入[]内的数字以选择:2

# 分别输入1、2

# 省略一堆文字
# 等待弹出选项

RUN Choose Task:[请输入括号内的数字]
请选择你要安装的ROS版本名称(请注意ROS1和ROS2区别):
[1]:foxy(ROS2)
[2]:galactic(ROS2)
[3]:noetic(ROS1)
[4]:rolling(ROS2)
[0]:quit
请输入[]内的数字以选择:3
RUN Choose Task:[请输入括号内的数字]
请选择安装的具体版本(如果不知道怎么选,请选1桌面版):
[1]:noetic(ROS1)桌面版
[2]:noetic(ROS1)基础版(小)
[0]:quit
请输入[]内的数字以选择:1

# 分别输入3、1;这里很重要安装的版本一定不要选错
# 然后开始等待

等待一段时间后,第一次提示软件包依赖不对,这里先敲回车继续。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
============================================================
请注意我,检测你在安装过程中出现依赖问题,请在稍后输入n,再选择y,即可解决(若无法解决,清在稍后手动运行命令: sudo aptitude install ros-noetic-desktop-full)
确认了解情况,请输入回车继续安装


# 第一次弹出上面的框,直接敲回车继续
# 片刻后,第一次弹出推荐方案。

是否接受该解决方案?[Y/n/q/?] n

# 输入n敲回车,拒绝第一次的方案。
# 片刻后,第二次弹出推荐方案。

是否接受该解决方案?[Y/n/q/?] Y

# 输入Y敲回车,接收第二次的方案。
# 片刻后,弹出要安装的包需要确认。

40 个软件包被升级,新安装 1025 个, 1 个将被删除, 同时 199 个将不升级。
需要获取 575 MB 的存档。 解包后将要使用 3,812 MB。
您要继续吗?[Y/n/?] Y

# 输入Y确认即可。
# 然后就是漫长漫长漫长漫长漫长漫长的等待

# 最后看到下面这句话 就安装完成了

恭喜你,安装成功了,再附赠你机器人学习宝藏网站:鱼香社区:https://fishros.org.cn/forum
Run CMD Task:[ls /opt/ros/noetic/setup.bash]
[-][0.01s] CMD Result:success

小鱼,黄黄的提示:您安装的是ROS1,可以打开一个新的终端输入roscore测试!

如果,这里第二次接受方案,然后往下走还是报错了,那就从头来,然后前两次都拒绝,第三次再接受。如果还失败,就再从头来,第四次再接受。

安装完成后,重新起一个终端,输入roscore指令,能看到如下信息,就表示ros安装完成了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
lckfb@MiWiFi-R3GV2-srv:~$ roscore
... logging to /home/lckfb/.ros/log/1647e6b0-38bd-11f0-b3d3-b81332af56be/roslaunch-MiWiFi-R3GV2-srv-16753.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://MiWiFi-R3GV2-srv:35197/
ros_comm version 1.17.3


SUMMARY
========

PARAMETERS
* /rosdistro: noetic
* /rosversion: 1.17.3

NODES

auto-starting new master
process[master]: started with pid [16761]
ROS_MASTER_URI=http://MiWiFi-R3GV2-srv:11311/

setting /run_id to 1647e6b0-38bd-11f0-b3d3-b81332af56be
process[rosout-1]: started with pid [16771]
started core service [/rosout]

2.7 权限设置

2.7.1 串口权限

两个串口/dev/ttyS3/dev/ttyS5使用普通用户登录默认都是没有操作权限的,在代码里不方便操作。

因此这里永久修改一下权限。

1
2
# 创建udev规则文件
sudo vi /etc/udev/rules.d/99-serial-ports.rules

添加以下内容

1
2
KERNEL=="ttyS3", MODE="0666"
KERNEL=="ttyS5", MODE="0666"

添加完成后重新加载

1
2
3
4
5
6
# 重新加载udev规则
sudo udevadm control --reload-rules
sudo udevadm trigger

# 或者重启系统使规则生效
sudo reboot

查看串口权限,可以看到有读写权限了

1
2
3
4
lckfb@MiWiFi-R3GV2-srv:~/ros1-car-ws$ ls -l /dev/ttyS5
crw-rw-rw- 1 root dialout 4, 69 11月 28 14:21 /dev/ttyS5
lckfb@MiWiFi-R3GV2-srv:~/ros1-car-ws$ ls -l /dev/ttyS3
crw-rw-rw- 1 root dialout 4, 67 11月 28 14:21 /dev/ttyS3

2.7.2 IO引脚

风扇和雷达供电控制引脚上电后默认也是没有操作权限的。

1
2
3
4
lckfb@MiWiFi-R3GV2-srv:~$ echo 36 > /sys/class/gpio/export
-bash: /sys/class/gpio/export: 权限不够
lckfb@MiWiFi-R3GV2-srv:~$ sudo echo 36 > /sys/class/gpio/export
-bash: /sys/class/gpio/export: 权限不够

ubuntu下没找到好的解决办法,创建一个脚本,运行ros程序前执行一下吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

# 脚本名称: setup_gpio_permissions.sh
# 功能:导出指定 GPIO 并赋予当前用户读写权限

GPIOs=(36 98)

for gpio in "${GPIOs[@]}"; do
echo "尝试导出 GPIO $gpio..."

# 导出 GPIO(如果尚未导出)
if [ ! -d "/sys/class/gpio/gpio$gpio" ]; then
echo $gpio > /sys/class/gpio/export 2>/dev/null || {
echo "无法导出 GPIO $gpio,请以 root 运行此脚本。"
exit 1
}
fi

# 设置 direction 和 value 的权限(允许所有用户读写)
chmod 666 "/sys/class/gpio/gpio$gpio/direction" 2>/dev/null
chmod 666 "/sys/class/gpio/gpio$gpio/value" 2>/dev/null

# 如果存在 active_low,也设置权限
[ -f "/sys/class/gpio/gpio$gpio/active_low" ] && chmod 666 "/sys/class/gpio/gpio$gpio/active_low"

echo "GPIO $gpio 已导出并设置权限。"
done

echo "完成!现在普通用户可以操作 GPIO 36 和 98。"

执行方法为

1
2
3
4
5
6
7
# 添加执行权限
sudo chmod 777 setup_gpio_permissions.sh

# 执行
sudo ./setup_gpio_permissions.sh

# 之后再启动ros程序

2.7.3 摄像头权限

执行以下命令,重启生效。

1
2
3
4
5
# 添加权限
sudo usermod -aG video $USER

# 或者重启系统使规则生效
sudo reboot

重启完成之后,执行以下命令,看到有video输出即表示成功。

1
2
lckfb@MiWiFi-R3GV2-srv:~$ groups
lckfb sudo audio video

2.8 硬件组装

这里硬件和结构相对来说简单,因此可以在软件编译完成后再进行硬件组装。

组装教程参考B站视频。

组装视频:https://space.bilibili.com/330622220

2.9 软件部署

下载程序

1
git clone https://gitee.com/imhaozi/TspRosCar.git
  1. 切换到Base分支,使用Keil开发,编译后烧录到底盘STM32中;
  2. 切换到TspWs分支,并将程序复制到泰山派中编译并运行;
    1. 运行程序前首先执行以下IO权限设置的脚本,否则无法正常打开雷达
    2. 程序中依赖多个软件包,分别安装即可
      1. 地图加载和保存:sudo apt install ros-noetic-map-server
      2. 建图:sudo apt install ros-noetic-gmapping
      3. 自动探索建图:sudo apt install ros-noetic-explore-lite
      4. 导航:sudo apt-get install ros-noetic-navigation
      5. websocket通信:sudo apt install ros-noetic-rosbridge-suite
    3. 运行命令如下roslaunch launch_pkg all.launch
  3. 切换到App分支,使用QT打开并运行(也可以直接运行打包好的上位机);

泰山派和运行上位机的电脑需要在一个网络下运行。

3. 开发笔记

以下内容为学习过程中的一些记录罢了。

3.1 创建项目

创建一个工作空间文件夹(就是一个工程文件夹)

  1. 工作空间中可以有多个软件包
  2. 软件包中又可以又多个节点

步骤1:创建工作空间

比如这里想创建一个小车项目,就可以创建下面的文件目录

  • Ros1CarWs
    • src:存放代码,源代码、功能包等

创建一个Ros1CarWs目录作为本项目的工作空间。

1
2
3
haozi@computer:~/develop$ mkdir Ros1CarWs
haozi@computer:~/develop$ cd Ros1CarWs/
haozi@computer:~/develop/Ros1CarWs$ mkdir src

步骤2:创建软件包

在工作空间的src目录下可以有多个软件包。

因此需要在src目录下进行创建,切换到工作空间的src目录下,执行如下格式指令:

1
catkin_create_pkg 包名 <依赖项1> <依赖项2> ...

比如,创建一个名叫test_pkg的包,指令如下:

1
haozi@computer:~/develop/Ros1CarWs/src$ catkin_create_pkg test_pkg rospy roscpp std_msgs

执行完成后,在src目录下就会多出一个新的目录test_pkg,该目录就是一个包了,包里面又包含了多个文件。

1
2
3
4
5
haozi@computer:~/develop/Ros1CarWs/src$ ls
CMakeLists.txt test_pkg wpr_simulation
haozi@computer:~/develop/Ros1CarWs/src$ cd test_pkg/
haozi@computer:~/develop/Ros1CarWs/src/test_pkg$ ls
CMakeLists.txt include package.xml src

步骤3:添加节点代码

在软件包的src目录下创建代码文件main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <ros/ros.h>

int main(int argc, char *argv[])
{
printf("test_pkg running~ \n");

// 后面的是节点名称
ros::init(argc, argv, "test_node");

while(ros::ok())
{
printf("test_node running~ \n");
sleep(1);
}
return 0;
}

在这个包的CMakeLists.txt文件中,build部分,找到对应的注释的位置,添加如下两条(没注释掉的是添加的,注释掉的是原有的)。

1
2
3
4
5
6
7
8
9
10
11
12
13
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/test_pkg_node.cpp)
add_executable(test_node src/main.cpp)

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
target_link_libraries(test_node
${catkin_LIBRARIES}
)

其中:

  • add_executable:表示需要编译可执行文件
  • target_link_libraries:表示需要链接ros库

步骤4:编译代码

在工作空间目录Ros1CarWs下执行编译命令

1
2
3
4
5
haozi@computer:~/develop/Ros1CarWs$ pwd
/home/haozi/develop/Ros1CarWs
haozi@computer:~/develop/Ros1CarWs$ catkin_make
[100%] Linking CXX executable /home/haozi/develop/Ros1CarWs/devel/lib/test_pkg/test_node
[100%] Built target test_node

编译完成后,工作空间下就会多出来两个文件夹,build、devel

1
2
haozi@computer:~/develop/Ros1CarWs$ ls
build devel src
  • build:编译文件
  • devel:执行文件,执行前需要在这里添加源

步骤5:执行

启动一个新的终端,启动ros

1
roscore

添加代码源(注意相对目录或者绝对目录)

1
haozi@computer:~/develop/Ros1CarWs$ source devel/setup.bash

执行代码

1
2
3
4
5
6
# 命令格式:rosrun 包名 节点名
haozi@computer:~/develop/Ros1CarWs$ rosrun test_pkg test_node
test_pkg running~
test_node running~
test_node running~
test_node running~

到这里,创建一个ros软件包并执行的流程就完成了。

还可以继续重复步骤2-5,就可以创建多个不同的软件包了。

步骤6:优化

每次打开终端总要source一下,可以修改配置,打开终端时自动source。

执行如下指令

1
haozi@computer:~$ gedit ~/.bashrc

在弹出的编辑器中,最后一行添加如下内容。

1
source ~/Ros1CarWs/devel/setup.bash

这样每次打开终端,就会自动执行这一行命令了。

不过这里我还是不用了。

3.2 电脑端可视化

开发过程中,需要调试时,小车主控不具有可视化能力,需要借用电脑来进行可视化操作。

步骤1:

虚拟机网络设置为桥接模式(这样开发板和虚拟机才可以在一个网段下)

步骤2:

将电脑和开发板连接同一个wifi

步骤3:

查看电脑端和开发板IP地址和设备名

1
hostname

结果:

  • 虚拟机
    • 主机名:computer
    • IP:192.168.31.28
  • 开发板
    • 主机名:MiWiFi-R3GV2-srv
    • IP:192.168.31.35

步骤4:

编辑/etc/hosts文件,添加一行,添加对方的IP和主机名

开发板端

1
192.168.31.28    computer

电脑端

1
192.168.31.35    MiWiFi-R3GV2-srv

设置完成之后,分别ping对方的ip和主机名,应该都是可以ping通的。

步骤5:

这里将开发板作为ROS主机使用。编辑~/.bashrc文件,添加几行。

开发板端

1
2
3
4
5
6
# ROS网络配置
export ROS_MASTER_URI=http://MiWiFi-R3GV2-srv:11311
export ROS_HOSTNAME=MiWiFi-R3GV2-srv

# 执行source
source ~/.bashrc

电脑端

1
2
3
4
5
# ROS网络配置
export ROS_MASTER_URI=http://MiWiFi-R3GV2-srv:11311
export ROS_HOSTNAME=computer
# 执行source
source ~/.bashrc

然后在开发板端运行roscore及其他服务,在电脑端就可以使用相关命令看到状态了。

也可以直接将上面两行写入到这个文件,就不用每次打开终端都需要重新导入了。

3.3 常用命令

软件包

1
2
3
4
5
6
# 创建软件包
catkin_create_pkg pkg_name rospy roscpp std_msgs

# launch启动
# roslaunch <包名> <launch文件名>
roslaunch launch_pkg all.launch

节点相关

1
2
3
4
5
# 查看节点图关系
rqt_graph

# 查看tf树
rosrun rqt_tf_tree rqt_tf_tree

话题相关

1
2
3
4
5
6
7
8
# 查看当前存在的话题
rostopic list

# 查看话题的订阅者和发布者
rostopic info /cmd_vel

# 查看实时消息内容
rostopic echo /cmd_vel

工具节点

1
2
# 运行速度控制器
rosrun rqt_robot_steering rqt_robot_steering

里程计数据可视化

里程计可视化

雷达数据可视化

雷达可视化

建图可视化

建图可视化

3.4 TF系统

使用以下命令查看TF树

1
rosrun rqt_tf_tree rqt_tf_tree

效果如下

TF树1

TF(TransForm,坐标变换系),主要搞清楚几个坐标系之间的关系。

地图坐标系

地图坐标系/map,最根本的坐标系,坐标系原点从建图开始就固定不动了。

  • 原点:在机器人建图时候的初始位置
  • 方向:遵循右手法则,正前方为X,正左方为Y,正上方为Z

机器人坐标系

机器人坐标系base_footprint,坐标系原点永远跟随机器人移动。

  • 原点:在机器人地面投影的正中心
  • 方向:遵循右手法则,机器人的正前方为X,机器人正左方为Y,机器人正上方为Z

为了描述机器人在地图中的位置,把地图坐标系作为父坐标系,机器人坐标系作为子坐标系。

只需要六个值就可以表示机器人在地图中的位置:

  1. 机器人坐标系在地图坐标系中,xyz三个方向上距离的偏差
  2. 机器人坐标系在地图坐标系中,xyz三个方向上角度的偏差

对于小车来说,不可能在空中,所以z方向距离永远为0,不会向前或者向后倒,所以xy方向的角度永远为0。


有了这两个坐标系,就可以使用雷达进行建图了,雷达建图使用的就是这两个坐标系之间的转换关系。

3.5 地图保存和加载

当建图完成之后,需要把这个地图保存起来,下次启动直接调用即可。

3.5.1 地图保存

软件包安装命令如下。会报某些软件包依赖不对的错误,根据提示补充相关依赖即可。

1
sudo apt install ros-noetic-map-server

安装完成后,先使用建图软件包完成建图,保持建图程序不要关闭。

运行地图保存程序

1
rosrun map_server map_saver -f <文件名>

如果只有一个文件名就是当前终端的路径,这里使用绝对路径

需要先创建/home/lckfb/TspRosCar/RosCarWs/src/map_config/home这个文件夹,否则会保存失败

1
rosrun map_server map_saver -f /home/lckfb/TspRosCar/RosCarWs/src/map_config/home/home_map

运行结果如下

1
2
3
4
5
6
7
8
9
10
lckfb@MiWiFi-R3GV2-srv:~/TspRosCar/RosCarWs$ rosrun map_server map_saver -f /home/lckfb/TspRosCar/RosCarWs/src/map_config/home/home_map
[INFO] [1764853848.865978437]: Waiting for the map
[INFO] [1764853849.171315087]: Received a 4000 X 4000 map @ 0.050 m/pix
[INFO] [1764853849.171582836]: Writing map occupancy data to /home/lckfb/TspRosCar/RosCarWs/src/map_config/home/home_map.pgm
[INFO] [1764853850.342584721]: Writing map occupancy data to /home/lckfb/TspRosCar/RosCarWs/src/map_config/home/home_map.yaml
[INFO] [1764853850.343969550]: Done

lckfb@MiWiFi-R3GV2-srv:~/TspRosCar/RosCarWs/src/map_config$ cd /home/lckfb/TspRosCar/RosCarWs/src/map_config/home
lckfb@MiWiFi-R3GV2-srv:~/TspRosCar/RosCarWs/src/map_config/home$ ls
home_map.pgm home_map.yaml

得到两个文件,两个文件共同组成了一个地图数据。

  • home_map.pgm:一张图片的格式
  • home_map.yaml:描述了这个图片的信息,比如每个像素点对应的实际大小、起始点等信息

3.5.2 地图加载

地图加载完成后,关闭建图节点,只运行一个roscore即可。

运行之后,查看当前ros存在的话题是找不到/map

1
rostopic list

然后运行以下命令加载地图(只需要yaml文件即可,文件中有对应的地图图片的名字)

1
rosrun map_server map_server <地图名.yaml>

同样的这里使用绝对路径

1
rosrun map_server map_server /home/lckfb/TspRosCar/RosCarWs/src/map_config/home/home_map.yaml

加载完成之后就有地图话题了,在rviz中可以看到发布的地图。

3.6 通信支持包

我们的上位机中肯定是无法直接运行ros来和小车进行通信的,可以使用网络通信获取ros中的消息内容。

在小车中需要一个将Ros消息和网络消息转换的东西(有现成的)。

将ROS环境的运行信息进行上报需要软件包rosbridge_server,安装命令如下

1
sudo apt install ros-noetic-rosbridge-suite

和其他的软件包一样,最后把这个软件包也启动起来即可。

1
roslaunch rosbridge_server rosbridge_websocket.launch