目录
2、把工作空间添加到~/.bashrc 文件中,即终端文件中
4、创建发布节点 node_a.cpp 与 订阅节点 node_b.cpp
8.1 int main(int argc, char **argv) 中 char **argv 等价 char *argv[]
8.2 #include <sstream> //std::stringstream, std::stringbuf
1、创建工作空间
mkdir -p ~/catkin_ws/src -p 建立级联目录 ~/ home目录 catkin_ws 是工作空间
cd ~/catkin_ws 进入工作空间 即home文件夹下的catkin_ws文件夹
catkin_make 编译工作空间,生成build文件夹 devel文件夹和src文件夹
注:
build文件夹为编译空间(The Build Space),其中的CMake*和catkin文件为工作包和项目保存缓存信息、配置和其他中间文件;
devel文件夹为开发空间(The Development Space),该文件夹保存编译后的程序,这些程序不需要安装就可以进行测试运行。
src文件夹:CMakeLists.txt文件 与 创建的功能包文件夹
2、把工作空间添加到~/.bashrc 文件中,即终端文件中
在工作空间目录下,即catkin_ws目录下:
echo $ROS_PACKAGE_PATH 查看已有的工作空间
显示是否为 /home/rain/ros_workspace/catkin_ws/src:/opt/ros/kinetic/share,若不是的话,输入
source devel/setup.bash
echo "source 工作空间目录/devel/setup.bash" >> ~/.bashrc 回车即可 >> 把数据附加到已存在的文件中
删除多余的工作空间目录:
新打开一个终端,打开终端脚本~/.bashrc文件: $sudo gedit ~/.bashrc
在文件末尾处,删除多余的工作空间路径,或添加新的工作空间路径,保存
新打开一个终端,执行: $ echo $ROS_PACKAGE_PATH
3、创建ROS功能包
cd 工作空间/src 进入src文件夹
catkin_create_pkg chap1 std_msgs roscpp 创建功能包chap1,依赖项是 std_msgs和roscpp
cd ../ 进入上一级目录,即catkin_ws文件夹下
catkin_make 编译工作空间
注:
std_msgs:包含了常见的消息类型,表示基本数据类型和其他基本的消息构造,如多维数组。
roscpp:使用C++实现ROS的各项功能,它提供了一个客户端库,让C++程序员能够调用这些接口快速完成与ROS主题。服务、参数相关的操作。
rospy:若需要使用Python,需添加此依赖性。例 catkin_create_pkg chap1 std_msgs roscpp rospy
4、创建发布节点 node_a.cpp 与 订阅节点 node_b.cpp
参考博客:https://blog.csdn.net/qq_31356389/article/details/79095040
cd 工作空间/src/chap1/src 或使用 roscd chap1/src 作用一样
注:roscd 功能包名字 正确 roscd 工作空间/功能包 错误
gedit node_a.cpp 复制粘贴发布代码,保存
gedit node_b.cpp 复制粘贴订阅代码,保存
5、编译节点
cd 工作空间/src/chap1
geditCMakeLists.txt 这两行等价 rosed chap1 CMakeLists.txt
在文件尾部添加:
add_executable(Test1_node_a src/node_a.cpp) #将node_a.cpp文件编译成可执行文件Test1_node_a
add_executable(Test1_node_b src/node_b.cpp)
add_dependencies(Test1_node_a chap1_generate_message_cpp) #添加可执行文件的消息依赖项
add_dependencies(Test1_node_b chap1_generate_message_cpp)
target_link_libraries(Test1_node_a ${catkin_LIBRARIES}) #为可执行文件Test_node_a添加链接库
target_link_libraries(Test1_node_b ${catkin_LIBRARIES})
cd 工作空间 即catkin_ws目录下
catkin_make 编译工作空间
6、运行节点
打开terminal:roscore
打开terminal:rosrun chap1 Test1_node_a
打开terminal:rosrun chap1 Test1_node_b
7、工作空间内的 文件夹树状图
8、代码说明
8.1 int main(int argc, char **argv) 中 char **argv 等价 char *argv[]
argc是自动算出的argv的lengh,运行时 只需传入argv中的字符即可
例:rosrun 节点 aaa.exe x.dat 5 6
argc = 4
argv[0] = aaa.exe argv[1] = x.dat argv[2] = 5 argv[3] = 6
8.2 #include <sstream> //std::stringstream, std::stringbuf
声明对象时:
std_msgs::String msg;
std::stringstream ss; //std::stringstream是类名,声明类的对象 ss
ss<<"Hello World";
msg.data = ss.str();// 调用 类里的str()函数,返回当前stream里的指针 string str() const; void str (const string& s);
8.3 const说明
参考博客:https://www.cnblogs.com/xudong-bupt/p/3509567.html
(1)const 修饰函数参数,则传递过来的参数在函数内不可以改变 例void str (const string& s);
(2)const 修饰成员函数,则const修饰的成员函数不能修改任何的成员变量(mutable修饰的变量除外) 例:string str() const;
const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量
(3)const 修饰函数返回值
指针传递 例 const int * mallocA(){} 返回的是指针
值传递: 如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。所以,对于值传递来说,加const没有太多意义。 例 const int GetInt(void)
8.4 关于回调函数
ros::spin(); //调用后,程序进入循环,直到ros::ok()返回false,进程结束。
ros::spinOnce(); //调用后,返回主程序,继续执行之后的程序
如果程序写了相关的消息订阅函数,一定要在相应位置加上 ros::spin(); 或 ros::spinOnce();
因为程序只有在运行到这两个函数时,才会处理收到的消息。