当前位置: 首页 > news >正文

Chapter4:机器人仿真

ROS1{\rm ROS1}ROS1的基础及应用,基于古月的课,各位可以去看,基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。
ROS{\rm ROS}ROS版本:ROS1{\rm ROS1}ROS1Melodic{\rm Melodic}Melodic;实际机器人:Hawkbot{\rm Hawkbot}Hawkbot



1.机器人URDF模型优化

  1. URDF{\rm URDF}URDF模型进化版本–xacro{\rm xacro}xacro模型文件

    1. 精简模型代码
      • 创建宏定义;
      • 文件包含;
    2. 提供可编程接口
      • 常量;
      • 变量;
      • 数学计算;
      • 条件语句;
  2. 常量定义

    # 常量定义
    <xacro:property name="M_PI" value="3.14159" /># 常量使用
    <origin xyz="0 0 0" ryp="${M_PI/2} 0 0" />
    
  3. 数学计算

    # 数学计算
    <origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
    
  4. 宏定义

    # 宏定义
    <xacro:macro name="name" params="A B C">
    ...
    </xacro:macro># 宏调用
    <name A="A_value" B="B_value" C="C_value" />
    
  5. 文件包含

    # 文件包含
    <xacro:include filename="$(find mbot_description)/urdf/xacro/mbot_base.xacro" />
    

2.使用xacro建立模型

# 1.在urdf文件夹下建立xacro文件夹
mkdir xacro# 在xacro目录下新建mbot_base.xacro和mbot.xacro文件
# 文件内容见下个代码块,请勿直接复制粘贴
touch mbot_base.xacro mbot.xacro# 2.新建display_mbot_base_xacro.launch文件
# 文件内容见下个代码块,请勿直接复制粘贴
touch display_mbot_base_xacro.launch# 3.模型显示
# 法1:将xacro文件转换成URDF文件显示
rosrun xacro xacro.py mbot.xacro > mbot.urdf# 法2:直接调用xacro文件解析器,在.launch文件中写入
<arg name="model" default="$(find xacro)/xacro--inorder'$(find mbot_description)/urdf/xacro/mbot.xacro'" /><param name="robot_description" command="$(arg model)" /># 4.启动.launch文件
roslaunch mbot_description display_mbot_base_xacro.launch
# mbot_base.xacro文件内容
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro"><!-- PROPERTY LIST --><xacro:property name="M_PI" value="3.1415926"/><xacro:property name="base_radius" value="0.20"/><xacro:property name="base_length" value="0.16"/><xacro:property name="wheel_radius" value="0.06"/><xacro:property name="wheel_length" value="0.025"/><xacro:property name="wheel_joint_y" value="0.19"/><xacro:property name="wheel_joint_z" value="0.05"/><xacro:property name="caster_radius" value="0.015"/> <!-- wheel_radius - ( base_length/2 - wheel_joint_z) --><xacro:property name="caster_joint_x" value="0.18"/><!-- Defining the colors used in this robot --><material name="yellow"><color rgba="1 0.4 0 1"/></material><material name="black"><color rgba="0 0 0 0.95"/></material><material name="gray"><color rgba="0.75 0.75 0.75 1"/></material><!-- Macro for robot wheel --><xacro:macro name="wheel" params="prefix reflect"><joint name="${prefix}_wheel_joint" type="continuous"><origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/><parent link="base_link"/><child link="${prefix}_wheel_link"/><axis xyz="0 1 0"/></joint><link name="${prefix}_wheel_link"><visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length = "${wheel_length}"/></geometry><material name="gray" /></visual></link></xacro:macro><!-- Macro for robot caster --><xacro:macro name="caster" params="prefix reflect"><joint name="${prefix}_caster_joint" type="continuous"><origin xyz="${reflect*caster_joint_x} 0 ${-(base_length/2 + caster_radius)}" rpy="0 0 0"/><parent link="base_link"/><child link="${prefix}_caster_link"/><axis xyz="0 1 0"/></joint><link name="${prefix}_caster_link"><visual><origin xyz="0 0 0" rpy="0 0 0"/><geometry><sphere radius="${caster_radius}" /></geometry><material name="black" /></visual></link></xacro:macro><xacro:macro name="mbot_base"><link name="base_footprint"><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.001 0.001 0.001" /></geometry></visual></link><joint name="base_footprint_joint" type="fixed"><origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" />        <parent link="base_footprint"/><child link="base_link" /></joint><link name="base_link"><visual><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry><material name="yellow" /></visual></link><wheel prefix="left" reflect="-1"/><wheel prefix="right" reflect="1"/><caster prefix="front" reflect="-1"/><caster prefix="back" reflect="1"/></xacro:macro>
</robot>
# mbot.xacro文件内容
<?xml version="1.0"?>
<robot name="arm" xmlns:xacro="http://www.ros.org/wiki/xacro"><xacro:include filename="$(find mbot_description)/urdf/xacro/mbot_base.xacro" /><mbot_base/></robot>
# display_mbot_base_xacro.launch文件内容
<launch><arg name="model" default="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/mbot.xacro'" /><arg name="gui" default="true" /><param name="robot_description" command="$(arg model)" /><!-- 设置GUI参数,显示关节控制插件 --><param name="use_gui" value="$(arg gui)"/><!-- 运行joint_state_publisher节点,发布机器人的关节状态  --><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" /><!-- 运行robot_state_publisher节点,发布tf  --><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /><!-- 运行rviz可视化界面 --><node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot.rviz" required="true" /></launch>

