VIM插件Vundle安装

第一步,安装。

git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle

第二步,更新.vimrc。

https://github.com/tailang/vimrc/blob/master/.vimrc
其中路径是个目录,vimrc用~/下面的.vimrc

第三步,安装。

:PluginInstall

其中,emmet用于xml文件,主要用法是在插入模式下,例如输入p#f,在输入模式下,继续按(Ctrl+y+,),三个按键同时按下。

 

下面是我的.vimrc文件,如有变更会在这里更新。
set nocompatible              ” be iMproved, required
filetype off                  ” required

” ==============================================================================
” set the runtime path to include Vundle and initialize
set rtp+=/home/gavin/.vim/bundle/vundle/

” ==============================================================================
” 安装的所有插件
call vundle#begin()

” 必须安装,let Vundle manage Vundle, required
Plugin ‘VundleVim/Vundle.vim’

” 来自github

“主题
Plugin ‘flazz/vim-colorschemes’

“底部状态栏
Plugin ‘Lokaltog/vim-powerline’

“文件目录
Plugin ‘scrooloose/nerdtree’

“快速查找
Plugin ‘kien/ctrlp.vim’

“快速注释
Plugin ‘scrooloose/nerdcommenter’

“自动补全
Plugin ‘Shougo/neocomplcache.vim’

“xml
Plugin ‘mattn/emmet-vim’

“Plugin ‘xml.vim’

” 来自vim

” non github repos

call vundle#end()            ” required

” ==============================================================================
filetype plugin indent on    ” required
” To ignore plugin indent changes, instead use:
“filetype plugin on

” ==============================================================================
” vundle命令
” :PluginList       – lists configured plugins
” :PluginInstall    – installs plugins; append `!` to update or just :PluginUpdate
” :PluginSearch foo – searches for foo; append `!` to refresh local cache
” :PluginClean      – confirms removal of unused plugins; append `!` to auto-approve removal

” ==============================================================================
” 组件设置
” flazz/vim-colorschemes,主题设置

“NERDTree 插件配置
map <F3> :NERDTreeToggle<CR>
autocmd bufenter * if (winnr(“$”) == 1 && exists(“b:NERDTree”) && b:NERDTree.isTabTree()) | q | endif
let NERDTreeShowHidden = 1 “NERDTREE显示隐藏文件
” ==============================================================================
” vim原生设置
” set rnu “显示相对行号
set nu
syntax on ” 打开语法检测

set tabstop=2 “设置tab键长度
set sw=2
set ts=2

set list “设置空格显示为+号
set listchars=trail:+

set foldmethod=syntax “代码折叠
set foldlevelstart=99 “默认不折叠

set cursorline  “设置光标行
set noswapfile “不要生成swap文件
set nobackup
set bufhidden=hide “当buffer被丢弃的时候隐藏它
set guicursor=n-v-c:hor10 “normal下贯标显示为下划线
set expandtab                 “Use space instead of tabs

let mapleader = “,”  “设置外部复制粘帖
let g:mapleader = “,”
map Y “+y
map P “+p

“noremap ok o<esc> “插入新行

” Change cursor shape between insert and normal mode in iTerm2.app
if $TERM_PROGRAM =~ “iTerm.app”
let &t_SI = “\<Esc>]50;CursorShape=1\x7″ ” Vertical bar in insert mode
let &t_EI = “\<Esc>]50;CursorShape=0\x7″ ” Block in normal mode
endif

“neocomplcache.vim
let g:neocomplcache_enable_at_startup = 1 “打开vim时自动打开
let g:neocomplcache_force_overwrite_completefunc = 1

gazebo入门测试

First step with gazebo and ros

• setup a ROS workspace
• create projects for your simulated robot
• create a Gazebo world
• create your own robot model
• connect your robot model to ROS
• use a teleoperation node to control your robot
• add a camera to your robot
• use Rviz to vizualize all the robot information

Setup a new workspace

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ..
catkin_make
source ~/catkin_ws/devel/setup.bash

Create projects for your simulated robot

cd ~/catkin_ws/src
catkin_create_pkg mybot_gazebo gazebo_ros
catkin_create_pkg mybot_description
catkin_create_pkg mybot_control

Creating your own World

roscd mybot_gazebo 
mkdir launch worlds
cd worlds
vim mybot.world

A basic world file defines at least a name:

world是我们调用所有model的接口,包括机器人也是一个model,在此处调用。

<?xml version="1.0"?>
<sdf version="1.4">
<world name="myworld">
</world>
</sdf>

At first we just want to add some basic  , like a ground and a basic illumination source inside the world tag. include标签包含的是model,我们在这里引入了三个model。

<include>
    <uri>model://sun</uri>
</include>

<include>
    <uri>model://ground_plane</uri>
</include>

<include>
    <uri>model://turtlebot</uri>
</include>
roscd mybot_gazebo/launch
vim mybot_world.launch

mybot_world.launch

launch文件的主要作用是调用其他文件。其中,arg是参数的意思。就这样,我们通过launch调用了一个world文件——mybot.world,然后world调用了其他的model。

<launch>      
    <include file="$(find gazebo_ros)/launch/empty_world.launch">       
        <arg name="world_name" value="$(find mybot_gazebo)/worlds/mybot.world"/>        
        <arg name="gui" value="true"/>    
    </include>  
</launch>

make a test

roslaunch mybot_gazebo mybot_world.launch

Creating your own Model

roscd mybot_description
mkdir urdf
cd urdf
gedit mybot.xacro
XACRO CONCEPTS

• xacro:include: Import the content from other file. We can divide the content in different xacros and merge them using xacro:include.
• property: Useful to define constant values. Use it later using ${property_name}
• xacro:macro: Macro with variable values. Later, we can use this macro from another xacro file, and we specify the required value for the variables. To use a macro, you have to include the file where the macro is, and call it using the macro’s name and filling
the required values.

mybot.xacro

This file will be the main description of our robot. Let’s put some xacro basic structure:

<?xml version="1.0"?>
<robot name="mybot" xmlns:xacro="http://www.ros.org/wiki/xacro">
        <!-- Put here the robot description -->
</robot>

Let’s define some physical properties for our robot, mainly the dimensions of the chassis, the caster wheel, the wheels and the camera:

<xacro:property name="PI" value="3.1415926535897931"/>

<xacro:property name="chassisHeight" value="0.1"/>
<xacro:property name="chassisLength" value="0.4"/>
<xacro:property name="chassisWidth" value="0.2"/>
<xacro:property name="chassisMass" value="50"/>

