开发板 A6490PM1 上通过ROS2-humble在RVIZ与Gazebo中完成智能小车的仿真
对开发板 A6490PM1 进行刷机操作并安装Aidlux
具体过程见以下网址
刷机教程:http://192.168.110.201:36666/guide/hardware/development-board/A6490PM1-user-manual
使用VNC完成远程连接,进入ubantu
22.04系统,并安装ROS2-humble
完成刷机及aidlux的安装后,根据教程获得手中开发板的ip
地址后在浏览器上通过ip:8000
进入aidlux
桌面系统,密码为aidlux
,桌面系统如下所示,
点击桌面底部的应用中心图标
进入应用中心后点击顶部的机器人选项,下载ubantu Desktop
,安装完成后打开该应用,通过获得的ip
地址和端口号通过VNC
进行远程连接进入ubantu系统。
ROS2-humble、RVIZ、gazebo
等软件的下载
ros2-humble、gazebo
可通过aidlux桌面系统的应用中心下载,也可在ubantu
系统中完成安装
ubantu
中ros2-humble、
gazebo、vescode的安装过程如下所示
ros2-humble
我们可以通过国内大佬小鱼开发的一键安装完成安装,感谢小鱼的一键安装。
通过按住键盘上的ctrl+alt+t
打开终端,在终端中输入以下命令,密码为aidlux
wget http://fishros.com/install -O fishros && . fishros
这里我们输入1(安装ROS
),按下回车
如上图所示,首先输入1(更换系统源再继续安装)并按下回车,接着继续选择1(仅更换系统源)并按下回车,接着就可以看见安装ROS
相关选项,这里可以选择要安装的humble版本,我们按下1选择humble
版本,然后再按下1(选择桌面版)并按下回车,接着等待安装工具自动完成ros
的安装
vscode
及微信等软件也可通过以上同样的方法安装
gazebo
的安装我们也通过命令行完成安装,在一个新的终端中我们输入以下命令
sudo apt install gazebo
除了安装gazebo
外,也可以下载一些模型文件到系统的gazebo
配置目录下,文件可以直接从github
上克隆,命令如下所示
$ mkdir -p ~/.gazebo
$ cd ~/.gazebo
$ git clone https://gitee.com/ohhuo/gazebo_models.git ~/.gazebo/models
$ rm -rf ~/.gazebo/models/.git #删除 .git 防止误识别为模型
启动gazebo的命令如下所示
gazebo
一些其他工具的安装
colcon构建工具
colcon是一个命令行工具,用于改进编译,测试和使用多个软件包的工作流程。它实现过程自动化,处理需求并设置环境以便于使用软件包。ROS2中便是使用colcon作为包构建工具的,但是ROS2中没有默认安装colcon,需要自行安装,安装命令如下:
sudo apt install python3-colcon-common-extensions
使用URDF文件完成小车建模,并在RVIZ中完成可视化显示
以下内容的代码均来自以下gitee仓库
chapt(1)/chapt/src/moxing/urdf/second.urdf.xacro · lenxiii/test - 码云 - 开源中国 (gitee.com)
使用gazebo
仿真的第一步是完成对机器人的建模,目前几乎所有的仿真平台都支持URDF格式,使用URDF文件可以通过代码描述模型的外形物理体积,运动惯性,物理属性,运动限制等內容。RVIZ可以将以URDF编写的小车模型描述文件进行可视化处理,以下内容为一个使用URDF格式编写的机器人模型示例部分文件,文件名为second.urdf.xacro
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="first_robot">
<!--机器人模型身体部分 -->
<link name="base_link">
<!--部件外观描述-->
<visual >
<!--沿自己几何中心的坐标偏移和旋转-->
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
<!--几何形状-->
<geometry>
<!--圆柱体 半径0.1m 高0.112m-->
<cylinder radius="0.1" length="0.12"/>
</geometry>
<!--材质标签 颜色白色 透明度为0.5-->
<material name="white">
<color rgba="1.0 1.0 1.0 0.5"/>
</material>
</visual>
</link>
<!--机器人模型轮子部分-->
<!--机器人模型左边轮子部分-->
<link name="left_wheel_link">
<visual>
<origin xyz="0.0 0.0 0.0" rpy="1.57079 0 0"/>
<geometry>
<!--圆柱体 半径0.04m 高0.032m-->
<cylinder radius="0.04" length="0.032"/>
</geometry>
<material name="black">
<color rgba="0.0 0.0 0.0 0.5""/>
</material>
</visual>
</link>
<!--机器人模型右边轮子部分-->
<link name="right_wheel_link">
<visual>
<origin xyz="0 0 0" rpy="1.57079 0 0" />
<geometry>
<cylinder length="0.04" radius="0.032" />
</geometry>
<material name="black">
<color rgba="0.0 0.0 0.0 0.8"/>
</material>
</visual>
<!--机器人模型关节部分-->
<joint name="lift_joint" type="revolute">
<!--子部件相当于父部件的平移和旋转-->
<origin xyz="0 0.10 -0.06" rpy="0.0 0.0 0.0"/>
<!--父部件(子部件连接的部件)-->
<parent link="base_link"/>
<!--子部件-->
<child link="left_wheel_link"/>
<!--定义旋转轴方向,绕y轴旋转-->
<axis xyz="0.0 1.0 0.0"/>
<!--对关节的运动限制 lower(最小角度) upper(最大角度) effort(最大扭矩) velocity(最大速度)-->
<limit lower="0.0" upper="0.0" effort="0.0" velocity="0.0"/>
</joint>
<joint name="right_wheel_joint" type="continuous">
<parent link="base_link" />
<child link="right_wheel_link" />
<origin xyz="0 -0.10 -0.06" />
<axis xyz="0 1 0" />
</joint>
</robot>
第一行<?xml version="1.0"?>
表示这是一个 XML 处理指令的开始,XML 的版本号为 1.0,URDF
使用XML
(Extensible Markup Language
可扩展标记语言)描述机器人的几何结构,传感器等信息。
第二至第三行中包含了三段不同含义的代码<robot>
及</robot>
是URDF
或XACRO
文件的根元素,用于描述机器人模型,所有的URDF
文件几乎都要写在这对标签当中。
name="first_robot
"定义了机器人的名称(first_robot
),在ROS
中用于标识该模型。
xmlns:xacro="http://www.ros.org/wiki/xacro
这句话声明了一个XML
命名空间,关联到XACRO
的官方文档页面。作用是告诉解析器该文件使用了Xacro
的宏功能(如变量、循环、条件等),而不仅是普通URDF
。简单来说URDF
文件中引入Xacro
后便可以使用xacro
编写宏,使机器人的建模更加简便由于篇幅原因本文对于Xacro
版本的URDF
文件不做过多介绍。
编写完成的URDF
文件通过使用launch
文件完成在RVIZ
中的启动,launch
文件示例如下
# 导入必要的ROS 2启动模块和功能包
from launch import LaunchDescription
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
from launch.actions import DeclareLaunchArgument
from launch.substitutions import Command,LaunchConfiguration
import os
from ament_index_python.packages import get_package_share_directory
def generate_launch_description():
# 声明一个启动参数,用于指定URDF文件的路径
# 默认路径为moxing功能包下的urdf/first.urdf.xacro文件
model_path=DeclareLaunchArgument(
name='model',default_value=
os.path.join(get_package_share_directory
("moxing"),"urdf","first.urdf.xacro"),
description="URDF文件路径"
)
# 使用xacro工具解析URDF文件,生成机器人描述参数
robot_description=ParameterValue(Command(["xacro ",LaunchConfiguration("model")]))
# 创建joint_state_publisher_gui节点,用于发布关节状态并提供GUI界面
joint_state_publisher_gui = Node(
package="joint_state_publisher_gui",
executable="joint_state_publisher_gui",
parameters=[{"robot_description": robot_description}], # 直接传递参数
)
# 创建robot_state_publisher节点,用于发布机器人状态
robot_state_publisher = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
parameters=[{"robot_description": robot_description}],
output="screen", # 可选:打印调试信息
)
# 创建rviz2节点,用于可视化机器人模型
rviz2_node=Node(
package="rviz2",
executable="rviz2",
name="rviz2",
output="screen",
)
# 返回LaunchDescription对象,包含所有声明的节点和参数
return LaunchDescription(
[
# 声明一个启动参数,用于指定是否使用仿真时间(如Gazebo)
DeclareLaunchArgument(
"use_sim_time",
default_value="false",
description="Use simulation (Gazebo) clock if true",
),
model_path,# 添加URDF文件路径参数
robot_state_publisher,# 添加机器人状态发布节点
joint_state_publisher_gui,# 添加关节状态发布GUI节点
rviz2_node,# 添加RViz2可视化节点
]
)
启动后RVIZ
会自动启动如下图所示
此时的RVIZ
中没有任何模型是正常的,接下来点击左下角的add
按钮在弹出的窗口中选择robotmodel
选项
随后在左侧的robotmodel
的选项中将Description Source
的选项选为Topic
,其次在下面的Description Topic
中选择/robot_description
完成以上操作后便可以在RVIZ
的中间看见一块白色物体,这是正常现象
在RVIZ
左侧边框的最上方有一个Fixed Frame
的选项,在其中选择你在URDf
文件中建立的任意一个link
部件便可以正常显示URDf
建立的机器人模型,完成以上操作后也可以加入add
模块,添加方式与robotmodel
一致,添加完成后,你便可以看见各个link
部件的坐标轴
以上便是在RVIZ
中显示URDF
描述的机器人模型的步骤,接下来我们将会把机器人模型加入到gazebo
仿真世界中
将机器人模型放入自定义gazebo
仿真世界中
使用gazebo
构建世界
在终端中输入gazebo
启动的gazebo
界面如图所示,启动后的gazebo
世界默认加载空世界,界面如图所示
我们可以通过界面左上角的insert
向空世界中加入之前在github
上克隆的模型
除了可以使用已经加载好的模型,在gazebo
中也可以实现手动画墙,设计自己的房间,接下来我们就来设计一个房间。
首先在gazebo
左上角的edit
的选项中点击Building Editor
简单的完成了一个封闭房间的设计后在左上角的file
中选择Exit Building Editor
选项会弹出如下窗口提示是否保存墙体文件,我们点击save and Exit
选项
点击之后会弹出如下界面
定义世界的名称,并选择保存的文件地址完成后点击choose
,最后点击save
即可在gazebo
界面中看见建好的房间模型。
同样,我们也可以在建好的房间模型中加入一些其他的模型,完成后便可以在file
的save world as
选项将我们的世界模型保存下下来,下次使用gazebo
命令加世界路径便可以直接加载世界模型
在gazebo
中加载机器人模型
gazebo
使用的是sdf
格式,而机器人建模时使用的是URDF
格式,所以要在gazebo
中显示机器人模型就需要将urdf
文件转换为sdf
我们可以通过gazebo-ros-pkgs
完成这一转换,安装命令如下
$ sudo apt install ros-humbl-gazebo-ros-pkg
安装好后使用以下launch
文件启动gazebo
并加载机器人模型
from launch import LaunchDescription
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
from launch.actions import DeclareLaunchArgument
from launch.substitutions import Command, LaunchConfiguration
import os
from ament_index_python.packages import get_package_share_directory
import launch
from launch.launch_description_sources import PythonLaunchDescriptionSource
import launch_ros
def generate_launch_description():
# 声明一个启动参数 `model`,用于指定URDF/Xacro文件路径
# 默认值为包 `moxing` 中 `urdf/second.urdf.xacro` 文件的路径
model_path = DeclareLaunchArgument(
name="model",
default_value=os.path.join(
get_package_share_directory("moxing"),
"urdf",
"second.urdf.xacro"
),
description="URDF 文件路径",
)
# 设置Gazebo世界文件的默认路径
# 路径指向包 `moxing` 中 `world/room1.world` 文件
default_world_path = os.path.join(
get_package_share_directory("moxing"),
"world",
"room1.world"
)
# 启动Gazebo仿真环境
# 使用 `gazebo_ros` 包的 `gazebo.launch.py` 启动文件
# 并传入世界文件路径 (`room1.world`) 和设置 `verbose` 为 `true`(输出详细日志)
gazebo_launch = launch.actions.IncludeLaunchDescription(
PythonLaunchDescriptionSource([get_package_share_directory(
"gazebo_ros"), '/launch', '/gazebo.launch.py']
),
launch_arguments=[('world', default_world_path), ('verbose', 'true')]
)
# 在Gazebo中生成机器人模型
# 使用 `gazebo_ros` 包的 `spawn_entity.py` 节点
# 参数:
# `-topic /robot_description`:从 `/robot_description` 话题获取机器人URDF
# `-entity robot1`:在Gazebo中生成的实体名称
spawn_action = launch_ros.actions.Node(
package="gazebo_ros",
executable="spawn_entity.py",
arguments=['-topic', '/robot_description', '-entity', 'robot1']
)
# 解析Xacro文件生成URDF描述
# 使用 `xacro` 命令处理 `model` 参数指定的文件
# 结果存储在 `robot_description` 中,类型为字符串
robot_description = ParameterValue(
Command(["xacro ", LaunchConfiguration("model")]),
value_type=str
)
# 启动 `robot_state_publisher` 节点
# 该节点发布机器人的TF(Transform)信息
# 参数:
# `source_list: ["/joint_states"]`:订阅Gazebo发布的关节状态
# `robot_description`:传入解析后的URDF描述
robot_state_publisher = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
parameters=[{
"source_list": ["/joint_states"], # 确保订阅 Gazebo 的关节数据
"robot_description": robot_description
}],
output="screen", # 输出日志到屏幕
)
# 启动 `joint_state_publisher_gui` 节点(GUI版本)
# 提供一个可视化界面,用于手动调整关节状态(如调试用)
joint_state_publisher_gui = Node(
package="joint_state_publisher",
executable="joint_state_publisher",
name="joint_state_publisher_gui", # 节点名称
)
# 启动RViz2可视化工具
# 加载包 `moxing` 中 `rviz/model.rviz` 的配置文件
rviz2_node = Node(
package="rviz2",
executable="rviz2",
name="rviz2",
output="screen",
arguments=['-d', os.path.join(
get_package_share_directory("moxing"),
'rviz', 'model.rviz'
)]
)
# 返回所有要启动的节点和动作
return launch.LaunchDescription([
model_path, # 声明模型路径参数
robot_state_publisher, # 发布机器人TF
joint_state_publisher_gui, # 关节状态发布(GUI)
gazebo_launch, # 启动Gazebo
spawn_action, # 在Gazebo中生成机器人
# 注意:`rviz2_node` 当前被注释掉,如需使用需取消注释
])
接着便可以在gazebo
的世界中我们的机器人模型已经放入世界了
在URDF
文件中除了描述机器人模型的外观也可以使用gazebo
插件模拟传感器的工作,例如IMU
和雷达。
以上便是如何在开发板 A6490PM1 上通过ROS2-humble在RVIZ与Gazebo中完成智能小车的仿真的全部内容