3.ArbotiX+rviz功能仿真

  1. ArbotiX{\rm ArbotiX}ArbotiX简介

    • 一款控制电机、舵机的硬件控制板;
    • 提供了相应的ROS{\rm ROS}ROS功能包;
    • 提供了一个差速控制器,通过接收速度控制指令,更新机器人的里程计状态;
  2. ArbotiX{\rm ArbotiX}ArbotiX安装

    # ros相关信息:Ubuntu 18.04+melodic
    # 1.下载ArbotiX功能包
    cd willard_ws/src/
    git clone -b indigo-devel
    https://github.com/vanadiumlabs/arbotix_ros.git# 2.工作空间下编译
    cd ~/willard_ws/
    catkin_make
  3. 配置ArbotiX{\rm ArbotiX}ArbotiX控制器

    # 1.创建launch文件
    cd willard_ws/src/mbot_description/launch/xacro/# 文件内容见下个代码块,请勿直接复制粘贴
    touch arbotix_mbot_with_camera_xacro.launch# 2.创建配置文件
    cd willard_ws/src/mbot_description/config/# 文件内容见下个代码块,请勿直接复制粘贴
    touch fake_mbot_arbotix.yaml# 3.启动仿真器
    roslaunch mbot_description arbotix_mbot_with_camera_xacro.launch# 4.键盘控制相关
    # 4.1 新建mbot_teleop功能包
    catkin_create_pkg willard_teleop roscpp std_msgs rospy# 4.2 在willard_teleop下创建launch、scripts文件夹
    mkdir launch scripts# 4.3 在/scripts文件夹下创建.py文件
    # 文件内容见下个代码块,请勿直接复制粘贴
    touch willard_teleop.py# 4.4 给.py文件添加可执行权限
    chmod 777 willard_teleop.py# 4.5 新建.launch文件
    # 文件内容见下个代码块,请勿直接复制粘贴
    touch willard_teleop.launch # 5.启动键盘控制
    roslaunch willard_teleop willard_teleop.launch
    # arbotix_mbot_with_camera_xacro.launch文件内容
    <launch><arg name="model" default="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/mbot_with_camera.xacro'" /><arg name="gui" default="false" /><param name="robot_description" command="$(arg model)" /><!-- 设置GUI参数,显示关节控制插件 --><param name="use_gui" value="$(arg gui)"/><node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen"><rosparam file="$(find mbot_description)/config/fake_mbot_arbotix.yaml" command="load" /><param name="sim" value="true"/></node><!-- 运行joint_state_publisher节点,发布机器人的关节状态  --><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" /><!-- 运行robot_state_publisher节点,发布tf  --><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /><!-- 运行rviz可视化界面 --><node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_arbotix.rviz" required="true" /></launch>
    # fake_mbot_arbotix.yaml文件内容
    controllers: {base_controller: {type: diff_controller, base_frame_id: base_footprint, base_width: 0.26, ticks_meter: 4100, Kp: 12, Kd: 12, Ki: 0, Ko: 50, accel_limit: 1.0 }
    }
    # willard_teleop.py文件内容
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-import rospy
    from geometry_msgs.msg import Twist
    import sys, select, termios, ttymsg = """
    Control mbot!
    ---------------------------
    Moving around:u    i    oj    k    lm    ,    .q/z : increase/decrease max speeds by 10%
    w/x : increase/decrease only linear speed by 10%
    e/c : increase/decrease only angular speed by 10%
    space key, k : force stop
    anything else : stop smoothlyCTRL-C to quit
    """moveBindings = {'i':(1,0),'o':(1,-1),'j':(0,1),'l':(0,-1),'u':(1,1),',':(-1,0),'.':(-1,1),'m':(-1,-1),}speedBindings={'q':(1.1,1.1),'z':(.9,.9),'w':(1.1,1),'x':(.9,1),'e':(1,1.1),'c':(1,.9),}def getKey():tty.setraw(sys.stdin.fileno())rlist, _, _ = select.select([sys.stdin], [], [], 0.1)if rlist:key = sys.stdin.read(1)else:key = ''termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)return keyspeed = .2
    turn = 1def vels(speed,turn):return "currently:\tspeed %s\tturn %s " % (speed,turn)if __name__=="__main__":settings = termios.tcgetattr(sys.stdin)rospy.init_node('mbot_teleop')pub = rospy.Publisher('/cmd_vel', Twist, queue_size=5)x = 0th = 0status = 0count = 0acc = 0.1target_speed = 0target_turn = 0control_speed = 0control_turn = 0try:print msgprint vels(speed,turn)while(1):key = getKey()# 运动控制方向键(1:正方向,-1负方向)if key in moveBindings.keys():x = moveBindings[key][0]th = moveBindings[key][1]count = 0# 速度修改键elif key in speedBindings.keys():speed = speed * speedBindings[key][0]  # 线速度增加0.1倍turn = turn * speedBindings[key][1]    # 角速度增加0.1倍count = 0print vels(speed,turn)if (status == 14):print msgstatus = (status + 1) % 15# 停止键elif key == ' ' or key == 'k' :x = 0th = 0control_speed = 0control_turn = 0else:count = count + 1if count > 4:x = 0th = 0if (key == '\x03'):break# 目标速度=速度值*方向值target_speed = speed * xtarget_turn = turn * th# 速度限位,防止速度增减过快if target_speed > control_speed:control_speed = min( target_speed, control_speed + 0.02 )elif target_speed < control_speed:control_speed = max( target_speed, control_speed - 0.02 )else:control_speed = target_speedif target_turn > control_turn:control_turn = min( target_turn, control_turn + 0.1 )elif target_turn < control_turn:control_turn = max( target_turn, control_turn - 0.1 )else:control_turn = target_turn# 创建并发布twist消息twist = Twist()twist.linear.x = control_speed; twist.linear.y = 0; twist.linear.z = 0twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = control_turnpub.publish(twist)except:print efinally:twist = Twist()twist.linear.x = 0; twist.linear.y = 0; twist.linear.z = 0twist.angular.x = 0; twist.angular.y = 0; twist.angular.z = 0pub.publish(twist)termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    # willard_teleop.launch
    <launch><node name="willard_teleop" pkg="willard_teleop" type="willard_teleop.py" output="screen"><param name="scale_linear" value="0.1" type="double"/><param name="scale_angular" value="0.4" type="double"/></node>
    </launch>
  4. 仿真效果图

    1