<xacro:property name="casterRadius" value="0.05"/>
<xacro:property name="casterMass" value="5"/>

<xacro:property name="wheelWidth" value="0.05"/>
<xacro:property name="wheelRadius" value="0.1"/>
<xacro:property name="wheelPos" value="0.2"/>
<xacro:property name="wheelMass" value="5"/>

<xacro:property name="cameraSize" value="0.05"/>
<xacro:property name="cameraMass" value="0.1"/>

We will also include three files :

 <xacro:include filename="$(find mybot_description)/urdf/mybot.gazebo" />
 <xacro:include filename="$(find mybot_description)/urdf/materials.xacro" />
 <xacro:include filename="$(find mybot_description)/urdf/macros.xacro" />

These three correspond respectively to:

• all the gazebo-specific aspects of our robot
• definition of the materials used (mostly colors)
• definitions of some macros for easier description of the robot

Add it to mybot.xacro

其中,collision代表碰撞标签,用于仿真过程中的碰撞体积计算。visual代表可视化,如果不定义,那么laser或者camera就看不到。inertial代表物体的惯性,如果不设置,那么当驱动它时候,默认密度为0,加速度会无穷大。

<link name='chassis'>
  <collision> 
    <origin xyz="0 0 ${wheelRadius}" rpy="0 0 0"/> 
    <geometry> 
      <box size="${chassisLength} ${chassisWidth} ${chassisHeight}"/> 
    </geometry> 
  </collision>
  <visual> 
    <origin xyz="0 0 ${wheelRadius}" rpy="0 0 0"/> 
    <geometry> 
      <box size="${chassisLength} ${chassisWidth} ${chassisHeight}"/> 
    </geometry> 
    <material name="orange"/>
  </visual>
  <inertial> 
    <origin xyz="0 0 ${wheelRadius}" rpy="0 0 0"/> 
    <mass value="${chassisMass}"/> 
    <box_inertia m="${chassisMass}" x="${chassisLength}" y="${chassisWidth}" z="${chassisHeight}"/>
  </inertial>
</link>

Add it to mybot.gazebo

在gazebo的显示中,chassis显示为橙色。

<gazebo reference="chassis">
  <material>Gazebo/Orange</material>
</gazebo>

Add this in the “materials.xacro” :

定义材料颜色。

<?xml version="1.0"?>
<robot>
<material name="black">
  <color rgba="0.0 0.0 0.0 1.0"/>
</material>

<material name="blue">
  <color rgba="0.0 0.0 0.8 1.0"/>
</material>

<material name="green">
  <color rgba="0.0 0.8 0.0 1.0"/>
</material>

<material name="grey">
  <color rgba="0.2 0.2 0.2 1.0"/>
</material>

<material name="orange">
  <color rgba="${255/255} ${108/255} ${10/255} 1.0"/>
</material>

<material name="brown">
  <color rgba="${222/255} ${207/255} ${195/255} 1.0"/>
</material>

<material name="red">
  <color rgba="0.8 0.0 0.0 1.0"/>
</material>

<material name="white">
  <color rgba="1.0 1.0 1.0 1.0"/>
</material>
</robot>

Add this in the macros.xacro file, within the robot tag

定义各种宏,下面包括气缸,方盒子和球的物理惯性定义。

<?xml version="1.0" ?>
<robot name="mybot" xmlns:xacro="http://www.ros.org/wiki/xacro">

<macro name="cylinder_inertia" params="m r h">
  <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}"
  />
</macro>

<macro name="box_inertia" params="m x y z">
  <inertia  ixx="${m*(y*y+z*z)/12}" ixy = "0" ixz = "0"
    iyy="${m*(x*x+z*z)/12}" iyz = "0"
    izz="${m*(x*x+z*z)/12}"
  />
</macro>

<macro name="sphere_inertia" params="m r">
  <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}"
  />
</macro>

</robot>

Add this before the chassis link in the mybot.xacro file :

<link name="footprint" />

<joint name="base_joint" type="fixed">
  <parent link="footprint"/>
  <child link="chassis"/>
</joint>

mybot_world.launch by adding the following two tags in the launch tag:

将.xacro文件转换成urdf文件,xacro文件的优势在于可以include,所以设计中更方便,但是gazebo调用时必须使用urdf文件。第二段时将的description量产成gazebo中的节点。

<!-- urdf xml robot description loaded on the Parameter Server, converting the xacro into a proper urdf file-->
<param name="robot_description" command="$(find xacro)/xacro.py '$(find mybot_description)/urdf/mybot.xacro'" />

<!-- push robot_description to factory and spawn robot in gazebo -->
<node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen"
 args="-urdf -param robot_description -model mybot" />

make a test

 roslaunch mybot_gazebo mybot_world.launch 

mybot.xacro As a next step we add a caster wheel to the robot. This is the simplest wheel as we have no axis and no friction

万向轮的添加。

<joint name="fixed" type="fixed">
  <parent link="chassis"/>
  <child link="caster_wheel"/>
</joint>

<link name="caster_wheel">
  <collision>
    <origin xyz="${casterRadius-chassisLength/2} 0 ${casterRadius-chassisHeight+wheelRadius}" rpy="0 0 0"/>
    <geometry>
      <sphere radius="${casterRadius}"/>
    </geometry>
  </collision>
  
  <visual>
    <origin xyz="${casterRadius-chassisLength/2} 0 ${casterRadius-chassisHeight+wheelRadius}" rpy="0 0 0"/>
    <geometry>
      <sphere radius="${casterRadius}"/>
    </geometry>
    <material name="red"/>
  </visual>

  <inertial>
    <origin xyz="${casterRadius-chassisLength/2} 0 ${casterRadius-chassisHeight+wheelRadius}" rpy="0 0 0"/>
    <mass value="${casterMass}"/>
    <sphere_inertia m="${casterMass}" r="${casterRadius}"/>
  </inertial>
</link>

mybot.gazebo Add a gazebo tag in the gazebo file for this link :

material 材料,gravity重力,damping factor阻尼因素(即震荡因素) ,mu1,mu2摩擦因子

<gazebo reference="caster_wheel">
  <mu1>0.0</mu1>
  <mu2>0.0</mu2>
  <material>Gazebo/Red</material>
</gazebo>

As usual, we specify the color used in material. We also added mu1 and mu2, with value 0 to remove the friction.

macros.xacro .We could add the two links in the main file, but let’s make one macro to make it simple.

这是一个轮子的函数,变量是lr和tY,这里面的变量都是类似于宏定义的替换。

