【ROS&GAZEBO】多旋翼无人机仿真(一)——搭建仿真环境
【ROS&GAZEBO】多旋翼无人机仿真(二)——基于rotors的仿真
【ROS&GAZEBO】多旋翼无人机仿真(三)——自定义多旋翼模型
上一篇介绍了如何用rotors进行仿真,这一篇继续介绍在ROS&GAZEBO中如何自定义多旋翼模型。
建立模型
在GAZEBO搭建模型第一步是建一个模型,可以在GAZEBO中直接设计模型,也可以通过导入STL文件建立模型,这里我选择后者,用SolidWorks设计了一个四旋翼模型导入到GAZEBO,
设计的简化四旋翼模型如下:
下一步是导出STP格式,这里要注意一点是导出时要注意坐标系的方向,这里我们需要对齐到NED(北东地)坐标系,
下一步导出STL格式,这里一定要选对参考坐标系。
构建工作空间
导出模型完成之后,需要开始建立ROS包,在第一篇【ROS&GAZEBO】多旋翼无人机仿真(一)——搭建仿真环境中已经搭建好了ROS工作空间,同时第二篇【ROS&GAZEBO】多旋翼无人机仿真(二)——基于rotors的仿真中的rotors包也是必须要的,如果没有完成的可以翻回去学习。下面开始搭建自定义模型的ROS包
首先创建一个文件夹
mkdir ~/catkin_ws/src/reed_simulator
mkdir ~/catkin_ws/src/reed_simulator/reed_gazebo
mkdir ~/catkin_ws/src/reed_simulator/reed_gazebo_plugin
mkdir ~/catkin_ws/src/reed_simulator/reed_gazebo/urdf
mkdir ~/catkin_ws/src/reed_simulator/reed_gazebo/launch
mkdir ~/catkin_ws/src/reed_simulator/reed_gazebo/meshes
这里reed_gazebo_plugin文件夹是后面添加自定义插件用的,暂时用不上
然后在reed_gazebo文件夹中新建CMakeLists.txt和package.xml
CMakeLists.txt中编写下面代码
cmake_minimum_required(VERSION 2.8.3)
project(reed_gazebo)
add_definitions(-std=c++11)
#--------------------------#
# Generation of SDF models #
#--------------------------#
# We need Gazebo version >= 3.0.0 to generate iris.sdf file
# (gz sdf ... command needs to be available)
find_package(gazebo REQUIRED)
find_package(PythonInterp REQUIRED)
find_package(catkin REQUIRED COMPONENTS gazebo_msgs geometry_msgs roscpp sensor_msgs)
catkin_package(
CATKIN_DEPENDS
gazebo_msgs
geometry_msgs
roscpp
sensor_msgs
)
include_directories(include ${catkin_INCLUDE_DIRS})
foreach(dir launch models resource worlds)
install(DIRECTORY ${dir}/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/${dir})
endforeach(dir)
package.xml中写入下面的代码:
<package format="2">
<name>reed_gazebo</name>
<version>2.2.3</version>
<description>The reed_gazebo package</description>
<maintainer email="liaoluweillw@163.com">Fadri Furrer</maintainer>
<author>Reed Liao</author>
<license>ASL 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<depend>gazebo_msgs</depend>
<depend>gazebo_plugins</depend>
<depend>geometry_msgs</depend>
<depend>joy</depend>
<depend>mav_msgs</depend>
<depend>roscpp</depend>
<depend>sensor_msgs</depend>
<depend>xacro</depend>
</package>
然后在~/catkin_ws下进行编译catkin build,如果没有报错,说明程序包已经构建好了,下面开始导入模型
将STL模型放入meshes文件夹,如下:
urdf文件夹中添加3个文件:reed_quad_x_base.xacro、reed_quad_x.xacro、mav_generic_odometry_sensor.gazebo
reed_quad_x_base.xacro中代码如下:
<?xml version="1.0"?>
<robot name="reed_quad_x" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find rotors_description)/urdf/component_snippets.xacro" />
<!-- Instantiate reed_quad_x "mechanics" -->
<xacro:include filename="$(find reed_gazebo)/urdf/reed_quad_x.xacro" />
<!-- Instantiate a controller. -->
<xacro:controller_plugin_macro namespace="${namespace}" imu_sub_topic="imu" />
<!-- Instantiate a ROS message interface -->
<!-- <xacro:ros_interface_plugin_macro namespace="${namespace}" />-->
<xacro:if value="$(arg enable_mavlink_interface)">
<!-- Instantiate mavlink telemetry interface. -->
<xacro:default_mavlink_interface namespace="${namespace}" imu_sub_topic="imu" rotor_count="6" />
</xacro:if>
<!-- Mount an ADIS16448 IMU. -->
<xacro:default_imu namespace="${namespace}" parent_link="${namespace}/base_link" />
<xacro:if value="$(arg enable_ground_truth)">
<xacro:ground_truth_imu_and_odometry namespace="${namespace}" parent_link="${namespace}/base_link" />
</xacro:if>
<xacro:if value="$(arg enable_logging)">
<!-- Instantiate a logger -->
<xacro:bag_plugin_macro
namespace="${namespace}"
bag_file="$(arg log_file)"
rotor_velocity_slowdown_sim="${rotor_velocity_slowdown_sim}"
wait_to_record_bag="$(arg wait_to_record_bag)" />
</xacro:if>
</robot>
reed_quad_x.xacro中代码如下:
<?xml version="1.0"?>
<robot name="reed_quad_x" xmlns:xacro="http://ros.org/wiki/xacro">
<!-- Properties -->
<xacro:property name="namespace" value="$(arg namespace)" />
<xacro:property name="rotor_velocity_slowdown_sim" value="10" />
<xacro:property name="use_mesh_file" value="true" />
<xacro:property name="mesh_file" value="package://reed_gazebo/meshes/reed_quad_x/body.STL" />
<xacro:property name="mass" value="1.5" /> <!-- [kg] -->
<xacro:property name="body_width" value="0.47" /> <!-- [m] -->
<xacro:property name="body_height" value="0.22" /> <!-- [m] -->
<xacro:property name="mass_rotor" value="0.005" /> <!-- [kg] -->
<xacro:property name="arm_length_front_x" value="0.18738" /> <!-- [m] -->
<xacro:property name="arm_length_back_x" value="0.18738" /> <!-- [m] -->
<xacro:property name="arm_length_front_y" value="0.18738" /> <!-- [m] -->
<xacro:property name="arm_length_back_y" value="0.18738" /> <!-- [m] -->
<xacro:property name="rotor_offset_top" value="0.026" /> <!-- [m] -->
<xacro:property name="radius_rotor" value="0.1" /> <!-- [m] -->
<xacro:property name="motor_constant" value="8.54858e-06" /> <!-- [kg.m/s^2] -->
<xacro:property name="moment_constant" value="0.016" /> <!-- [m] -->
<xacro:property name="time_constant_up" value="0.0125" /> <!-- [s] -->
<xacro:property name="time_constant_down" value="0.025" /> <!-- [s] -->
<xacro:property name="max_rot_velocity" value="838" /> <!-- [rad/s] -->
<xacro:property name="sin30" value="0.5" />
<xacro:property name="cos30" value="0.866025403784" />
<xacro:property name="sqrt2" value="1.4142135623730951" />
<xacro:property name="rotor_drag_coefficient" value="8.06428e-05" />
<xacro:property name="rolling_moment_coefficient" value="0.000001" />
<!-- Property Blocks -->
<xacro:property name="body_inertia">
<inertia ixx="0.0347563" ixy="0.0" ixz="0.0" iyy="0.0458929" iyz="0.0" izz="0.0977" /> <!-- [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] [kg.m^2] -->
</xacro:property>
<!-- inertia of a single rotor, assuming it is a cuboid. Height=3mm, width=15mm -->
<xacro:property name="rotor_inertia">
<xacro:box_inertia x="${radius_rotor}" y="0.015" z="0.003" mass="${mass_rotor*rotor_velocity_slowdown_sim}" />
</xacro:property>
<!-- Included URDF Files -->
<xacro:include filename="$(find rotors_description)/urdf/multirotor_base.xacro" />
<!-- Instantiate multirotor_base_macro once -->
<xacro:multirotor_base_macro
robot_namespace="${namespace}"
mass="${mass}"
body_width="${body_width}"
body_height="${body_height}"
use_mesh_file="${use_mesh_file}"
mesh_file="${mesh_file}"
>
<xacro:insert_block name="body_inertia" />
</xacro:multirotor_base_macro>
<!-- Instantiate rotors -->
<xacro:vertical_rotor
robot_namespace="${namespace}"
suffix="front_right"
direction="ccw"
motor_constant="${motor_constant}"
moment_constant="${moment_constant}"
parent="${namespace}/base_link"
mass_rotor="${mass_rotor}"
radius_rotor="${radius_rotor}"
time_constant_up="${time_constant_up}"
time_constant_down="${time_constant_down}"
max_rot_velocity="${max_rot_velocity}"
motor_number="0"
rotor_drag_coefficient="${rotor_drag_coefficient}"
rolling_moment_coefficient="${rolling_moment_coefficient}"
color="Blue"
use_own_mesh="false"
mesh="">
<origin xyz="${arm_length_front_x} -${arm_length_front_y} ${rotor_offset_top}" rpy="0 0 0" />
<xacro:insert_block name="rotor_inertia" />
</xacro:vertical_rotor>
<xacro:vertical_rotor
robot_namespace="${namespace}"
suffix="back_left"
direction="ccw"
motor_constant="${motor_constant}"
moment_constant="${moment_constant}"
parent="${namespace}/base_link"
mass_rotor="${mass_rotor}"
radius_rotor="${radius_rotor}"
time_constant_up="${time_constant_up}"
time_constant_down="${time_constant_down}"
max_rot_velocity="${max_rot_velocity}"
motor_number="1"
rotor_drag_coefficient="${rotor_drag_coefficient}"
rolling_moment_coefficient="${rolling_moment_coefficient}"
color="Red"
use_own_mesh="false"
mesh="">
<origin xyz="-${arm_length_back_x} ${arm_length_back_y} ${rotor_offset_top}" rpy="0 0 0" />
<xacro:insert_block name="rotor_inertia" />
</xacro:vertical_rotor>
<xacro:vertical_rotor robot_namespace="${namespace}"
suffix="front_left"
direction="cw"
motor_constant="${motor_constant}"
moment_constant="${moment_constant}"
parent="${namespace}/base_link"
mass_rotor="${mass_rotor}"
radius_rotor="${radius_rotor}"
time_constant_up="${time_constant_up}"
time_constant_down="${time_constant_down}"
max_rot_velocity="${max_rot_velocity}"
motor_number="2"
rotor_drag_coefficient="${rotor_drag_coefficient}"
rolling_moment_coefficient="${rolling_moment_coefficient}"
color="Blue"
use_own_mesh="false"
mesh="">
<origin xyz="${arm_length_front_x} ${arm_length_front_y} ${rotor_offset_top}" rpy="0 0 0" />
<xacro:insert_block name="rotor_inertia" />
</xacro:vertical_rotor>
<xacro:vertical_rotor robot_namespace="${namespace}"
suffix="back_right"
direction="cw"
motor_constant="${motor_constant}"
moment_constant="${moment_constant}"
parent="${namespace}/base_link"
mass_rotor="${mass_rotor}"
radius_rotor="${radius_rotor}"
time_constant_up="${time_constant_up}"
time_constant_down="${time_constant_down}"
max_rot_velocity="${max_rot_velocity}"
motor_number="3"
rotor_drag_coefficient="${rotor_drag_coefficient}"
rolling_moment_coefficient="${rolling_moment_coefficient}"
color="Red"
use_own_mesh="false"
mesh="">
<origin xyz="-${arm_length_back_x} -${arm_length_back_y} ${rotor_offset_top}" rpy="0 0 0" />
<xacro:insert_block name="rotor_inertia" />
</xacro:vertical_rotor>
</robot>
<?xml version="1.0"?>
<robot name="$(arg mav_name)" xmlns:xacro="http://ros.org/wiki/xacro">
<!-- Instantiate the mav-->
<xacro:include filename="$(find reed_gazebo)/urdf/$(arg mav_name)_base.xacro" />
<!-- Mount a generic odometry sensor without odometry map (working everywhere). -->
<xacro:odometry_plugin_macro
namespace="${namespace}"
odometry_sensor_suffix="1"
parent_link="${namespace}/base_link"
pose_topic="odometry_sensor1/pose"
pose_with_covariance_topic="odometry_sensor1/pose_with_covariance"
position_topic="odometry_sensor1/position"
transform_topic="odometry_sensor1/transform"
odometry_topic="odometry_sensor1/odometry"
parent_frame_id="world"
child_frame_id="${namespace}/odometry_sensor1"
mass_odometry_sensor="0.00001"
measurement_pisor="1"
measurement_delay="0"
unknown_delay="0.0"
noise_normal_position="0 0 0"
noise_normal_quaternion="0 0 0"
noise_normal_linear_velocity="0 0 0"
noise_normal_angular_velocity="0 0 0"
noise_uniform_position="0 0 0"
noise_uniform_quaternion="0 0 0"
noise_uniform_linear_velocity="0 0 0"
noise_uniform_angular_velocity="0 0 0"
enable_odometry_map="false"
odometry_map=""
image_scale="">
<inertia ixx="0.00001" ixy="0.0" ixz="0.0" iyy="0.00001" iyz="0.0" izz="0.00001" /> <!-- [kg m^2] [kg m^2] [kg m^2] [kg m^2] [kg m^2] [kg m^2] -->
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</xacro:odometry_plugin_macro>
</robot>
做到这里,已经完成了URDF模型的编写,下面就是launch启动文件的编写,这里涉及到3个文件:mav_hovering_example.launch、mav.launch、spawn_mav.launch,这里就不展示具体的代码了,所有文件我都打包好了放入gitee了,最后的效果如下:
到此为止,我们还没涉及到一行C++代码,全都是使用rotors程序包里面编写好的插件,后面我们将自定义插件,如果对里面细节不清楚的,可以自行研究rotors程序包或者留言交流
gitee地址:https://gitee.com/liaoluweillw/reed_simulator
版权声明:本文为博主Reed Liao原创文章,版权归属原作者,如果侵权,请联系我们删除!
原文链接:https://blog.csdn.net/qq_37680545/article/details/123243313