4.Gazebo物理仿真环境搭建

4.1 ros_control
  1. ros_control{\rm ros\_control}ros_control简介

    • ROS{\rm ROS}ROS为开发者提供的机器人控制中间件;
    • 包含一系列控制器接口、传动装置接口、硬件接口、控制器工具等;
    • 可以帮助机器人应用功能包快速落地,提高开发效率;
  2. ros_control{\rm ros\_control}ros_control框架

    2

    3

    • 控制器管理器:提供一种通用的接口来管理不同的控制器;
    • 控制器:读取硬件状态,发布控制命令,完成每个joint{\rm joint}joint的控制;
    • 硬件资源:为上下两层提供硬件资源的接口;
    • 机器人硬件抽象:机器人硬件抽象和硬件资源直接打交道,通过write{\rm write}writeread{\rm read}read方法完成硬件操作;
    • 真实机器人:执行接收到的命令;

    4

  3. 控制器(controllers)({\rm controllers})(controllers)介绍

    5

4.2 仿真步骤
  1. 配置机器人模型;
  2. 创建仿真环境;
  3. 开始仿真;
4.2.1 配置物理仿真模型
  • STEP1{\rm STEP1}STEP1:为link{\rm link}link添加惯性参数和碰撞属性;
  • STEP2{\rm STEP2}STEP2:为link{\rm link}link添加gazebo{\rm gazebo}gazebo标签;
  • STEP3{\rm STEP3}STEP3:为joint{\rm joint}joint添加传动装置;
  • STEP4{\rm STEP4}STEP4:添加gazebo{\rm gazebo}gazebo控制器插件;
    • <robotNamespace{\rm robotNamespace}robotNamespace>:机器人的命名空间;
    • <leftJoint{\rm leftJoint}leftJoint>和<rightJoint{\rm rightJoint}rightJoint>:左右轮转动的关节joint{\rm joint}joint
    • <wheelSeparation{\rm wheelSeparation}wheelSeparation>和<wheelDiameter{\rm wheelDiameter}wheelDiameter>:机器人模型的相关尺寸,在计算差速参数时需要使用;
    • <commandTopic{\rm commandTopic}commandTopic>:控制器订阅的速度控制指令,生成全局命名时需要结合<robotNamespace{\rm robotNamespace}robotNamespace>中设置的命名空间;
    • <odometryFrame{\rm odometryFrame}odometryFrame>:里程计数据的参考坐标系,ROS{\rm ROS}ROS中一般命名为odom{\rm odom}odom

物理仿真模型配置实例:

