
安装好ROS后,要配置环境变量
# source /opt/ros/ 直接添加到.bashrc文件最好 第一步: 首先,建立一个工作空间: $ mkdir -p ~/test_ws/src 跳至src空文件夹 $ cd ~/test_ws/src 注:src是源文件source的缩写 然后初始化工作空间 $ catkin_init_workspace 这个时候src文件目录下有个CMakeLists.txt文件 然后跳到工作空间top层,因为只有这一层这样才能build $ cd ~/test_ws $ catkin_make 配置环境变量到该工作空间 export ROS_PACKAGE_PATH=~/test_ws:$ROS_PACKAGE_PATH 或直接加入.bashrc //这里只配置到test_ws一级 这个时候test_ws下就有文件夹:build devel src 在'devel'文件夹里面你可以看到几个setup.*sh文件。 source这些文件中的任何一个都可以将当前工作空间设置 在ROS工作环境的最顶层 所以需要: $ source devel/setup.bash 或者加入.bashrc文件 //这里配置到test_ws/src一级 检查是否设置成功: $ echo $ROS_PACKAGE_PATH /home/exbot/test_ws/src:/opt/ros/groovy/share:/opt/ros/groovy/stacks 以上一个完整的工作空间就设置好了,以后要编写程序包 都在这个工作空间之下新建。 注:ROS命令行工具,比如roscd roscpp rospack等等都只能切换到那些路径已经包含在ROS_PACKAGE_PATH环境变量中的软件包,要查看ROS_PACKAGE_PATH中包含的路径可以输入: $ echo $ROS_PACKAGE_PATH 这就是配置环境变量的作用、、、 第二步:创建ROS程序包 首先了解一个程序包的组成: 1、该程序包必须包含catkin compliant package.xml文件 这个package.xml文件提供有关程序包的元信息,也就是基本说明信息,同时还包括重要的依赖包文件声明。 2、程序包必须包含一个catkin 版本的CMakeLists.txt文件,而Catkin metapackages中必须包含一个对CMakeList.txt文件的引用。 3、每个目录下只能有一个程序包。 这意味着在同一个目录下不能有嵌套的或者多个程序包存在 一个包含程序包的简单工作空间看起来就像这样: 命令:catkin_creat_pkg 切换到工作空间下的src文件夹: $ cd ~/test_ws/src 创建一个test_pack的程序包:catkin_create_pkg test_pack std_msgs rospy roscpp 这个程序包依赖于std_msgs、roscpp和rospy; 关于依赖介绍请☞http://wiki.ros.org/cn/ROS/Tutorials/CreatingPackage 这个时候test_pack文件夹下将有 CMakeLists.txt package.xml 和include src 文件夹 其中CMakeLists.txt,package.xml是可以也需要自定义的。 第三步:编译程序包 命令:catkin_make 只能在顶层的工作空间(本例子是test_ws)工作空间运行catkin_make,如果在其它文件夹下运行catkin_make,会出现The specified base path "/home/exbot/test_ws/src" contains a CMakeLists.txt but "catkin_make" must be invoked in the root of workspace的提示。 该命令会编译src文件夹下的所有catkin工程。 直接运行catkin_make只会编译test_pack/src这个默认路径下面的源程序,如果你的源代码不在默认工作空间中(~/catkin_ws/src),比如说存放在了my_src中,那么你可以这样来使用 catkin_make: $ catkin_make --source my_src $ catkin_make install --source my_src # (optionally) catkin_make首先输出它所使用到的每个空间所在的路径 Base path: /home/exbot/test_ws Source space: /home/exbot/test_ws/src Build space: /home/exbot/test_ws/build Devel space: /home/exbot/test_ws/devel Install space: /home/exbot/test_ws/install 这时候在工作空间下面有几个文件夹:build devel(development space) src 没有install space是因为还没有安装这个文件包 具体作用及各个文件介绍详见http://wiki.ros.org/catkin/workspaces#Build_Space build 目录是build space的默认所在位置,同时cmake 和 make也是在这里被调用来配置并编译你的程序包。devel 目录是devel space的默认所在位置, 同时也是在你安装程序包之前存放可执行文件和库文件的地方。 运行节点 在运行任何节点之前,必须要先运行roscore指令; 运行一个节点:rosrun [package_name] [node_name] 查看节点的详细信息rosnode [ping/list/info/kill/machine/cleanup] node_name 关于话题 Rqt:$ rosrun rqt_graph rqt_graph 可以查看节点与节点之间的通信和话题信息图 $ rostopic rostopic bw [topic_name] display bandwidth used by topic rostopic echo [topic_name] print messages to screen rostopic hz [topic_name] display publishing rate of topic rostopic list [topic_name] print information about active topics(显示所有话题的发布者和订阅者) rostopic pub [topic_name] publish data to topic rostopic type [topic_name] print topic type 关于服务 服务(services)是节点之间通讯的另一种方式。服务允许节点发送请求(request) 并获得一个响应(response)。 rossrv show turtlesim/Spawn float32 x float32 y//海龟的x,y坐标 float32 theta//海龟的头部的弧度角 string name --- string name 创建消息和服务 消息:msg文件就是一个描述ROS中所使用消息类型的简单文本文件,它们会被用来生成不同语言的源代码。 服务(srv): 一个srv文件描述一项服务。它包含两个部分:请求和响应。 msg文件存放在package的msg目录下,srv文件则存放在srv目录下。这些文件夹是需要自己新建的。 msg文件实际上就是每行声明一个数据类型和变量名。比如: Header header string child_frame_id geometry_msgs/PoseWithCovariance pose geometry_msgs/TwistWithCovariance twist srv文件分为请求和响应两部分,由'---'分隔。下面是srv的一个样例: int A int B --- int Sum 其中 A 和 B 是请求, 而Sum 是响应。 创建一个消息msg文件 $ cd ~/test_ws/src/test_pack //切换到程序包文件夹 $ mkdir msg//在程序包文件夹下面建立一个msg文件夹 $ echo "int num" > msg/Num.msg//定义一个名为num的int型数据。 然后很重要的一步,要将msg文件编译称为C++,python语言的源程序,必须要借助一些依赖文件,所以需要在程序包中的package.xml中写入 这两句,没有 和 注:package.xml只是提供了一些说明信息,并不会对实际编译造成影响; 真正起到实际作用的是在CMakeLists.txt 文件中的find package()中加入依赖项,比如此处使之成为如下形式: find_package (catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) 有时候你会发现,即使你没有调用find_package,你也可以编译通过。这是因为catkin把你所有的package都整合在一起,因此,如果其他的package调用了find_package,你的package的依赖就会是同样的配置。但是,在你单独编译时,忘记调用find_package会很容易出错。 同样,你需要确保你设置了运行依赖: catkin_package ( ... CATKIN_DEPENDS message_runtime ... ... ) 另外找到如下代码: # add_message_files( # FILES # Message1.msg # Message2.msg # ) 使之变成这样: add_message_files ( FILES Num.msg ) 另外必须确定函数generate_messages()被调用了 # generate_messages( # DEPENDENCIES # std_msgs # ) 使之变成这样: generate_messages( DEPENDENCIES std_msgs ) 关于CMakeLists.txt文件,详情http://wiki.ros.org/catkin/CMakeLists.txt 编写发布器和订阅器 所谓的发布器和订阅器,也即是通过消息进行信息传递的节点。下面将首先介绍编写一个名为“talker”的发布器节点和一个“listener”订阅器节点。 记住:编写一个程序包的程序,都是在程序包内部的src文件里,而不是在外层的工作空间。 cd ~/test_ws/src/test_pack/src,这个目录下将会储存所有test_pack的源代码。 编写talker.cpp程序文件: gedit talker.cpp 写好程序,保存。在相同的目录下写好listener.cpp文件 配置好相应的依赖和目标文件路径详情: http://wiki.ros.org/cn/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29 编写一个服务和客户节点 所谓的服务(service)和客户(client),也就是节点,这组节点是通过服务(srv)来进行通信的,srv它是一个文件,我们之前编写过,通过对srv里面的内容进行读写来达到服务节点和客户节点通信的目的。 首先编写一个简单的service节点("add_two_ints_server"),同样源代码在src文件夹下,命名为add_two_ints_server.cpp,复制例程代码: #include "ros/ros.h" #include "beginner_tutorials/AddTwoInts.h" bool add(beginner_tutorials::AddTwoInts::Request &req, beginner_tutorials::AddTwoInts::Response &res)通过地址改变srv中的值 { res.sum = req.a + req.b; ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b); ROS_INFO("sending back response: [%ld]", (long int)res.sum); //返回响应,在之前编写的///srv文件里,响应只有一个int sum return true; } int main(int argc, char **argv) { ros::init(argc, argv, "add_two_ints_server"); ros::NodeHandle n; ros::ServiceServer service = n.advertiseService("add_two_ints", add); //运行相加的程序段 ROS_INFO("Ready to add two ints."); ros::spin(); return 0; } 再编写一个客户(client)节点,命名为add_two_ints_client.cpp #include "ros/ros.h" #include "beginner_tutorials/AddTwoInts.h" #include int main(int argc, char **argv)//初值个数给argc,初值赋给argv这个数组 { ros::init(argc, argv, "add_two_ints_client"); if (argc != 3) //输入值不够两个(加文件名共三个) { ROS_INFO("usage: add_two_ints_client X Y"); return 1; } ros::NodeHandle n; ros::ServiceClient client = n.serviceClient //创建一个与add_two_ints的service相关的client beginner_tutorials::AddTwoInts srv;//创建一个名为“srv”的srv类,这个srv是我们之前生成的AddTwoInts srv.request.a = atoll(argv[1]); srv.request.b = atoll(argv[2]); //一个srv变量下有一组请求变量和一组回应变量,此处是给 //请求变量赋初值。 if (client.call(srv))//调用服务,转到服务节点运行 { ROS_INFO("Sum: %ld", (long int)srv.response.sum); } else { ROS_ERROR("Failed to call service add_two_ints"); return 1; } return 0; } 编译节点 再来编辑一下beginner_tutorials里面的CMakeLists.txt,文件位于~/catkin_ws/src/beginner_tutorials/CMakeLists.txt,并将下面的代码添加在文件末尾: add_executable(add_two_ints_server src/add_two_ints_server.cpp) target_link_libraries(add_two_ints_server ${catkin_LIBRARIES}) add_dependencies(add_two_ints_server beginner_tutorials_gencpp) add_executable(add_two_ints_client src/add_two_ints_client.cpp) target_link_libraries(add_two_ints_client ${catkin_LIBRARIES}) add_dependencies(add_two_ints_client beginner_tutorials_gencpp) 这段代码将生成两个可执行程序"add_two_ints_server"和"add_two_ints_client",这两个可执行程序默认被放在你的devel space下的包目录下,默认为~/catkin_ws/devel/lib/share/