<macro name="wheel" params="lr tY">

<link name="${lr}_wheel">
  <collision>
    <origin xyz="0 0 0" rpy="0 ${PI/2} ${PI/2}" />
    <geometry>
      <cylinder length="${wheelWidth}" radius="${wheelRadius}"/>
    </geometry>
  </collision>

  <visual>
    <origin xyz="0 0 0" rpy="0 ${PI/2} ${PI/2}" />
    <geometry>
      <cylinder length="${wheelWidth}" radius="${wheelRadius}"/>
    </geometry>
    <material name="black"/>
  </visual>

  <inertial>
    <origin xyz="0 0 0" rpy="0 ${PI/2} ${PI/2}" />
    <mass value="${wheelMass}"/>
    <cylinder_inertia m="${wheelMass}" r="${wheelRadius}" h="${wheelWidth}"/>
  </inertial>
</link>

<gazebo reference="${lr}_wheel">
  <mu1 value="1.0"/>
  <mu2 value="1.0"/>
  <kp  value="10000000.0" />
  <kd  value="1.0" />
  <fdir1 value="1 0 0"/>
  <material>Gazebo/Black</material>
</gazebo>


<joint name="${lr}_wheel_hinge" type="continuous">
  <parent link="chassis"/>
  <child link="${lr}_wheel"/>
<origin xyz="${-wheelPos+chassisLength/2} ${tY*wheelWidth/2+tY*chassisWidth/2} ${wheelRadius}" rpy="0 0 0" />
  <axis xyz="0 1 0" rpy="0 0 0" />
  <limit effort="100" velocity="100"/>
  <joint_properties damping="0.0" friction="0.0"/>
</joint>


<transmission name="${lr}_trans">
  <type>transmission_interface/SimpleTransmission</type>
   <joint name="${lr}_wheel_hinge">
    <hardwareInterface>EffortJointInterface</hardwareInterface>
  </joint>
  <actuator name="${lr}Motor">
    <hardwareInterface>EffortJointInterface</hardwareInterface>
    <mechanicalReduction>10</mechanicalReduction>
  </actuator>
</transmission>

</macro>

mybot.xacro

<wheel lr="left" tY="1"/>
<wheel lr="right" tY="-1"/>

Connect your robot to ROS

Alright, our robot is all nice and has this new car smell, but we can’t do anything with it yet as it has no connection with
ROS In order to add this connection we need to add gazebeo plugins to our model. There are different kinds of plugins:

  • World: Dynamic changes to the world, e.g. Physics, like illumination or gravity, inserting models
  • Model: Manipulation of models (robots), e.g. move the robots
  • Sensor: Feedback from virtual sensor, like camera, laser scanner
  • System: Plugins that are loaded by the GUI, like saving images

First of all we’ll use a plugin to provide access to the joints of the wheels. The transmission tags in our URDF will be used by this plugin the define how to link the joints to controllers. To activate the plugin, add the following to mybot.gazebo:

<gazebo>
  <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
    <robotNamespace>/mybot</robotNamespace>
  </plugin>
</gazebo>

With this plugin, we will be able to control the joints, however we need to provide some extra configuration and explicitely
start controllers for the joints. In order to do so, we’ll use the package mybot_control that we have defined before. Let’s first create the configuration file:

roscd mybot_control
mkdir config
cd config
vim mybot_control.yaml

This file will define three controllers: one for each wheel, connections to the joint by the transmission tag, one for
publishing the joint states. It also defined the PID gains to use for this controller:

mybot:
  # Publish all joint states -----------------------------------
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  
  

  # Effort Controllers ---------------------------------------
  leftWheel_effort_controller:
    type: effort_controllers/JointEffortController
    joint: left_wheel_hinge
    pid: {p: 100.0, i: 0.1, d: 10.0}
  rightWheel_effort_controller:
    type: effort_controllers/JointEffortController
    joint: right_wheel_hinge
    pid: {p: 100.0, i: 0.1, d: 10.0}

Now we need to create a launch file to start the controllers. For this let’s do:

roscd mybot_control
mkdir launch
cd launch
vim mybot_control.launch

In this file we’ll put two things. First we’ll load the configuration and the controllers, and we’ll also start a node that will
provide 3D transforms (tf) of our robot. This is not mandatory but that makes the simulation more complete

<launch>

  <!-- Load joint controller configurations from YAML file to parameter server -->
  <rosparam file="$(find mybot_control)/config/mybot_control.yaml" command="load"/>

  <!-- load the controllers -->
  <node name="controller_spawner"
    pkg="controller_manager"
    type="spawner" respawn="false"
    output="screen" ns="/mybot"
    args="joint_state_controller
      rightWheel_effort_controller
      leftWheel_effort_controller"/>


  <!-- convert joint states to TF transforms for rviz, etc -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="false" output="screen">
    <param name="robot_description" command="$(find xacro)/xacro.py '$(find mybot_description)/urdf/mybot.xacro'" />
    <remap from="/joint_states" to="/mybot/joint_states" />
  </node>

</launch>

make a test

roslaunch mybot_gazebo mybot_world.launch 
roslaunch mybot_control mybot.launch 
rostopic list

We could launch our model on gazebo and then launch the controller, but to save some time (and terminals), we’ll start the controllers automatically by adding a line to the mybot_world.launch in the mybot_gazebo package :

<!-- ros_control mybot launch file -->
<include file="$(find mybot_control)/launch/mybot_control.launch" />
rostopic pub -1 /mybot/leftWheel_effort_controller/command std_msgs/Float64 "data: 1.5"
rostopic pub -1 /mybot/rightWheel_effort_controller/command std_msgs/Float64 "data: 1.0"
rostopic echo /mybot/joint_states

Teleoperation of your robot

Adding a camera

    <joint name="camera_joint" type="fixed">
        <axis xyz="0 1 0" />
        <origin xyz="0 0 0.2" rpy="0 0 0"/>
      <parent link="footprint"/>
      <child link="camera"/>
    </joint>


    <link name="camera">
      <collision>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <box size="${cameraSize} ${cameraSize} ${cameraSize}"/>
        </geometry>
      </collision>

      <visual>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
          <box size="${cameraSize} ${cameraSize} ${cameraSize}"/>
        </geometry>
        <material name="blue"/>
      </visual>

      <inertial>
        <mass value="${cameraMass}" />
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <box_inertia m="${cameraMass}" x="${cameraSize}" y="${cameraSize}" z="${cameraSize}" />
      </inertial>
    </link>

Add the plugin to gazebo file