# mbot_base_gazebo.xacro文件内容<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro"><!-- PROPERTY LIST --><xacro:property name="M_PI" value="3.1415926"/><xacro:property name="base_mass"   value="20" /> <xacro:property name="base_radius" value="0.20"/><xacro:property name="base_length" value="0.16"/><xacro:property name="wheel_mass"   value="2" /><xacro:property name="wheel_radius" value="0.06"/><xacro:property name="wheel_length" value="0.025"/><xacro:property name="wheel_joint_y" value="0.19"/><xacro:property name="wheel_joint_z" value="0.05"/><xacro:property name="caster_mass"    value="0.5" /> <xacro:property name="caster_radius"  value="0.015"/> <!-- wheel_radius - ( base_length/2 - wheel_joint_z) --><xacro:property name="caster_joint_x" value="0.18"/><!-- Defining the colors used in this robot --><material name="yellow"><color rgba="1 0.4 0 1"/></material><material name="black"><color rgba="0 0 0 0.95"/></material><material name="gray"><color rgba="0.75 0.75 0.75 1"/></material><!-- Macro for inertia matrix --><xacro:macro name="sphere_inertial_matrix" params="m r"><inertial><mass value="${m}" /><inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"iyy="${2*m*r*r/5}" iyz="0" izz="${2*m*r*r/5}" /></inertial></xacro:macro><xacro:macro name="cylinder_inertial_matrix" params="m r h"><inertial><mass value="${m}" /><inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"iyy="${m*(3*r*r+h*h)/12}" iyz = "0"izz="${m*r*r/2}" /> </inertial></xacro:macro><!-- Macro for robot wheel --><xacro:macro name="wheel" params="prefix reflect"><joint name="${prefix}_wheel_joint" type="continuous"><origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/><parent link="base_link"/><child link="${prefix}_wheel_link"/><axis xyz="0 1 0"/></joint><link name="${prefix}_wheel_link"><visual><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length = "${wheel_length}"/></geometry><material name="gray" /></visual><collision><origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /><geometry><cylinder radius="${wheel_radius}" length = "${wheel_length}"/></geometry></collision><cylinder_inertial_matrix  m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" /></link><gazebo reference="${prefix}_wheel_link"><material>Gazebo/Gray</material></gazebo><!-- Transmission is important to link the joints and the controller --><transmission name="${prefix}_wheel_joint_trans"><type>transmission_interface/SimpleTransmission</type><joint name="${prefix}_wheel_joint" ><hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface></joint><actuator name="${prefix}_wheel_joint_motor"><hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface><mechanicalReduction>1</mechanicalReduction></actuator></transmission></xacro:macro><!-- Macro for robot caster --><xacro:macro name="caster" params="prefix reflect"><joint name="${prefix}_caster_joint" type="continuous"><origin xyz="${reflect*caster_joint_x} 0 ${-(base_length/2 + caster_radius)}" rpy="0 0 0"/><parent link="base_link"/><child link="${prefix}_caster_link"/><axis xyz="0 1 0"/></joint><link name="${prefix}_caster_link"><visual><origin xyz="0 0 0" rpy="0 0 0"/><geometry><sphere radius="${caster_radius}" /></geometry><material name="black" /></visual><collision><origin xyz="0 0 0" rpy="0 0 0"/><geometry><sphere radius="${caster_radius}" /></geometry></collision>      <sphere_inertial_matrix  m="${caster_mass}" r="${caster_radius}" /></link><gazebo reference="${prefix}_caster_link"><material>Gazebo/Black</material></gazebo></xacro:macro><xacro:macro name="mbot_base_gazebo"><link name="base_footprint"><visual><origin xyz="0 0 0" rpy="0 0 0" /><geometry><box size="0.001 0.001 0.001" /></geometry></visual></link><gazebo reference="base_footprint"><turnGravityOff>false</turnGravityOff></gazebo><joint name="base_footprint_joint" type="fixed"><origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" />        <parent link="base_footprint"/><child link="base_link" /></joint><link name="base_link"><visual><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry><material name="yellow" /></visual><collision><origin xyz=" 0 0 0" rpy="0 0 0" /><geometry><cylinder length="${base_length}" radius="${base_radius}"/></geometry></collision>   <cylinder_inertial_matrix  m="${base_mass}" r="${base_radius}" h="${base_length}" /></link><gazebo reference="base_link"><material>Gazebo/Blue</material></gazebo><wheel prefix="left"  reflect="-1"/><wheel prefix="right" reflect="1"/><caster prefix="front" reflect="-1"/><caster prefix="back"  reflect="1"/><!-- controller --><gazebo><plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"><rosDebugLevel>Debug</rosDebugLevel><publishWheelTF>true</publishWheelTF><robotNamespace>/</robotNamespace><publishTf>1</publishTf><publishWheelJointState>true</publishWheelJointState><alwaysOn>true</alwaysOn><updateRate>100.0</updateRate><legacyMode>true</legacyMode><leftJoint>left_wheel_joint</leftJoint><rightJoint>right_wheel_joint</rightJoint><wheelSeparation>${wheel_joint_y*2}</wheelSeparation><wheelDiameter>${2*wheel_radius}</wheelDiameter><broadcastTF>1</broadcastTF><wheelTorque>30</wheelTorque><wheelAcceleration>1.8</wheelAcceleration><commandTopic>cmd_vel</commandTopic><odometryFrame>odom</odometryFrame> <odometryTopic>odom</odometryTopic> <robotBaseFrame>base_footprint</robotBaseFrame></plugin></gazebo> </xacro:macro></robot>
4.2.2 创建仿真环境
# view_mbot_gazebo_empty_world.launch文件内容<launch><!-- 设置launch文件的参数 --><arg name="paused" default="false"/><arg name="use_sim_time" default="true"/><arg name="gui" default="true"/><arg name="headless" default="false"/><arg name="debug" default="false"/><!-- 运行gazebo仿真环境 --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="debug" value="$(arg debug)" /><arg name="gui" value="$(arg gui)" /><arg name="paused" value="$(arg paused)"/><arg name="use_sim_time" value="$(arg use_sim_time)"/><arg name="headless" value="$(arg headless)"/></include><!-- 加载机器人模型描述参数 --><param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_gazebo.xacro'" /> <!-- 运行joint_state_publisher节点,发布机器人的关节状态  --><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> <!-- 运行robot_state_publisher节点,发布tf  --><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"  output="screen" ><param name="publish_frequency" type="double" value="50.0" /></node><!-- 在gazebo中加载机器人模型--><node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"args="-urdf -model mrobot -param robot_description"/> </launch>
# 1.启动空环境下的.launch文件
roslaunch mbot_gazebo view_mbot_gazebo_empty_world.launch # 2.启动键盘控制节点
roslaunch mbot_teleop mbot_teleop.launch# 3.添加环境模型
# 3.1 直接添加,把模型保存到~/.gazebo/models/下
cd ~/.gazebo/models/
git clone https://github.com/osrf/gazebo_models.git# 添加好模型后,保存为.world文件# 3.2 使用Buiding Editor,在gazebo的edit下
# 4.把仿真模型路径写入.launch文件,即可加载

效果如下图:

6

7

8

