总结ROS的基础教程的内容

如果你还没有学习过ROS针对初学者的专门设立的教程,请先点击下面的链接开始。
链接: ROS初级教程.
此文是一个学习过后的总结,用于加深对初级教程的理解与记忆。

一、学习简单的ros命令(先来13个…)

1、//catkin的编译命令
catkin_make
2、//ros的核心组件,ros所有的节点间的通信都需要roscore的支持,所以在运行其他节点、服务的时候需要提前执行roscore
roscore
3、//类似linux的cd命令,可以理解为ros + cd
roscd
4、//类似linux的ls命令,可以理解为ros + ls,可以直接查看软件包目录下的文件
rosls [package_name]
5、//通过包名进行查找
rospack find [package name]
6、//查看包所依赖的库
rospack depends [package_name]
7、//运行某个节点
rosrun [package_name] [node_name] [__name:=new_name]
8、//使用默认的编辑器编辑某个package下面的文件
rosed [package_name] [filename]
9、//要获得运行节点列表 ,可以查看rosnode -h
rosnode list
10、//想查看某种消息类型的详情
rosmsg show message-type-name
11、//获取当前活跃的话题,可以查看rostopic -h
rostopic list
12、//查看 service 列表,可以查看rosservice -h
rosservice list
13、//调用 service
rosservice call [service] [args]

二、了解ros的一些术语(5个)

节点(node):节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。
话题(topic):话题,节点可以发布消息到话题,也可以订阅话题以接收消息。
消息(message):消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。
服务(service):服务是节点之间通讯的另一种方式。服务允许节点发送请求(request) 并获得一个响应(response)
节点管理器(master):节点管理器,ROS名称服务 (比如帮助节点找到彼此)。

三、了解几个常用的文件(7个)

urdf文件:机器人的描述文件,该文件可用于机器人的模拟软件中,通常在文件中包含节点、材质、Collision标签(碰撞)等
srv文件:一个srv文件描述一项服务。srv文件则存放在srv目录下 ,它包含两个部分:请求和响应,请求可相应之间用“------”隔开
msg文件
msg文件存放在package的msg目录下,msg文件实际上就是每行声明一个数据类型和变量名。可以使用几种常见的数据类型和一种特殊的数据类型:

int8, int16, int32, int64 (plus uint*) 
float32, float64 
string 
time, duration 
other msg files 
variable-length array[] and fixed-length array[C] 

在ROS中有一个特殊的数据类型:Header,它含有时间戳和坐标系信息。在msg文件的第一行经常可以看到Header header的声明.
package.xml: package.xml 文件
和 android中的manifest 文件类似,描述功能包的属性,包括功能包的名字、版本号、作者、维护者、通行证 以及所以来的功能包。
strack.xml:ros中strack通常是指package的集合,用来描述所包含的package的信息
CmakeLists.txt : 编译配置文件,使用CMake编译
launch文件:可以理解为一种脚本,系统性的启动机器人所需要的各个node与services

四、了解常用的调试工具与仿真软件(4个)

新力得(sypatic):协助安装一些关联的库与包
rqt_graph命令:图形化表示出node与topic以及message之间的关联
gazebo:一种模拟的物理场景,通过各种模型的搭建,让虚拟的机器人run在一个真是的环境中
rviz:模拟机器人的各种数据等,使用时还可以根据实际情况使用各种适用的插件

五、理解几个用例代码(3个)

例1 、创建一个消息与服务

首先创建一个消息(共需要知道3点)
1、需要编辑msg/message.msg文件,在其中加入消息类型

string first_name
string last_name
uint8 age
uint32 score

2、同时修改package.xml文件

  <build_depend>message_generation</build_depend>
  <run_depend>message_runtime</run_depend>

3、同时修改CMakeList.txt文件

find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
	......
catkin_package(
  ...
  CATKIN_DEPENDS message_runtime ...
  ...)
	......
add_message_files(
  FILES
  Num.msg
)

创建一个service(共需要知道2点)
1、需要添加一个srv/AddTwoInts.srv

int64 a
int64 b
---
int64 sum

2、同时在CMakeList.txt文件中添加

# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation)
	......
add_service_files(
  FILES
  AddTwoInts.srv
)
	......
generate_messages(
  DEPENDENCIES
  std_msgs
)