<gazebo reference="camera">
  <material>Gazebo/Blue</material>
  <sensor type="camera" name="camera1">
    <update_rate>30.0</update_rate>
    <camera name="head">
      <horizontal_fov>1.3962634</horizontal_fov>
      <image>
        <width>800</width>
        <height>800</height>
        <format>R8G8B8</format>
      </image>
      <clip>
        <near>0.02</near>
        <far>300</far>
      </clip>
    </camera>
    <plugin name="camera_controller" filename="libgazebo_ros_camera.so">
      <alwaysOn>true</alwaysOn>
      <updateRate>0.0</updateRate>
      <cameraName>mybot/camera1</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>
rosrun image_view image_view image:=/mybot/camera1/image_raw

Visualisation with RViz

rosrun rviz rviz

整个代码框架如下:

(转)机器人描述–URDF和XACRO

原文链接:http://m.blog.csdn.net/article/details?id=52297524

1. 关于URDF的一些杂谈

URDF(Unified Robot Description Format), 是一种特殊的xml文件格式, 作为机器人的一种描述文件, 在ROS里面大量使用. 接触ROS比较久的同学, 应该会经常见到一种类似命名的包(package) – xxx_description. 这个包里面就是包含某个机器人的描述文件. 比如pr2_decription, baxter_descrition, 以及ur_description等. 上述举例的机器人描述包都是可以通过apt-get的方式进行安装. 使用命令格式如斯: sudo apt-get install ros-indigo-pr2-descrition, 其中indigo是你所安装的ROS版本名, 后面就是所需要安装的包名, 下划线用中画线代替.

对机器人使用gazebo进行仿真时, 需要加载的机器人模型就是urdf模型, 当然, 单纯的urdf是不能精确描述机器人以及所需要仿真的世界的. gazebo对其进行了扩展, 感兴趣的朋友可以查看gazebo官网的一些教程. 其中会提供一些标签, 对系统动态, 重心等的设定.

如果想使用开源库moveit对机器人进行路径规划, 在moveit setup assistant教程中, 第一步就是关于如何将机器人模型导入进来, 导入的机器人模型就是urdf(导入xacro格式时也是先将其解析为urdf).

诸如这些应用, 当然还不限于这些应用, 可以看到, 了解URDF以及会使用URDF是一件很重要的事情. 而xacro文件, 是提供了一些更为高级编辑方式的宏文件. 这种格式的文件, 在使用时, 均先会调用rosrun xacro xacro.py xxx.urdf.xacro > xxx.urdf, 将其解析成对应的urdf文件. 然后再使用.

下述内容, 仅仅是对urdf文件编辑和查看由最基础的了解, 以方便能够看得懂机器人描述文件, 以及该怎么利用别人已经写好的描述文件进行组合, 重构得到自己的机器人描述文件. 如果是需要更详细, 精确的描述, 则还需要自己再去对urdf文件进行学习.

2. URDF文件

URDF教程中, 第一个出现的就是下图, 很形象的将URDF要定义的主要内容给展现了出来. 一般, 机器人都是由link和joint进行描述. 都会呈现为树状(想象数据结构里面的树), 如图1, 由一个根link(link1)向上, 分别出现了两个分支–link2和link3, 分别由joint连接link. link4就可以类似的理解.


这里写图片描述
了解机器人的一般描述方式之后, 我们来看一下下图中这个形状的机器人该怎么来描述它.

<robot name="test_robot">
  <link name="link1" />
  <link name="link2" />
  <link name="link3" />
  <link name="link4" />

  <joint name="joint1" type="continuous">
    <parent link="link1"/>
    <child link="link2"/>
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
  </joint>

  <joint name="joint3" type="continuous">
    <parent link="link3"/>
    <child link="link4"/>
  </joint>
</robot>

从上述内容可以看到, 机器人最重要的两个内容 – link和joint, 是如何进行定义. 文件都定义了哪些标签, 以及该怎么使用. 其中内容很简单, 我就不浪费篇幅了.

细心的朋友肯定能够感受到, 虽然能够想象的出来大概是一个什么样子, 但是上面的内容是不能够唯一确定一个机器人或者一个…东西…, 因为每个link长什么样子?他们又是一个什么样子的位置关系? 这些在上面的内容中都是没有定义的. 如图中所示, 可能现在每一个不同的同学, 所联想到的样子都是不一样的, 一个仙人掌? 一个两指的夹持器? anythin..当然, 上面所示内容的urdf文件是不能够被正确解析的, 也是不能够可视化出来的. 但上面内容就类似于整个机器人的骨架, 机器人就由这些东西组成. 一共拥有4个link, 和3个joint, 像图中所示的样子连接起来.

2.2 位置

在定义好了机器人的骨架后, 进一步我们可以使用origin子标签进行定义link所应该在的位置. 但是有一点应该注意到, link和link之间是使用joint进行连接, 那么link的位置, 就由连接他的joint确定. 所以, 该子标签是定义在joint内. 在三维空间中, 要精确描述一个刚性体的姿态, 仅仅使用他的xyz坐标是不够的, 还需要使用rpy. rpy角是描述船舶在海中航行时姿态的一种方法. 将船的行驶方向取为z轴, 绕z轴旋转称为滚动(Roll), 绕y轴旋转称为俯仰(Pitch), 绕x轴旋转称为偏转(Yaw). 这种描述方式大量运用于各个领域. 依稀记得, kinect2关于脸部模型匹配的DEMO程序里面, 对脸部的描述就用到了这种描述方式来描述姿态. 在机器人中, 当然运用就更多了. 现在对之前的内容进行扩充. 其中rpy代表的是角度, 用弧度表示.

<robot name="test_robot">
  <link name="link1" />
  <link name="link2" />
  <link name="link3" />
  <link name="link4" />


  <joint name="joint1" type="continuous">
    <parent link="link1"/>
    <child link="link2"/>
    <origin xyz=".5 .3 0.7" rpy="0 0 0" />
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
    <origin xyz="-.2 .5 -0.3" rpy="0 0 1.57" />
  </joint>

  <joint name="joint3" type="continuous">
    <parent link="link3"/>
    <child link="link4"/>
    <origin xyz=".5 0 0.2" rpy="0 0 -1.57" />
  </joint>
</robot>

上述位置关系定义如下图所示. xyz就如同一个平移向量, 将下一个link的原点坐标移动到下一个位置(起点是父link的原点). 同时, 你也可以多尝试几次rpy, 体会下一个坐标系是如何进行变换的. 虽然现在还没有任何东西出来, 但每个link的空间位置以及姿态已经被我们所指定了.