4.3 传感器仿真
4.3.1 摄像头仿真
  • <sensor{\rm sensor}sensor>标签:描述传感器;

    • type{\rm type}type:传感器类型,camera{\rm camera}camera
    • name{\rm name}name:摄像头命名,自由设置;
  • <camera{\rm camera}camera>标签:描述摄像头参数;

    • 分辨率、编码格式、图像范围、噪音参数等;
  • <plugin{\rm plugin}plugin>标签:加载摄像头仿真插件libgazebo_ros_camera.so{\rm libgazebo\_ros\_camera.so}libgazebo_ros_camera.so

    • 设置插件的命名空间、发布图像的话题、参考坐标系等;
  • 摄像头仿真的.xacro{\rm .xacro}.xacro文件实例

    # camera_gazebo.xacro文件内容<?xml version="1.0"?>
    <robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="camera"><xacro:macro name="usb_camera" params="prefix:=camera"><!-- Create laser reference frame --><link name="${prefix}_link"><inertial><mass value="0.1" /><origin xyz="0 0 0" /><inertia ixx="0.01" ixy="0.0" ixz="0.0"iyy="0.01" iyz="0.0"izz="0.01" /></inertial><visual><origin xyz=" 0 0 0 " rpy="0 0 0" /><geometry><box size="0.01 0.04 0.04" /></geometry><material name="black"/></visual><collision><origin xyz="0.0 0.0 0.0" rpy="0 0 0" /><geometry><box size="0.01 0.04 0.04" /></geometry></collision></link><gazebo reference="${prefix}_link"><material>Gazebo/Black</material></gazebo><gazebo reference="${prefix}_link"><sensor type="camera" name="camera_node"><update_rate>30.0</update_rate><camera name="head"><horizontal_fov>1.3962634</horizontal_fov><image><width>1280</width><height>720</height><format>R8G8B8</format></image><clip><near>0.02</near><far>300</far></clip><noise><type>gaussian</type><mean>0.0</mean><stddev>0.007</stddev></noise></camera><plugin name="gazebo_camera" filename="libgazebo_ros_camera.so"><alwaysOn>true</alwaysOn><updateRate>0.0</updateRate><cameraName>/camera</cameraName><imageTopicName>image_raw</imageTopicName><cameraInfoTopicName>camera_info</cameraInfoTopicName><frameName>camera_link</frameName><hackBaseline>0.07</hackBaseline><distortionK1>0.0</distortionK1><distortionK2>0.0</distortionK2><distortionK3>0.0</distortionK3><distortionT1>0.0</distortionT1><distortionT2>0.0</distortionT2></plugin></sensor></gazebo></xacro:macro>
    </robot>
# 1.在~/willard_ws/src/mbot_description/urdf/xacro/sensors/下新建camera_gazebo.xacro文件,内容见上一代码块
touch camera_gazebo.xacro# 2.启动仿真环境
# view_mbot_with_camera_gazebo.launch内容见下一代码块
roslaunch mbot_gazebo view_mbot_with_camera_gazebo.launch# 3.查看图像
rqt_image_view# 4.启动键盘控制机器人移动
roslaunch mbot_teleop mbot_teleop.launch
# view_mbot_with_camera_gazebo.launch文件内容<launch><!-- 设置launch文件的参数 --><arg name="world_name" value="$(find mbot_gazebo)/worlds/playground.world"/><arg name="paused" default="false"/><arg name="use_sim_time" default="true"/><arg name="gui" default="true"/><arg name="headless" default="false"/><arg name="debug" default="false"/><!-- 运行gazebo仿真环境 --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(arg world_name)" /><arg name="debug" value="$(arg debug)" /><arg name="gui" value="$(arg gui)" /><arg name="paused" value="$(arg paused)"/><arg name="use_sim_time" value="$(arg use_sim_time)"/><arg name="headless" value="$(arg headless)"/></include><!-- 加载机器人模型描述参数 --><param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_with_camera_gazebo.xacro'" /> <!-- 运行joint_state_publisher节点,发布机器人的关节状态  --><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> <!-- 运行robot_state_publisher节点,发布tf  --><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"  output="screen" ><param name="publish_frequency" type="double" value="50.0" /></node><!-- 在gazebo中加载机器人模型--><node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"args="-urdf -model mrobot -param robot_description"/> </launch>

9

