1.创建环境部分(gazebo)
1.1 建一个新的工作区
ros2 pkg create box_bot_gazebo --build-type ament_cmake
创建launch 、models和 worlds文件夹,删除src和include
1.2 launch部分
此部分包括1.启动gazebo方针环境 2.导入worlds 3.导入机器人
这里直接把现成的代码复制进去。
1.3 worlds部分
启动的gazebo环境
复制代码
1.4 models部分
包含了 gazebo中添加的各种物体的模型,编译之后,需要导入.bashrc中,Gazebo plugin
复制代码
1.5 CMakeLists.txt
编译的准则。(要添加依赖、添加安装位置)
添加两部分:
第一部分:
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
find_package(ament_cmake REQUIRED)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
# Skip if Gazebo not present
find_package(gazebo QUIET)
if(NOT gazebo_FOUND)
message(WARNING "Gazebo not found, proceeding without that simulator.")
return()
endif()
添加依赖(rclcpp、rclpy)还有gazebo!至于为什么是这三个?
第二部分:
install(
DIRECTORY
launch
worlds
models
DESTINATION
share/${PROJECT_NAME}/
)
install(
PROGRAMS
launch/robot_description_publisher.py
DESTINATION lib/${PROJECT_NAME}
)
1.第一个 install(DIRECTORY … DESTINATION share/
P
R
O
J
E
C
T
N
A
M
E
/
)
将
编
译
后
的
文
件
(
l
a
u
n
c
h
、
w
o
r
l
d
s
、
m
o
d
e
l
s
文
件
夹
内
的
)
下
载
到
指
定
文
件
夹
中
。
2.
第
二
个
i
n
s
t
a
l
l
(
P
R
O
G
R
A
M
S
.
.
.
.
D
E
S
T
I
N
A
T
I
O
N
l
i
b
/
{PROJECT_NAME}/)将编译后的文件(launch、worlds、models文件夹内的)下载到指定文件夹中。 2.第二个install (PROGRAMS ....DESTINATION lib/
PROJECTNAME/)将编译后的文件(launch、worlds、models文件夹内的)下载到指定文件夹中。2.第二个install(PROGRAMS....DESTINATIONlib/{PROJECT_NAME})将编译后的文件(launch文件夹内)下载到指定文件夹内。(launch文件被下载了两次)
所有:
cmake_minimum_required(VERSION 3.8)
project(box_bot_gazebo)
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(<dependency> REQUIRED)
find_package(ament_cmake REQUIRED)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclpy REQUIRED)
# Skip if Gazebo not present
find_package(gazebo QUIET)
if(NOT gazebo_FOUND)
message(WARNING "Gazebo not found, proceeding without that simulator.")
return()
endif()
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
install(
DIRECTORY
launch
worlds
models
DESTINATION
share/${PROJECT_NAME}/
)
install(
PROGRAMS
launch/robot_description_publisher.py
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
1.6 package.xml部分
编译所用到的包
1.
<depend>ament_cmake</depend>
<depend>rclcpp</depend>
<depend>rclpy</depend>
<depend>gazebo_ros</depend>
至于为什么这四个
ament_cmake:用于编译
rclcpp:程序需要c++编译器
rclpy:程序需要python编译器
gazebo_ros:程序需要gazebo_ros编译器
2.
<exec_depend>gazebo_ros_pkgs</exec_depend>
<exec_depend>ros2launch</exec_depend>
至于为什么这两个
gazebo_ros_pkgs:只要启动gazebo就要用这个
ros2launch:用于启动launch文件
2.创建机器人部分(robot)
2.1 创建一个新的分区
ros2 pkg create box_bot_description --build-type ament_cmake
删除src和include,添加robot和meshes、rviz文件夹
meshes通常存储功能、逻辑实现部分,这里指robot的逻辑功能,所以models里也可以有meshes文件夹。
2.2 为robot文件夹添加内容
此文件夹就是要包含机器人的各个部位等情况。复制代码进来
3.解读代码(核心)
3.1 box_bot.launch.py
这是本历程要启动的程序
#!/usr/bin/python3
# -*- coding: utf-8 -*-
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
def generate_launch_description():
pkg_box_bot_gazebo = get_package_share_directory('box_bot_gazebo')
# Sart World
start_world = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_box_bot_gazebo, 'launch',
'start_world_launch.py'),
)
)
spawn_robot_world = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_box_bot_gazebo, 'launch',
'spawn_robot_ros2.launch.py'),
)
)
start_rviz = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_box_bot_gazebo, 'launch', 'start_rviz.launch.py'),
)
)
return LaunchDescription([
start_world,
spawn_robot_world,
start_rviz
])
这里启动了三个文件:1.start_world_launch.py 2.spawn_robot_ros2.launch.py
3.start_rviz.launch.py
3.1.1 start_world_launch.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
pkg_box_bot_gazebo = get_package_share_directory('box_bot_gazebo')
# Set the path to the WORLD model files.
gazebo_models_path = os.path.join(pkg_box_bot_gazebo, 'models')
os.environ["GAZEBO_MODEL_PATH"] = gazebo_models_path
print("GAZEBO MODELS PATH=="+str(os.environ["GAZEBO_MODEL_PATH"]))
# Gazebo launch
gazebo = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py'),
)
)
return LaunchDescription([
DeclareLaunchArgument(
'world',
default_value=[os.path.join(pkg_box_bot_gazebo, 'worlds', 'box_bot_box_room.world'), ''],
description='SDF world file'),
gazebo
])
首先启动系统的gazebo.launch.py文件,再加载world文件(就在worlds里面)。
3.1.2 spawn_robot_ros2.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
import xacro
import random
# this is the function launch system will look for
def generate_launch_description():
####### DATA INPUT ##########
urdf_file = 'box_bot_gen.urdf'
xacro_file = "box_bot_with_meshes.xacro"
#xacro_file = "box_bot.xacro"
package_description = "box_bot_description"
use_urdf = False
# Position and orientation
# [X, Y, Z]
position = [0.73, -0.39, 0.5]
# [Roll, Pitch, Yaw]
orientation = [0.0, 0.0, 0.0]
# Base Name or robot
robot_base_name = "box_bot"
####### DATA INPUT END ##########
if use_urdf:
# print("URDF URDF URDF URDF URDF URDF URDF URDF URDF URDF URDF ==>")
robot_desc_path = os.path.join(get_package_share_directory(
package_description), "robot", urdf_file)
else:
# print("XACRO XACRO XACRO XACRO XACRO XACRO XACRO XACRO XACRO XACRO XACRO ==>")
robot_desc_path = os.path.join(get_package_share_directory(
package_description), "robot", xacro_file)
#进入box_bot_description/robot文件夹,对box_bot_with_meshes.xacro文件进行编译整合处理
robot_desc = xacro.process_file(robot_desc_path) #使用python对xacro文件进行处理
xml = robot_desc.toxml() #然后将其字符串化....
entity_name = robot_base_name+"-"+str(random.random())
# Spawn ROBOT Set Gazebo
spawn_robot = Node(
package='gazebo_ros', #gazebo官方文件夹,用于加入机器人
executable='spawn_entity.py',
name='spawn_entity',
output='screen',
arguments=['-entity', #参数设定,有很多参数,若要加入多个机器人必然要设置!
entity_name,
'-x', str(position[0]), '-y', str(position[1]
), '-z', str(position[2]),
'-R', str(orientation[0]), '-P', str(orientation[1]
), '-Y', str(orientation[2]),
'-topic', '/robot_description'
]
)
# Publish Robot Desciption in String form in the topic /robot_description
publish_robot_description = Node( #一个机器人发布者
package='box_bot_gazebo',
executable='robot_description_publisher.py',
name='robot_description_publisher',
output='screen',
arguments=['-xml_string', xml,
'-robot_description_topic', '/robot_description'
]
)
# Robot State Publisher
use_sim_time = LaunchConfiguration('use_sim_time', default='true')
robot_state_publisher_node = Node( #机器人位置发布者
package='robot_state_publisher',
executable='robot_state_publisher',
parameters=[{'use_sim_time': use_sim_time, 'robot_description': xml}],
output="screen"
)
# create and return launch description object
return LaunchDescription(
[
spawn_robot,
publish_robot_description,
robot_state_publisher_node
]
)
下图是gazebo官方包中spawn_entity.py中的一句
是启动机器人可以设置的参数之一。
4.设置机器人信息的CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(box_bot_description)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
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)
find_package(ament_cmake REQUIRED)
find_package(urdf REQUIRED)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
endif()
install(
DIRECTORY
robot
meshes
rviz
DESTINATION
share/${PROJECT_NAME}/
)
ament_package()
1.find_package(urdf REQUIRED) 要添加urdf
2.install 将需要编译的包文件夹导入。
3.
install(
PROGRAMS
launch/robot_description_publisher.py
DESTINATION lib/${PROJECT_NAME}
)
PROGRAMS 后将所有的python文件导入lib文件夹中,作为一个库!而非.launch.py导入
5.启动
ros2 launch box_bot_gazebo box_bot.launch.py
启动后,gazebo一直停留在准备世界的界面,首先考虑是models和plugin导入的路径的问题
后来才发现,world加载的是box_bot_box_room,改为box_bot_empty后,又出现问题!
这里是机器人模型又有问题了!f**k!
经检查,本程序添加的机器人包含了激光,但是我的cmke文件内并没有将激光作为一个plugin,install进lib里面,所以导致出错,把导入激光的的语句删掉之后就可以了。
![在这里插入图片描述](https://img-blog.csdnimg.cn/37db2b14
但是机器人并没有图片对其包裹。