link_graph

2.3 形状

在解决了每个link的相对位置之后, 还有一个很关键的问题, 就是每个link长什么样子呢? 圆的? 扁的? 还是奇形怪状的? 下面示例了一些常用的形状, 以及可能会导入的一些奇形怪状的东西. 不但可以导入stl格式的文件, 还可以导入dae格式.下述示例中导入了一个小刀.

<?xml version="1.0"?>
<robot name="test_robot">
  <link name="link1">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2" />
      </geometry>
    </visual>
  </link>

  <link name="link2">
    <visual>
      <geometry>
        <box size="0.6 0.2 .1" />
      </geometry>
    </visual>
  </link>

  <link name="link3" >
    <visual>
      <geometry>
        <sphere radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="link4" >
    <visual>
      <origin rpy="0 -1.57 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://urdf_csdn/urdf/mesh/knife.stl"/>
      </geometry>
    </visual>
  </link>


  <joint name="joint1" type="fixed">
    <parent link="link1"/>
    <child link="link2"/>
    <origin xyz="0.22 0 0.6" rpy="0 1.57 0" />
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
    <origin xyz="-0.1 0.5 0" />
  </joint>

  <joint name="joint3" type="fixed">
    <parent link="link3"/>
    <child link="link4"/>
    <origin xyz=".5 0 0" rpy="0 0 -1.57" />
  </joint>
</robot>

2.4 Collision 和 joint限制

当然, 每个link一般是不会产生重合的, 在运动规划的时候, 也会去避免碰撞到自己, 所以针对于每一个link, 还有一个collision标签, 和visual标签内容完全一样.

前面内容可以看到, 每个link可以看作是一个刚体, 刚体和刚体之间是通过joint进行连接, 那么, 问题就来了. 这个joint是固定的? 还是可以任意的动? 如果可以动, 那么, 问题又来了, 极限位置是多少? 等等等等…

比如, 我们限定joint2只能沿着y轴旋转, 则需要添加<axis xyz="0 1 0"/>, 类似的, 可以指定其他关节的转动轴, 例如<axis xyz="-0.2 0.1 1"/>.

比如, 我们要限定joint2的移动范围, 则需要添加<limit lower="-3.14" upper="3.14" effort="150.0" velocity="3.15"/>, 从标签中可以看到, 上下限以及速度, 力矩等都是可以指定的.

<?xml version="1.0"?>
<robot name="test_robot">
  <link name="link1">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2" />
      </geometry>
    </visual>

    <collision>
      <origin xyz="0.0 0 0.0" rpy="0 0 0" />
      <geometry>
        <cylinder length="0.6" radius="0.2" />
      </geometry>
    </collision>
  </link>

  <link name="link2">
    <visual>
      <geometry>
        <box size="0.6 0.2 .1" />
      </geometry>
    </visual>
  </link>

  <link name="link3" >
    <visual>
      <geometry>
        <sphere radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="link4" >
    <visual>
      <origin rpy="0 -1.57 0" xyz="0 0 0"/>
      <geometry>
        <mesh filename="package://urdf_csdn/urdf/mesh/knife.stl"/>
      </geometry>
    </visual>
  </link>


  <joint name="joint1" type="fixed">
    <parent link="link1"/>
    <child link="link2"/>
    <origin xyz="0.22 0 0.6" rpy="0 1.57 0" />
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
    <origin xyz="-0.1 0.5 0" />
    <axis xyz="0 1 0"/>
    <limit lower="-3.14" upper="3.14" effort="150.0" velocity="3.15"/>
  </joint>

  <joint name="joint3" type="fixed">
    <parent link="link3"/>
    <child link="link4"/>
    <origin xyz=".5 0 0" rpy="0 0 -1.57" />
  </joint>
</robot>

2.5 可视化

查看urdf文件, 可以使用urdf_tutorial包, 命令格式roslaunch urdf_tutorial display.launch model:=path/to/your/xxx.urdf, 会使用Rviz进行显示, 如上述内容, 进行显示之后, 可以得到下图所示内容. 坐标系图示, 需要添加TF条目进行显示. 值得注意的地方, 将Global Options中的fixed frame设定为link1. 如果你设定了可移动的关节, 想查看以下关节移动的效果以及设定等, 使用roslaunch urdf_tutorial display.launch model:=path/to/your/xxx.urdf gui:=true, 你会看到弹出一个控制面板(如果没找到, 再好好找一找, 或许真的很小).


这里写图片描述
通过上述方式, 在rviz中正确显示模型之后, 新打开一个命令行, 输入rostopic list命令, 可以查看到类似如下的输出. 可以看到, 开启了/joint_states话题(Topic), 使用rostopic echo /joint_states可以看到话题数据.


这里写图片描述

3. XACRO文件

前面也提到了, XACRO文件和URDF实质上是等价的. XACRO格式提供了一些更高级的方式来组织编辑机器人描述. 主要提供了三种方式来使得整个描述文件变得简单. 借用在教程中一句话来形容xacro的优势: “Fortunately, you can use the xacro package to make your life simpler”.

3.1 Constants

Usage: <xacro:property name="WIDTH" value="2.0"/>

类似于C语言中的宏定义, 在头部定义, 如<xacro:property name="WIDTH" value="2.0"/>, 以${WIDTH}的方式进行使用. 经常会看到的一个常量定义, <property name="PI" value="3.14159265" />. 还有定义一个前缀, 这样后面关节名都可以方便的进行修改. 比如<property name="prefix" value="my_"/>, 后面关节名字就可以类似的进行更新. <joint name="${prefix}joint1" type="revolute"/>.

在有了上面的常量定义之后, 类似于宏定义, 完成字符串替换, 同时还可以进行一些简单的数学运算.

Usage: ${1/2}, ${PI*(WIDTH*0.5)}

3.2 Macros

这个才是xacro文件中最重要的部分. 就像宏函数一样, 完成一些最小模块的定义, 方便重用, 以及可以使用参数来标识不同的部分.

3.2.1 Simple Macro

Usage:

<xacro:macro name="default_origin">
    <origin xyz="0 0 0" rpy="0 0 0"/>
</xacro:macro>
<xacro:default_origin />

前面三行对宏进行定义, 第四行是使用.

3.2.2 Parameterized Macro

Usage:

<xacro:macro name="default_link" params="prefix">
    <link name="${prefix}_link1" />
</xacro:macro>
<xacro:default_link prefix="my" />