4.3.2 RGB-D摄像头(kinect)仿真
# 1.在~/willard_ws/src/mbot_description/urdf/xacro/sensors/下新建kinect_gazebo.xacro文件,内容见下一代码块
touch kinect_gazebo.xacro# 2.启动仿真环境
# view_mbot_with_kinect_gazebo.launch内容见下一代码块
roslaunch mbot_gazebo view_mbot_with_kinect_gazebo.launch# 3.查看图像
rosrun rviz rviz# 4.启动键盘控制机器人移动
roslaunch mbot_teleop mbot_teleop.launch
# kinect_gazebo.xacro文件内容<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="kinect_camera"><xacro:macro name="kinect_camera" params="prefix:=camera"><!-- Create kinect reference frame --><!-- Add mesh for kinect --><link name="${prefix}_link"><origin xyz="0 0 0" rpy="0 0 0"/><visual><origin xyz="0 0 0" rpy="0 0 ${M_PI/2}"/><geometry><mesh filename="package://mbot_description/meshes/kinect.dae" /></geometry></visual><collision><geometry><box size="0.07 0.3 0.09"/></geometry></collision></link><joint name="${prefix}_optical_joint" type="fixed"><origin xyz="0 0 0" rpy="-1.5708 0 -1.5708"/><parent link="${prefix}_link"/><child link="${prefix}_frame_optical"/></joint><link name="${prefix}_frame_optical"/><gazebo reference="${prefix}_link"><sensor type="depth" name="${prefix}"><always_on>true</always_on><update_rate>20.0</update_rate><camera><horizontal_fov>${60.0*M_PI/180.0}</horizontal_fov><image><format>R8G8B8</format><width>640</width><height>480</height></image><clip><near>0.05</near><far>8.0</far></clip></camera><plugin name="kinect_${prefix}_controller" filename="libgazebo_ros_openni_kinect.so"><cameraName>${prefix}</cameraName><alwaysOn>true</alwaysOn><updateRate>10</updateRate><imageTopicName>rgb/image_raw</imageTopicName><depthImageTopicName>depth/image_raw</depthImageTopicName><pointCloudTopicName>depth/points</pointCloudTopicName><cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName><depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName><frameName>${prefix}_frame_optical</frameName><baseline>0.1</baseline><distortion_k1>0.0</distortion_k1><distortion_k2>0.0</distortion_k2><distortion_k3>0.0</distortion_k3><distortion_t1>0.0</distortion_t1><distortion_t2>0.0</distortion_t2><pointCloudCutoff>0.4</pointCloudCutoff></plugin></sensor></gazebo></xacro:macro>
</robot>
# view_mbot_with_kinect_gazebo.launch文件内容<launch><!-- 设置launch文件的参数 --><arg name="world_name" value="$(find mbot_gazebo)/worlds/playground.world"/><arg name="paused" default="false"/><arg name="use_sim_time" default="true"/><arg name="gui" default="true"/><arg name="headless" default="false"/><arg name="debug" default="false"/><!-- 运行gazebo仿真环境 --><include file="$(find gazebo_ros)/launch/empty_world.launch"><arg name="world_name" value="$(arg world_name)" /><arg name="debug" value="$(arg debug)" /><arg name="gui" value="$(arg gui)" /><arg name="paused" value="$(arg paused)"/><arg name="use_sim_time" value="$(arg use_sim_time)"/><arg name="headless" value="$(arg headless)"/></include><!-- 加载机器人模型描述参数 --><param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_with_kinect_gazebo.xacro'" /> <!-- 运行joint_state_publisher节点,发布机器人的关节状态  --><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> <!-- 运行robot_state_publisher节点,发布tf  --><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"  output="screen" ><param name="publish_frequency" type="double" value="50.0" /></node><!-- 在gazebo中加载机器人模型--><node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"args="-urdf -model mrobot -param robot_description"/> </launch>

仿真效果图:

10

4.3.3 激光雷达仿真
# 1.在~/willard_ws/src/mbot_description/urdf/xacro/sensors/下新建lidar_gazebo.xacro文件,内容见下一代码块
touch lidar_gazebo.xacro# 2.启动仿真环境
# view_mbot_with_laser_gazebo.launch内容见下一代码块
roslaunch mbot_gazebo view_mbot_with_laser_gazebo.launch# 3.查看图像
rosrun rviz rviz# 4.启动键盘控制机器人移动
roslaunch mbot_teleop mbot_teleop.launch
# lidar_gazebo.xacro文件内容<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="laser"><xacro:macro name="rplidar" params="prefix:=laser"><!-- Create laser reference frame --><link name="${prefix}_link"><inertial><mass value="0.1" /><origin xyz="0 0 0" /><inertia ixx="0.01" ixy="0.0" ixz="0.0"iyy="0.01" iyz="0.0"izz="0.01" /></inertial><visual><origin xyz=" 0 0 0 " rpy="0 0 0" /><geometry><cylinder length="0.05" radius="0.05"/></geometry><material name="black"/></visual><collision><origin xyz="0.0 0.0 0.0" rpy="0 0 0" /><geometry><cylinder length="0.06" radius="0.05"/></geometry></collision></link><gazebo reference="${prefix}_link"><material>Gazebo/Black</material></gazebo><gazebo reference="${prefix}_link"><sensor type="ray" name="rplidar"><pose>0 0 0 0 0 0</pose><visualize>false</visualize><update_rate>5.5</update_rate><ray><scan><horizontal><samples>360</samples><resolution>1</resolution><min_angle>-3</min_angle><max_angle>3</max_angle></horizontal></scan><range><min>0.10</min><max>6.0</max><resolution>0.01</resolution></range><noise><type>gaussian</type><mean>0.0</mean><stddev>0.01</stddev></noise></ray><plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so"><topicName>/scan</topicName><frameName>laser_link</frameName></plugin></sensor></gazebo></xacro:macro>
</robot>

仿真效果图:

11

相关文章:

Chapter4:机器人仿真

ROS1{\rm ROS1}ROS1的基础及应用&#xff0c;基于古月的课&#xff0c;各位可以去看&#xff0c;基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本&#xff1a;ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic&#xff1b;实际机器人&#xff1a;Ha…...

python(14)--集合

前言 本篇文章学习的是 python 中集合的基础知识。 集合元素的内容是不可变的&#xff0c;常见的元素有整数、浮点数、字符串、元组等。至于可变内容列表、字典、集合等不可以是集合元素。虽然集合不可以是集合的元素&#xff0c;但是集合本身是可变的&#xff0c;可以去增加或…...

【Spark分布式内存计算框架——Spark Core】4. RDD函数(中)Transformation函数、Action函数

3.2 Transformation函数 在Spark中Transformation操作表示将一个RDD通过一系列操作变为另一个RDD的过程&#xff0c;这个操作可能是简单的加减操作&#xff0c;也可能是某个函数或某一系列函数。值得注意的是Transformation操作并不会触发真正的计算&#xff0c;只会建立RDD间…...

Mysql 数据类型

1、数值数据类型 1.1 整数类型(精确值) INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT MySQL支持SQL标准的整数类型INTEGER (或INT)和SMALLINT。作为标准的扩展&#xff0c;MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每种整数类型所需的存储和范围。…...

运行Whisper笔记(1)