最后你需要知道刚才的添加最后都生成的哪些东西
所有在msg路径下的.msg文件都将转换为ROS所支持语言的源代码。生成的C++头文件将会放置在~/catkin_ws/devel/include/package_name/。 Python脚本语言会在 ~/catkin_ws/devel/lib/python2.7/dist-packages/package_name/msg 目录下创建。 lisp文件会出现在 ~/catkin_ws/devel/share/common-lisp/ros/package_name/msg/ 路径下.
注:如果想要查看需要查看可以使用:(例)
rosmsg show beginner_tutorials/Num
rossrv show beginner_tutorials/AddTwoInts

~~============================================================~~

例2、编写简单的消息发布器和订阅器 (共需要知道3点)

1、编辑发布器,src/talker.cpp
其中主要做的事如下
//初始化 ROS 。它允许 ROS 通过命令行进行名称重映射.在这里,我们也可以指定节点的名称——运行过程中,节点的名称必须唯一。

ros::init(argc, argv, "talker");
ros::NodeHandle n;

//告诉 master 我们将要在 chatter(话题名) 上发布 std_msgs/String 消息类型的消息。这样 master 就会告诉所有订阅了 chatter 话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 1000 个的时候就会开始丢弃先前发布的消息。

ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(10);

//使用一个由 msg file 文件产生的『消息自适应』类在 ROS 网络中广播消息。现在我们使用标准的String消息,它只有一个数据成员 “data”。当然,你也可以发布更复杂的消息类型。

chatter_pub.publish(msg);
ros::spinOnce();

2、编辑订阅器 src/listener.cpp 文件
首先有一个回调函数,当接收到 chatter 话题的时候就会被调用。消息是以 boost shared_ptr 指针的形式传输,这就意味着你可以存储它而又不需要复制数据。

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

然后告诉 master 我们要订阅 chatter 话题上的消息。当有消息发布到这个话题时,ROS 就会调用 chatterCallback() 函数。第二个参数是队列大小,以防我们处理消息的速度不够快,当缓存达到 1000 条消息后,再有新的消息到来就将开始丢弃先前接收的消息。
NodeHandle::subscribe() 返回 ros::Subscriber 对象,你必须让它处于活动状态直到你不再想订阅该消息。当这个对象销毁时,它将自动退订 chatter 话题的消息。

ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

最后ros::spin() 进入自循环,可以尽可能快的调用消息回调函数。如果没有消息到达,它不会占用很多 CPU,所以不用担心。一旦 ros::ok() 返回 false,ros::spin() 就会立刻跳出自循环。这有可能是 ros::shutdown() 被调用,或者是用户按下了 Ctrl-C,使得 master 告诉节点要终止运行。也有可能是节点被人为关闭的。

ros::spin();

3、在CMakeLists.txt,并将下面的代码添加在文件末尾

## 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)

~~============================================================~~

例3、编写简单的服务器和客户端 (共需要知道3点)

1、创建server端,编辑 src/add_two_ints_server.cpp
首先定义一个函数,这个函数提供两个int值求和的服务,int值从request里面获取,而返回数据装入response内,这些数据类型都定义在srv文件内部,函数返回一个boolean值。

bool add(beginner_tutorials::AddTwoInts::Request  &req,
         beginner_tutorials::AddTwoInts::Response &res)
{
  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);
  return true;
}

然后service建立起来,并在ROS内发布出来。

ros::ServiceServer service = n.advertiseService("add_two_ints", add);
ros::spin();

2、创建client端,编辑 src/add_two_ints_client.cpp
首先这段代码为add_two_ints service创建一个client。ros::ServiceClient 对象待会用来调用service。

ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");

然后我们实例化一个由ROS编译系统自动生成的service类,并给其request成员赋值。一个service类包含两个成员request和response。同时也包括两个类定义Request和Response。

beginner_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);

最后需要调用service。由于service的调用是模态过程(调用的时候占用进程阻止其他代码的执行),一旦调用完成,将返回调用结果。如果service调用成功,call()函数将返回true,srv.response里面的值将是合法的值。如果调用失败,call()函数将返回false,srv.response里面的值将是非法的。

if (client.call(srv))

3、然后在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/。你可以直接调用可执行程序,或者使用rosrun命令去调用它们。它们不会被装在/bin目录下,因为当你在你的系统里安装这个包的时候,这样做会污染PATH变量。如果你希望在安装的时候你的可执行程序在PATH变量里面,你需要设置一下install target

你可能感兴趣的:(ROS)