类似, 前三行定义, 第四行是进行使用. 当然, 不单由这样简单的参数, 还可以使用块参数.
Usage:

<xacro:macro name="default_link" params="prefix *origin">
    <link name="${prefix}_link1" >
        <xacro:insert_block name="prigin" />
    </link>
</xacro:macro>
<xacro:default_link prefix="my">
    <origin xyz="0 0 0" rpy="0 0 0" />
</xacro:default_link>

一般情况下, 很多已有的机器人模型, 都是以xacro格式提供描述, 而在xacro文件中, 整个机器人定义为一个很大的宏. 例如, barrett hand, 想进一步了解的朋友可以点击前面的链接, 查看以下barrett hand是如何进行描述的.

3.2.3 Include

很多模型都是已宏的形式进行定义, 并以最小集团分成很多个文件. 而最终的机器人描述就变得非常简单了. 下面摘录一个ur5的描述文件. 从中可以看出来xacro的强大优势. 在最后的示例中我们还能够看到, urdf文件也是能够直接导入进来的.

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="ur5" >

  <!-- common stuff -->
  <xacro:include filename="$(find ur_description)/urdf/ur5/common.gazebo.xacro" />

  <!-- ur5 -->
  <xacro:include filename="$(find ur_description)/urdf/ur5/ur5.urdf.xacro" />

  <!-- arm -->
  <xacro:ur5_robot prefix="" joint_limited="false"/>

  <link name="world" />

  <joint name="world_joint" type="fixed">
    <parent link="world" />
    <child link = "base_link" />
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
  </joint>

</robot>

当然, 此时的简单是建立在之前的复杂的基础上的. 从上述内容中可以看到, 首先是在ur_description包中找到另外几个xacro文件, 将其包含进来. 当然应该注意到, include类似于C语言中的include, 先将该文件扩展到包含的位置. 但包含进来的文件很有可能只是一个参数宏的定义. 并没有被调用. 所以, 示例中调用了一个宏(<xacro:ur5_robot prefix="" joint_limited="false"/>), 产生一个ur5机器人.

3.3 可视化

urdf_tutorial包也是可以查看xacro文件的. 使用roslaunch urdf_tutorial xacrodisplay.launch model:=path/to/your/xxx.urdf.xacro.

4. 关于urdf_tutorial

前面提到的可视化都是使用urdf_tutorial包进行的. 分别调用了两个launch文件. 在上面的示例中我们还看到了不但会使用rviz进行可视化, 还会发起一些话题等. 其实这些我们能够从他的launch文件中一窥究竟.

打开命令行, 输入: rosed urdf_tutorial dispaly.launch. 会使用vim打开该文件. 可以看到下述内容.

<launch>
  <arg name="model" />
  <arg name="gui" default="False" />
  <param name="robot_description" textfile="$(arg model)" />
  <param name="use_gui" value="$(arg gui)"/>
  <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
</launch>

由上可以看到, 参数model是没有默认值的, 所以调用该launch文件必须指定model参数. 其他都比较易懂, 主要解释以下robot_description, 可以看到, 其前面是param. 这个是指定ros 参数服务器中的参数值. 而打开rviz之后, rviz就是直接从参数服务器中读取机器人描述文件, 也就是这个参数. 然后进行显示. use_gui也是如此对显示产生的影响. 另外, 还发起了两个发布者节点, 分别发布joint_states和robot_state. 这也就是会由joint_states话题的原因. xacrodispaly.launch文件和上面类似, 但在处理文件时, 使用的是: <param name="robot_description" command="$(find xacro)/xacro.py $(arg model)" />. 在launch中将xacro文件解析为urdf.

至于其中启动的两个节点, joint_state_publisher 和 robot_state_publisher, 可以查看ROS Answer上相关的解释. 另外, 在robot_state_publisher概述中提到, robot_state_publisher从/joint_states话题中获取机器人joint角度作为输入, 使用机器人的运动学树模型计算出机器人link的3D姿态, 然后将其发布到话题/tf/tf_static. joint_state_publisher从ROS参数服务器中读取robot_description参数, 找到所有non-fixed joint, 发布他们的JointState消息到/joint_states话题.

5. 排列组合

5.1 UR + Barrett

有了前面的基础之后, 我们就可以进行一些属于我们自己的私人定制了. 比如说, 使用ur5作为手臂, 接上barrett hand或者shadow hand. 这样就可以得到一个完整的操作模型了. 先看一下效果.


这里写图片描述
UR Description

首先需要下载所需要的UR机械臂的包, 打开命令行, 输入: git clone https://github.com/ros-industrial/universal_robot.git, 下载下来之后, 在universal_robot文件夹内有一个叫ur_description文件夹, 这里面就是我们需要的机器人描述文件.

* Barrett Hand Description*

https://github.com/RobotnikAutomation/barrett_hand/tree/hydro-devel中, 下载得到bhand_description, 就是我们所需要的barrett hand描述文件.

* 组合 *

将前面得到的ur_description和bhand_description拷贝到catkin_ws目录下(确保能够找到这两个包), 到catkin_ws目录下, 运行catkin_make. 注意查看提示信息, 是否发现ur_description和bhand_description这两个包.

以下述内容新建一个文件, 以xxx.urdf.xacro格式命名. 运行roslaunch urdf_tutorial xacrodisplay.launch model:=path/to/your/xxx.urdf.xacro来进行显示. 最终结果就如上图所示. 从下面的描述来看, 是不是很简洁?

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="ur5bh" >

  <!-- common stuff -->
  <xacro:include filename="$(find ur_description)/urdf/common.gazebo.xacro" />

  <!-- ur5 -->
  <xacro:include filename="$(find ur_description)/urdf/ur5.urdf.xacro" />

  <!-- barrett hand -->
  <xacro:include filename="$(find bhand_description)/urdf/bh282.urdf.xacro" />

  <!-- arm -->
  <xacro:ur5_robot prefix="" joint_limited="true"/>

  <link name="world" />

  <joint name="world_joint" type="fixed">
    <parent link="world" />
    <child link = "base_link" />
    <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
  </joint>

  <!-- end effector -->
  <xacro:bhand_macro parent="ee_link" name="bh">
    <origin xyz="0.012 0.0 0.0" rpy="${pi/2.0} ${pi/2.0} ${pi/2.0}"/>
  </xacro:bhand_macro>

</robot>

5.2 Baxter + YCB

有些时候, 我们不但需要机器人, 同时还需要一些场景, 比如机器人面前的一个桌子, 桌子上面放一些物品等, 或者一些稀奇古怪的东西, 放在机器人旁边, 和机器人一起导入来运行. 就比如下图所示的样子.