最近chatGPT很火&#xff0c;就去逛了一下openai的github项目。发现了这个项目。 这个项目可以识别视频中的音频&#xff0c;转换出字幕。 带着一颗好奇的心就尝试自己去部署玩一玩 跟着这篇文章一步步来进行安装&#xff0c;并且跟着这篇文章解决途中遇到的问题。 途中还会遇…...

2023年最强大的12款数据可视化工具,值得收藏

做数据分析也有年头了&#xff0c;好的坏的工具都用过&#xff0c;推荐几个觉得很好用的&#xff0c;避坑必看&#xff01; PS&#xff1a;一般比较成熟的公司里&#xff0c;数据分析工具不只是满足业务分析和报表制作&#xff0c;像我现在给我们公司选型BI工具&#xff0c;是做…...

LeetCode刷题系列 -- 523. 连续的子数组和

给你一个整数数组 nums 和一个整数 k &#xff0c;编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组&#xff1a;子数组大小 至少为 2 &#xff0c;且子数组元素总和为 k 的倍数。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。如果存…...

LeetCode刷题系列 -- 525. 连续数组

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组&#xff0c;并返回该子数组的长度。示例 1:输入: nums [0,1]输出: 2说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2:输入: nums [0,1,0]输出: 2说明: [0, 1] (或 [1, 0]) 是具有相同数…...

JavaEE15-Spring Boot统一功能处理

目录 1.统一用户登录权限效验 1.1.最初用户登录验证 1.2.Spring AOP用户统一登录验证的问题 1.3.Spring拦截器 1.3.1.创建自定义拦截器&#xff0c;实现 HandlerInterceptor 接口并重写 preHandle&#xff08;执行具体方法之前的预处理&#xff09;方法 1.3.2.将自定义拦…...

centos7.6 设置防火墙

1、查看系统版本 cat /etc/redhat-release2、查看防火墙运行状态 systemctl status firewalld这里可以看到当前是未运行状态(inactive)。 3、关闭开机自启动防火墙 systemctl disable firewalld.service4、启动防火墙并查看状态&#xff0c;系统默认 22 端口是开启的。 sy…...

在线支付系列【22】微信支付实战篇之集成服务商API

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言1. 环境搭建2. 特约商户进件3. 统一下单总结前言 在上篇文档中&#xff0c;我们做好了接入前准备工作&#xff0c;接下来使用开源框架集成服务商相关API。 一个简单的支付系统完成支付流程…...

3.2 埃尔米特转置

定义 对于复矩阵&#xff0c;转置又不一样&#xff0c;常见的操作是共轭转置&#xff0c;也叫埃尔米特转置Hermitian transpose。埃尔米特转置就是对矩阵先共轭&#xff0c;再转置&#xff0c;一般来说用三种符号表示埃尔米特转置&#xff1a; 第一种符号是AHA^HAH&#xff0c…...

Python爬虫之Scrapy框架系列(13)——实战ZH小说爬取数据入MySql数据库

目录&#xff1a;1 数据持久化存储&#xff0c;写入Mysql数据库①定义结构化字段&#xff1a;②重新编写爬虫文件&#xff1a;③编写管道文件&#xff1a;④辅助配置&#xff08;修改settings.py文件&#xff09;&#xff1a;⑤navicat创库建表&#xff1a;⑥ 效果如下&#xf…...

MySQL篇02-三大范式,多表查询

数据入库时,由于数据设计不合理&#xff0c;会存在数据重复、更新插入异常等情况, 故数据库中表的设计遵循的设计规范&#xff1a;三大范式1.第一范式(1NF)要求数据库的每一列都是不可分割的原子数据项&#xff0c;即原子性。强调的是列的原子性&#xff0c;即数据库中每一列的…...

vue-cli3创建Vue项目

文章目录前言一、使用vue-cli3创建项目1.检查当前vue的版本2.下载并安装Vue-cli33.使用命令行创建项目二、关于配置前言 本文讲解了如何使用vue-cli3创建属于自己的Vue项目&#xff0c;如果本文对你有所帮助请三连支持博主&#xff0c;你的支持是我更新的动力。 下面案例可供…...

Linux perf probe 的使用(三)

文章目录前言一、Dynamic Tracing二、kprobes2.1 perf kprobe 的使用2.2 kprobe Arguments3.3 tcp_sendmsg()3.3.1 Kernel: tcp_sendmsg()3.3.2 Kernel: tcp_sendmsg() with size3.3.2 Kernel: tcp_sendmsg() line number and local variable三、uprobes的使用3.1 perf uprobe …...

python GUI编程 多窗口跳转

# 多窗口跳转例子from tkinter import *def main(): # 主窗体def goto(num):root.destroy() # 关闭主窗体if num 1:one() # 进入第1个窗体elif num 2:two() # 进入第2个窗体root Tk()root.geometry(300x150600200)root.title(登录窗口)but1 Button(root, text"进入…...

nuxt 学习笔记

这里写目录标题路由跳转NuxtLinkquery参数params参数嵌套路由tab切换效果layouts 文件夹强制约定放置所有布局文件&#xff0c;并以插槽的形式作用在页面中1.在app.vue里面2.component 组件使用Vue < component :is"">Vuex生命周期数据请求useFetchuseAsyncDat…...

Python编程自动化办公案例(1)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.使用库讲解 1.xlrd 2.xlwt 二.主要案例 1.批量合并 模板如下&#xf…...

一站式 Elasticsearch 集群指标监控与运维管控平台

上篇文章写了一下消息运维管理平台&#xff0c;今天带来的是ES的监控和运维平台。目前初创企业&#xff0c;不像大型互联网公司&#xff0c;可以重复的造轮子。前期还是快速迭代试错阶段&#xff0c;方便拿到市场反馈&#xff0c;及时调整自己的战略和产品方向。让自己活下去&a…...

