书籍名称:《Learning ROS for RoboticsProgramming - Second Edition》Chapter2
一、创建工作空间
查看已有的工作空间:
$ echo ROS_PACKAGE_PATH
新建工作空间:
1.创建文件夹
$ mkdir –p ~/dev/catkin_ws/src
$ cd ~/dev/catkin_ws/src
$ catkin_init_workspace
2.编译
$ cd ~/dev/catkin_ws
$ catkin_make
3.添加路径
$ source devel/setup.bash
4.创建功能包
在src文件夹下:
$ cd ~/dev/catkin_ws/src
$ catkin_create_pkg chapter2_tutorials std_msgs roscpp rospy
//catkin_create_pkg 功能包名 依赖1 依赖2 依赖3
依赖项包括:
• std_msgs : 常见的消息类型,表示消息基本数据类型和其他基本构造;
• roscpp : 使用C++实现ROS功能,提供了一个客户端库;
• rospy:使用python实现ROS功能。
5.编译功能包
返回上一层。
$ cd ~/dev/catkin_ws/
$ catkin_make
如果到达100%,表示一切顺利,否则会报错停止编译。
二、创建节点
1.打开功能包的src文件夹:/dev/catkin_ws/chapter2_tutorials/src/
$ roscd chapter2_tutorials/src/
在这个文件夹中,创建两个新文件(节点):example1_a.cpp和example1_b.cpp,
example1_a.cpp:
#include "ros/ros.h" //"ros/ros.h"包含ROS节点所有节点的必要文件
#include "std_msgs/String.h" //"std_msgs/String.h"包含消息类型
#include <sstream>
int main(int argc, char **argv)
{
ros::init(argc, argv, "example1_a"); //启动该节点并设置其名称(example1_a),该名称是唯一的
ros::NodeHandle n; //设置节点进程的句柄
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message", 1000);
//把这个节点设置成发布者,并把发布主题的类型告诉节点管理器。第一个参数是消息名称“message”,第二个参数将缓冲区设置为1000个消息
ros::Rate loop_rate(10); //设置频率10Hz
while (ros::ok()) //一直运行,直到CTRL+C停止运行
{
std_msgs::String msg; //创建消息变量,变量类型必须符合发送的要求
std::stringstream ss;
ss << " I am the example1_a node "; //要发布的消息内容
msg.data = ss.str();
chatter_pub.publish(msg); //发布消息
ros::spinOnce(); //如果出现订阅者,ROS会更新和读取所有主题
loop_rate.sleep(); //按频率挂起
}
return 0;
}
example1_b.cpp:
#include "ros/ros.h"
#include "std_msgs/String.h"
/*接收消息然后发布*/
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str()); //在命令行窗口显示消息内容
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "example1_b");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("message", 1000, chatterCallback);
//创建一个订阅者,从主题获取以“message”为名称的消息,缓冲区为1000,处理消息句柄的回调函数chatterCallback
ros::spin(); /ros::spin()库是响应循环,消息到达时调用函数chatterCallback,CTRL+C结束循环
return 0;
}
2.编译节点
打开CMakelists.txt:
$ rosed chapter2_tutorials CMakeLists.txt
//rosed 节点名 CMakeLists.txt
在最后加上
include_directories(
include
${catkin_INCLUDE_DIRS}
)
//原书这里把节点名写成char2_example1_a/b导致后面编译不成功
//添加可执行文件
//add_executable(节点名 src/节点名.cpp)
add_executable(example1_a src/example1_a.cpp)
add_executable(example1_b src/example1_b.cpp)
//添加依赖项
//add_dependencies(节点名 功能包名_generate_messages_cpp)
add_dependencies(example1_a chapter2_tutorials_generate_messages_cpp)
add_dependencies(example1_b chapter2_tutorials_generate_messages_cpp)
//链接
//target_link_librariex(节点名 ${catkin_LIBRARIES})
target_link_libraries(example1_a ${catkin_LIBRARIES})
target_link_libraries(example1_b ${catkin_LIBRARIES})
回到上层,编译功能包
$ cd ~/dev/catkin_ws/
$ catkin_make chapter2_tutorials
3.打开roscore,启动ROS
$ roscore
4.在两个不同的窗口运行以下命令:
$ rosrun chapter2_tutorials chap2_example1_a
$ rosrun chapter2_tutorials chap2_example1_b
会看到:
Chapter2原书部分错误与修正:
P56:
问题:
$ roscd chapter2_tutorials/src/
roscd: No such package/stack 'chapter2_tutorials'
解决:没有将工作空间路径: /home/catkin_ws/devel/setup.bash 添加到 .bashrc中
$ gedit ~/.bashrc
在最后加上:
source /home/xxx/dev/catkin_ws/devel/setup.bash
P60:
(1)问题:
$ rosrun chapter2_tutorials example1_a
[rosrun] Couldn't find executable named example1_a below /home/rushaonan/dev/catkin_ws/src/chapter2_tutorials
解决:
$ cd ~/dev/catkin_ws
$ catkin_make --pkg chapter2_tutorials
$ source devel/setup.bash
或者查看上面的CMakeLists.txt说明。
P61(P62同):
修改package.xml文件:
Now, edit package.xml and remove <!-- --> from the <build_depend>message_generation</build_depend> and <run_depend>message_runtime</run_depend>
P69:
chapter2.launch中:
<node name ="example1_a" pkg="chapter2_tutorials" type="example1_a"/>
改为<node name ="example1_a" pkg="chapter2_tutorials" type="chap2_example1_a"/>
<node name ="example1_b" pkg="chapter2_tutorials" type="example1_b"/>
改为<node name ="example1_b" pkg="chapter2_tutorials" type="chap2_example1_b"/>