这里写图片描述
* Baxter *

可以使用另外一种方式来获取Baxter的描述文件. 打开命令行, 以此输入:

$ sudo apt-get install ros-indigo-baxter-description
$ cd ~/catkin_ws/src/
$ cp -r /opt/ros/indigo/baxter_description ./
$ rosrun xacro xacro.py --inorder baxter_description/urdf/baxter.urdf.xacro\
> baxter_description/urdf/baxter_new.urdf

如上所述, 一定得注意最后一条指令, 可以参考Github上xacro的一条Issues, 其中一定需要添加--inorder, 参数. 否则生成模型会失败. 所以我们提前将baxter的xacro文件转换成urdf格式.

* The YCB Object and Model Set *

http://rll.eecs.berkeley.edu/ycb/上, 可以下载到一些物体的三维模型以及urdf文件. 进入网站之后, 点击下载ROS packages for setup descriptions of ‘Pitcher-Mug Protocol’ and ‘Table Setting Protocol’ in Gazebo simulation environment. 将下载下来的文件解压到和前述文件中的同级目录中. 其中有一些launch文件, 可以运行起来, 看一看效果. 挺好玩的.

* 排列 *

所有东西都准备好之后, 将下述内容拷贝到一个新的xacro文件中. 和之前一样, 运行并显示. 可以得到前述图像中的样子. 和之前的类似, viz打开之后, 需要将Fixed Frame设定成world, 模型才能正常显示.

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="baxter_and_world" >

  <link name="world"/>

  <joint name="world_to_baxter" type="fixed">
    <parent link="world"/>
    <child link="base"/>
  </joint>

  <!-- baxter -->
  <xacro:include filename="$(find baxter_description)/urdf/baxter_new.urdf" />

  <!-- table -->
  <xacro:include filename="$(find ycb_object_models)/models/urdf/table.urdf" />

  <joint name="base_table" type="fixed" >
    <parent link="world"/>
    <child link="table_top_link"/>
    <origin xyz="1 0 -0.7" />
  </joint>

</robot>

 

gazebo-设计自己的package

  1. 在工作目录的src下,创建两个package,用catkin_create_pkg创建。

/MYROBOT_description

机器人模型与描述文件

/MYROBOT_gazebo

world文件与launch文件

文件夹结构如下面所示。

../catkin_ws/src
    /MYROBOT_description
        package.xml
        CMakeLists.txt
        /urdf
            MYROBOT.urdf
        /meshes
            mesh1.dae
            mesh2.dae
            ...
        /materials
        /cad
    /MYROBOT_gazebo
        /launch
            MYROBOT.launch
        /worlds
            MYROBOT.world
        /models
            world_object1.dae
            world_object2.stl
            world_object3.urdf
        /materials
        /plugins

2. 在launch目录创建myrobot.launch文件。

<launch>
  <!-- We resume the logic in empty_world.launch, changing only the name of the world to be launched -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(find myrobot_gazebo)/worlds/myrobot.world"/>
    <!-- more default parameters can be changed here -->
  </include>
</launch>

3. 在world文件夹中创建world文件,这里我们直接调用网上下载的agvs_office.world,改名为myrobot.world。

4. 运行

. ~/work_space/devel/setup.bash
roslaunch myrobot_gazebo myrobot.launch

5. 到这里我们就已经运行起来我们的world地图了。

Gazebo运行——安装ARIAC

ARIAC是一个自动仓储的运行环境,在Gazebo上有,比较适合我以后的方向,所以第一目标是在Gazebo上运行ARIAC。Gazebo上有相应的介绍和安装运行步骤。

  1. sudo apt-get install ariac

这个在ubuntu 16.04的环境中没法实现,所以直接下载code编译。

2. 设置工作空间

mkdir -p ~/ariac_ws/src
cd ~/ariac_ws

3. 下载代码

cd ~/ariac_ws/src
git clone https://bitbucket.org/osrf/ariac

4.安装支持包

sudo apt-get install ros-indigo-image-common ros-indigo-geometry-msgs ros-indigo-gazebo-ros-control \
  ros-indigo-ros-controllers ros-indigo-controller-manager ros-indigo-effort-controllers \
  ros-indigo-joint-state-publisher ros-indigo-joint-state-controller ros-indigo-robot-state-publisher \
  ros-indigo-xacro

5.运行安装程序

source /opt/ros/indigo/setup.bash
cd ~/ariac_ws
catkin_make install
source ~/ariac_ws/install/setup.bash

6.运行例程

$ source /opt/ros/kinetic/setup.bash
$ rosrun osrf_gear gear.py -f `catkin_find --share osrf_gear`/config/comp_conf2.yaml ~/helloworld_ws/src/ariac_example/config/sample_gear_conf.yaml -o /tmp
$ source ~/helloworld_ws/devel/setup.bash
$ rosrun ariac_example ariac_example_node

(转) W520 + Ubuntu 12.04LTS, 13.10, 14.04LTS安装Nvidia显卡驱动设置

本人W540,安装ubuntu 16.04之后,Nvidia显卡驱动安装正常,但是Gazebo的运行兼容性太差,考虑到ROS的学习,换成Ubuntu 14.04,但是Nvidia的驱动安装不正常。另外,在此基础上,关注secure boot的影响。

原文地址:

http://blog.csdn.net/ubuntu64fan/article/details/12614967

Thinkpad W520带有双显卡:集显Intel 3000和独显Nvidia 1000m/2000m。Nvidia为Windows提供了官方的Optimus驱动支持,可以在集显和独显之间自动切换。在Ubuntu下却遇到了奇怪的问题:如果BIOS里选择使用独显,无法安装Ubuntu(如果在集显安装后,再切换到独显,会无法启动Ubuntu, 偶尔可以启动)。这又带来了另一个问题,因为W520的集显只能输出到笔记本屏幕,要外接显示器,必须使用独显。好在Linux有一个活跃的社区,只要Google一下、折腾一番,总是能找到解决方法。

我自己的解决过程如下:

(1)进入BIOS,在 Configuration -> Display选项中,选择使用集显(Integrated Graphic Card),并且禁用Optimus识别。然后安装Ubuntu。如果你已经安装了Ubuntu,但是在选择使用独显后,很难成功启动,这时不用重装,请看下一步。

(2)进入BIOS, 在Security->Intel Virtualization(虚拟化)选项,禁用(Disable)VT-D。然后在 Configuration -> Display选项中,选择使用独显(Discrete Graphic Card),并且禁用Optimus识别。重启后,就可以进入Ubuntu了。