C# 调用Python

一、简介 IronPython 是一种在 NET 和 Mono 上实现的 Python 语言&#xff0c;由 Jim Hugunin&#xff08;同时也是 Jython 创造者&#xff09;所创造。 Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python是…...

51单片机最强模块化封装(3)

文章目录 前言一、创建smg文件,添加smg文件路径二、smg文件编写三、模块化测试总结前言 本篇文章将带大家继续封装我们的代码。 这里我们会封装数码管的操作函数。 一、创建smg文件,添加smg文件路径 这里的操作就不过多解释了,大家自行看前面的文章即可。 51单片机模块化…...

【CSS 布局】水平垂直居中

CSS 布局-水平垂直居中 一、水平居中 创建一个父盒子&#xff0c;和子盒子 <div class"parent"><div class"child"></div> </div>基本样式如下 .parent {background-color: #fff; }.child {background-color: #999;width: 100p…...

【C++】类和对象--类的6个默认成员函数

目录1.类的6个默认成员函数2.构造函数2.1概念2.2特性3.析构函数3.1概念3.2特性4.拷贝构造函数4.1概念4.2特征5.赋值运算符重载5.1运算符重载5.2赋值运算符重载5.3前置和后置重载5.4流插入和流提取运算符重载6.const成员7.取地址重载和const取地址操作符重载1.类的6个默认成员函…...

常见面试题---------如何处理MQ消息丢失的问题?

如何处理MQ消息丢失的问题? RabbitMQ丢失消息分为如下几种情况&#xff1a; 生产者丢消息&#xff1a; 生产者将数据发送到RabbitMQ的时候&#xff0c;可能在传输过程中因为网络等问题而将数据弄丢了。 RabbitMQ自己丢消息&#xff1a; 如果没有开启RabbitMQ的持久化&#x…...

十四、Linux网络:高级IO

目录 五种IO模型 同步IO 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO...

带你走进API安全的知识海洋

Part1什么是API API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访…...

【Java】TCP的三次握手和四次挥手

三次握手 TCP三次握手是一个经典的面试题&#xff0c;它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接&#xff0c;并进行数据传递。&#xff08;客户端主动发起的&#xff09;TCP之所以需要三次握手是因为TCP双方都是全双工的。 什么是全双工&#xff1f; TCP任何…...

JUC并发编程

1.什么是JUC java.util工具包、包、分类 业务&#xff1a;普通业务线程代码 Thread Runable: 没有返回值、效率相比Callable相对较低。 2.线程和进程 进程&#xff1a;一个程序&#xff0c;QQ.exe Music.exe 程序的集合 一个进程往往可以包含多个线程&#xff0c;至少包含一个…...

概率统计·假设检验【正态总体均值的假设检验、正态总体方差的假设检验】

均值假设检验定义 2类错误 第1类错误&#xff08;弃真&#xff09;&#xff1a;当原假设H0为真&#xff0c;观察值却落入拒绝域&#xff0c;因而拒 绝H0这类错误是“以真为假” 犯第一类错误的概率显著性水平α第2类错误&#xff08;取伪&#xff09;&#xff1a;当原假设H0不…...

做推广能提高网站权重么/深圳seo优化

在上一篇文章里面我们编译了在X86体系的最简单的Linux下的入门驱动Hello&#xff0c;现在我们开始开发在ARM板上的最简单的Hello的驱动&#xff1a; 开发环境&#xff1a;虚拟机上的Linux(Fedora)ARM(11)友善之臂的光盘带的linux内核linux-2.6.36 开发步骤&#xff1a; 1.先安装…...

wordpress wrapper/推广赚佣金的平台

图像算法中会经常用到摄像机的畸变校正&#xff0c;有必要总结分析OpenCV中畸变校正方法&#xff0c;其中包括普通针孔相机模型和鱼眼相机模型fisheye两种畸变校正方法。 普通相机模型畸变校正函数针对OpenCV中的cv::initUndistortRectifyMap()&#xff0c;鱼眼相机模型畸变校正…...

深圳本地做网站/百度云搜索引擎入口盘多多

题目链接 题目大意 从左到右选三道题&#xff0c;要求难度递增&#xff0c;求花费时间的最小值。 题目思路 emm&#xff0c;对于这种题目&#xff0c;看到三个值&#xff0c;其实就想要枚举中间值&#xff0c;然后这个又是类似于逆序对。 以难度值为节点编号 &#xff0c;时…...

深圳网站制作 论坛/镇江网站seo

Express中间件body-parser简单实现 之前文章写了怎么用body-parser中间件处理post请求&#xff0c;今天就大概实现下body-parser中urlencoded 这个方法。 首先通过命令提示输入 mkdir lib && cd lib。 再输入touch body-parser.js。 把下面的代码在body-parser.js 敲一…...

青岛市北区网站制作公司/什么叫seo优化

最近在安装Xcode的插件时&#xff0c;本来应该选择loadbundle&#xff0c;但是选择了skip bundle&#xff0c;导致插件一直安装不上&#xff0c;后来网上找了一堆东西&#xff0c;但是好像没用。幸好&#xff0c;最后解决了。 先说说原因&#xff1a;这是因为Xcode黑名单的问题…...

wordpress用户名忘记/百度联盟一天多少收入

1、v1.begin() 2是第三个元素 2、定义时指定10个元素的内存&#xff0c;同时给所有元素赋值6 ——vector v3(10, 6) 3、;...