(3)这时需要安装Nvidia为Linux提供的专属驱动。首先打开Additional Drivers,这时会出现一个Nvidia驱动列表,选择NVIDIA accelerated graphics driver (version  current) [Recommended],然后点击Activate按钮,就会自动安装Nvidia显卡驱动。

如果要安装最新的Nidia显卡驱动,可以使用下面方法:

sudo apt-get update
sudo apt-get install nvidia-settingssudo apt-get install nvidia-current-dev

重启后,运行NVIDIA X Server Settings,就能看到当前的Nvidia驱动和显卡信息。这时通过VGA或DisplayPort外接显示器也没问题了。

(4)上面方法的问题是,需要在BIOS里禁用VT-D选项。可是我还需要使用虚拟化,要解决这个问题,需要编辑/etc/default/grub,修改GRUB_CMDLINE_LINUX_DEFAULT这一行,加上nox2apic选项:

GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash nox2apic”

然后必须运行:

$ sudo update-grub

重启, 在BIOS就可以启用Intel Virtualization的VT-D,然后仍然能在独显模式下启动Ubuntu。

(5)这时会遇到新问题:按Fn+Home/End组合键时,亮度无法调节。解决方法是修改:

/etc/X11/xorg.conf

在Section “Device”中加入下面一行:

 Option  “RegistryDwords”        “EnableBrightnessControl=1″

如果/etc/X11/xorg.conf不存在,运行:

$ sudo nvidia-xconfig

自动生成这个文件。

然后重启,就可以调节亮度了。

(6) 另外,如果进入Ubuntu登陆界面时,屏幕亮度变为最小。解决方法是编辑

/etc/init.d/rc.local,

加上下面一行(最大亮度值是15,最小是0,可根据自己的需要,修改echo的设置值,参考之前的Thinkpad W520安装Ubuntu 12.04折腾记

echo 12 | sudo tee /sys/class/backlight/acpi_video0/brightness

ROS-收发节点的编写

节点是一个链接到ROS的可执行,下面编写一个发布节点talker来连续发送一个message。

首先,切换到work space下面的某个包中。

roscd beginner_tutorials

在包下面创建一个src文件夹。

mkdir src

src用来当前包下面的源文件。

用vim创建一个src/talker.cpp的文件。

下面是可执行的代码。

 

// ros公共头文件
#include "ros/ros.h"
// 包含std_msgs/String信息,这是String.msg文件自动生成的
#include "std_msgs/String.h"

#include <sstream>

/**
 * This tutorial demonstrates simple sending of messages over the ROS system.
 */
int main(int argc, char **argv)
{
  // Initialize ROS. This allows ROS to do name remapping through
  // the command line -- not important for now. This is also where we
  // specify the name of our node. Node name must be unique in a running system.
  // The name used here must be a base name, ie. it cannot have a / in it.
  ros::init(argc, argv, "talker");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle n;

  /**
   * The advertise() function is how you tell ROS that you want to
   * publish on a given topic name. This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing. After this advertise() call is made, the master
   * node will notify anyone who is trying to subscribe to this topic name,
   * and they will in turn negotiate a peer-to-peer connection with this
   * node.  advertise() returns a Publisher object which allows you to
   * publish messages on that topic through a call to publish().  Once
   * all copies of the returned Publisher object are destroyed, the topic
   * will be automatically unadvertised.
   *
   * The second parameter to advertise() is the size of the message queue
   * used for publishing messages.  If messages are published more quickly
   * than we can send them, the number here specifies how many messages to
   * buffer up before throwing some away.
   */
  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

  ros::Rate loop_rate(10);

  /**
   * A count of how many messages we have sent. This is used to create
   * a unique string for each message.
   */
  int count = 0;
  while (ros::ok())
  {
    /**
     * This is a message object. You stuff it with data, and then publish it.
     */
    std_msgs::String msg;

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

    ROS_INFO("%s", msg.data.c_str());

    /**
     * The publish() function is how you send messages. The parameter
     * is the message object. The type of this object must agree with the type
     * given as a template parameter to the advertise<>() call, as was done
     * in the constructor above.
     */
    chatter_pub.publish(msg);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }


  return 0;
}

Create the src/listener.cpp file within the beginner_tutorials package and paste the following inside it.

#include "ros/ros.h"
#include "std_msgs/String.h"

/**
 * This tutorial demonstrates simple receipt of messages over the ROS system.
 */
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  /**
   * The ros::init() function needs to see argc and argv so that it can perform
   * any ROS arguments and name remapping that were provided at the command line.
   * For programmatic remappings you can use a different version of init() which takes
   * remappings directly, but for most command-line programs, passing argc and argv is
   * the easiest way to do it.  The third argument to init() is the name of the node.
   *
   * You must call one of the versions of ros::init() before using any other
   * part of the ROS system.
   */
  ros::init(argc, argv, "listener");

  /**
   * NodeHandle is the main access point to communications with the ROS system.
   * The first NodeHandle constructed will fully initialize this node, and the last
   * NodeHandle destructed will close down the node.
   */
  ros::NodeHandle n;

  /**
   * The subscribe() call is how you tell ROS that you want to receive messages
   * on a given topic.  This invokes a call to the ROS
   * master node, which keeps a registry of who is publishing and who
   * is subscribing.  Messages are passed to a callback function, here
   * called chatterCallback.  subscribe() returns a Subscriber object that you
   * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
   * object go out of scope, this callback will automatically be unsubscribed from
   * this topic.
   *
   * The second parameter to the subscribe() function is the size of the message
   * queue.  If messages are arriving faster than they are being processed, this
   * is the number of messages that will be buffered up before beginning to throw
   * away the oldest ones.
   */
  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  /**
   * ros::spin() will enter a loop, pumping callbacks.  With this version, all
   * callbacks will be called from within this thread (the main one).  ros::spin()
   * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
   */
  ros::spin();

  return 0;
}

cpp文件是node的文件,为了编译这两个node,必须更改一下包内的package.xml和CMakeList.txt文件。

cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)

## Find catkin and any catkin packages
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)

## Declare ROS messages and services
add_message_files(FILES Num.msg)
add_service_files(FILES AddTwoInts.srv)

## Generate added messages and services
generate_messages(DEPENDENCIES std_msgs)

## Declare a catkin package
catkin_package()

## Build talker and listener
include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

通过下面的代码来运行这两个节点。

# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
$ rosrun beginner_tutorials talker
$ rosrun beginner_tutorials listener