ROS基础目录

  • 工作空间
    • 创建工作空间
    • 编译工作空间
    • 设置环境变量
      • 仅在当前terminal中有效的设置方法
      • 永久有效的方法
    • 在环境变量中 筛选有用信息
    • 创建功能包
    • 编译功能包
    • 查找功能包
  • ROS通信机制
    • 1、话题编程
      • 创建发布者
      • 创建接收者
    • 此处出现的问题:
      • 自定义消息结构
    • 2、服务编程
      • 定义srv文件
        • **注意**
      • 创建一个服务器
      • 客户端程序
      • 编译代码

工作空间

src 代码空间

build 编译空间

devel 开发空间

install 安装控件

创建工作空间

创建工作空间是在src目录下进行catkin_init_workspace

mkdir -p ~/catkin_ws/src     // 创建目录  -p 一次行创建多级目录
cd ~/catkin_ws/src          // 切换到 ~/catkin_ws/src   目录下
catkin_init_workspace       // 初始化工作空间

编译工作空间

编译工作空间要在根目录下

cd ~/catkin_ws/              // 切换到工作空间根目录
catkin_make                 // 编译

设置环境变量

仅在当前terminal中有效的设置方法

source devdl/setup.bash      // 这一步是在根目录下执行

确定当前环境变量是否设置成功

echo $ROS_PACKAGE_PATH

输出

/home/luo/ws/catkin_ws/src:/opt/ros/melodic/share

环境变量通过 : 进行分割 如果自己的目录在环境变量中,既是设置成功,可以发现后加入的环境变量在前面。

永久有效的方法

前面的方法在新开的terminal中,刚刚设置的环境变量还是不存在的。如果想在新打开的terminal中依然存在刚设置的环境变量,需要修改~目录下的.bashrc。方法如下

nano ~/.bashrc

在.bashrc 最后加入

source ~/ws/catkin_ws/devel/setup.bash
source ~/.bashrc                // 更新环境变量

验证 环境变量 是否成功设置,新开一个terminal,

echo $ROS_PACKAGE_PATH

查看输出的路径中是否有刚刚自己添加的路径。

在环境变量中 筛选有用信息

env |grep ROS_PACKAGE_PATH

查看环境变量中和ROS_PACKAGE_PATH相关的信息

创建功能包

创建功能包要在src下面

catkin_create_pkg learning_communication std_msgs rospy roscpp

其中catkin_create_pkg是指令

learning_communication功能包的名字

std_msgs rospy roscpp 是依赖环境 正常都要带上

编译功能包

返回到根目录

cd ..

编译

catkin_make

注意事项:同一个工作空间下,不可以存在相同的功能包

​ 不同的工作空间下,可以存在相同的功能包

查找功能包

rospack find roscpp_tutorials

返回的是功能包的路径

ROS通信机制

1、话题编程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjiF89gD-1640778615234)(D:\笔记文件夹\ROS基础(2).assets\image-20211229105628607-16407466072741.png)]

  1. 创建发布者

  2. 创建订阅者

  3. 添加编译选项

  4. 运行可执行程序

创建发布者

/*** 该例程将发布chatter话题,消息类型String*/#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc, argv, "talker");// 创建节点句柄ros::NodeHandle n;// 创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::Stringros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);// 设置循环的频率ros::Rate loop_rate(10);int count = 0;while (ros::ok()){// 初始化std_msgs::String类型的消息std_msgs::String msg;std::stringstream ss;ss << "hello world " << count;msg.data = ss.str();// 发布消息ROS_INFO("%s", msg.data.c_str());chatter_pub.publish(msg);// 循环等待回调函数ros::spinOnce();// 按照循环频率延时loop_rate.sleep();++count;}return 0;
}

CMakeLists.txt 中文件修改

生产可执行文件 talker 生成到 devel/lib/node名称下/talker,之后通过rosrun 对其进行执行

add_executable(talker src/talker.cpp)

如果cpp中用到第三方插件,需要在这里进行target_link 链接到第三方库文件,现在链接的库是catkin的基础库

 target_link_libraries(talker  ${catkin_LIBRARIES} )

创建接收者

自己写的程序

#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,"lensener");ros::NodeHandle n;ros::Subscriber sub = n.subscribe("chatter1",1000,chatterCallback);ros::spin();return 0;
}

程序历程

/*** 该例程将订阅chatter话题,消息类型String*/#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节点ros::init(argc, argv, "listener");// 创建节点句柄ros::NodeHandle n;// 创建一个Subscriber,订阅名为chatter的topic,注册回调函数chatterCallbackros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);// 循环等待回调函数ros::spin();return 0;
}

CMakeLists.txt 中文件修改

生产可执行文件 talker 生成到 devel/lib/node名称下/talker,之后通过rosrun 对其进行执行

add_executable(lensener src/lensener.cpp)

如果cpp中用到第三方插件,需要在这里进行target_link 链接到第三方库文件,现在链接的库是catkin的基础库

 target_link_libraries(lensener  ${catkin_LIBRARIES} )

此处出现的问题:

当先开启 subscribe,再启动Publisher 时, 发布的前两包信息会被丢弃 这个是什么原因?

  1. 定义msg文件
  2. 再package.xml中添加功能包依赖
  3. 再CMakeList.txt中添加编译

自定义消息结构

  1. 在功能包下新建 msg文件夹

    新建文件Person.msg

    string name
    uint8 sex
    uint8 ageuint8 unknown = 0
    uint8 male =1
    uint8 female =2
    
  2. 在package.xml 中加入

      <build_depend> message_generation</build_depend><exec_depend>message_runtime</exec_depend>
    
  3. CMakeList中加入

    1. find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
      )
      
    2. ## Generate messages in the 'msg' folder
      add_message_files(FILESPerson.msg# Message2.msg
      )
      
    3. ## Generate added messages and services with any dependencies listed here
      generate_messages(DEPENDENCIESstd_msgs
      )
      
    4. catkin_package(
      #  INCLUDE_DIRS include
      #  LIBRARIES learning_communicationCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
      #  DEPENDS system_lib
      )
      

      在创建完成后,编译 可以通过

      rosmsg show Person 来验证创建的是否正确
      

2、服务编程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0t52qGJO-1640778615236)(D:\笔记文件夹\ROS基础 (2).assets\image-20211229153801254-16407634850601.png)]

  1. 创建服务器
  2. 创建客户端
  3. 添加编译选项
  4. 运行可执行程序

定义srv文件

  1. 定义srv文件

  2. 在package.xml中添加功能包依赖

      <build_depend> message_generation</build_depend><exec_depend>message_runtime</exec_depend>
    
  3. 在CMakeList.txt中修改 和自定义添加编译依赖 1、2 相同 3 是特有的

  4. find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
    )
    
  5. catkin_package(
    #  INCLUDE_DIRS include
    #  LIBRARIES learning_communicationCATKIN_DEPENDS roscpp rospy std_msgs message_runtime
    #  DEPENDS system_lib
    )
    
  6. ## Generate services in the 'srv' folder
    add_service_files(FILESAddTwo.srv# Service2.srv
    )
    
  7. 生成可支持 文件

    add_executable(server src/server.cpp)
    
  8. 测试生成文件是否可用

    启动 roscore rosrun

注意

在vscode中编程为了在编程过程中能够讲新建的srv文件引入,需要在 src/.vscode/c_cpp_properties.json 文件下 includePath 下面加入

    "includePath": ["/opt/ros/melodic/include/**","/home/luo/ws/catkin_ws/src/learning_communication/include/**","/usr/include/**","/home/luo/ws/catkin_ws/devel/include/learning_communication**"             // 这行是新加入的,包含的新生成的srv文件],

创建一个服务器

  1. 初始化ROS节点
  2. 创建Server实例
  3. 循环等到服务请求,进入回调函数
  4. 在回调函数中完成服务功能的处理,并反馈应答数据
#include "ros/ros.h"
#include "learning_communication/AddTwo.h"// service回调函数,输入参数req,输出参数res
bool add(learning_communication::AddTwo::Request  &req,learning_communication::AddTwo::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;
}int main(int argc, char **argv)
{// ROS节点初始化ros::init(argc,argv,"add_two_inis_server");// 创建节点句柄ros::NodeHandle n;// 创建一个名为add_two_ints的server,注册回调函数add()ros::ServiceServer service = n.advertiseService("add_two_inis",add);// 循环等待回调函数ROS_INFO("Ready to add two ints.");ros::spin();return 0;
}

客户端程序

#include "learning_communication/AddTwo.h"
#include "ros/ros.h"
#include <cstdlib>int main(int argc, char **argv)
{// ROS节点初始化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;// 创建一个client,请求add_two_int service,service消息类型是learning_communication::AddTwoIntsros::ServiceClient client = n.serviceClient<learning_communication::AddTwo>("add_two_inis_server");// 创建learning_communication::AddTwoInts类型的service消息learning_communication::AddTwo srv;srv.request.a = atoll(argv[1]);srv.request.b = atoll(argv[2]);// 发布service请求,等待加法运算的应答结果if(client.call(srv)){ROS_INFO("Sum: %ld",(long int)srv.response.sum);}else{ROS_INFO("Failed to call service add_ two_ints");return 1;}return 0;
}

编译代码

add_executable(server src/server.cpp)                        // 编译代码生成可执行文件
target_link_libraries(server  ${catkin_LIBRARIES} )         // 设置链接库
add_dependencies(server ${PROJECT_NAME}_gencpp)             // server  需要多加的一句  设置依赖add_executable(client src/client.cpp)
target_link_libraries(client  ${catkin_LIBRARIES} )
add_dependencies(client ${PROJECT_NAME}_gencpp)

ROS 基础知识(一)相关推荐

  1. ros基础知识(1)

    之前在毕设时用到了ROS,但后来就没怎么使用了,现在回头整理资料的时候觉得这个技能不能荒废了,因此打算复习整理一下并写在博客里,方便和大家讨论学习,我打算从最基础的东西开始介绍. 一.Linux与 U ...

  2. ros 基础知识总结

    45 ros的导航算法(全局路径规划算法与局部路径规划算法) (1) 全局路径规划算法(Dijkstra算法和A*算法)  { 绿色:起点 红色:终点   黑色:障碍物    白色:路径    黄色: ...

  3. ROS开发系列(1)- ROS基础知识

    1.常用指令 1.1 roscore 启动一个roscore就相当于是开启了一个rosmaster,也就是管理器 1.2 rosrun rosrun指令的第一个参数是功能包的名字,如果这个时候双击ta ...

  4. ROS移动机器人——ROS基础知识与编程

    此文章基于冰达机器人进行笔记整理,使用的环境为其配套环境,可结合之前的ROS,赵虚左老师的文章结合进行观看,后期也会进行整合 同时建议观看cn/ROS/Tutorials - ROS Wiki 官方教 ...

  5. 一 ROS基础教程

    ROS教程 这是小弟的学习笔记,有错求请拍,多指教,谢谢 一 ROS基础知识 ROS文件系统介绍 1.功能包集stack ROS软件包集合,像Navigation Stack,属于导航软件包集合,包含 ...

  6. ROS学习笔记基础2(基础知识和ROS架构)

    ROS学习笔记1(基础知识和ROS架构) 文章目录 ROS学习笔记1(基础知识和ROS架构) 1. 什么是ROS 2. ROS和其他机器人平台有什么不同 3. ROS架构组成 3.1 文件系统级别 3 ...

  7. ROS Qt环境的搭建及基础知识介绍

    ROS Qt环境的搭建及基础知识介绍 文章目录 ROS Qt环境的搭建及基础知识介绍 1. 开发环境搭建 1.1 qtcreator安装 1.2 catkin_create_qt_pkg环境配置 1. ...

  8. 【睿慕课点云处理】第一章-基础知识

    [睿慕课点云处理]第一章-基础知识 作业 答 ROS对齐多种传感器数据的时间戳message_filters

  9. [ROS基础-4] ROS系统框架

    系列文章目录 [ROS基础-1] Linux系统介绍与ubuntu安装(virtualbox) [ROS基础-2] Ubuntu系统基本操作与基本命令讲解 [ROS基础-3] ROS系统安装与基本配置 ...

  10. 嵌入式软件开发岗位----求职过程记录(基础知识和面经总结)

    1.本栏用来记录社招找工作过程中的内容,包括基础知识以及面试问题等,以便于后续个人回顾学习: 暂时只有2023年3月份,第一次社招找工作的过程: 2.个人经历: 研究生期间课题是SLAM在无人机上的应 ...

最新文章

  1. 【案例分析】android广播接收不到原因分析
  2. 最受欢迎的十款免费安全软件
  3. 欧洲最大云服务公司火灾!数百万网站出现故障企业网络推广大型瘫痪现场!...
  4. 求二叉树某个结点的祖先
  5. ADMM:交替方向乘子算法
  6. Python实训day11am【大作业思路梳理】
  7. 城市规划Java_智慧城市通过边缘计算转向高层次的城市规划
  8. apache.camel_Apache Camel 2.16发布–十大亮点
  9. CI框架取消index.php
  10. 《Head First设计模式》第四章笔记 工厂模式
  11. mysql 占用swap_查看swap占用情况
  12. Python打印某范围内的素数
  13. 12-31--MAGENTO---强大的配置功能挖掘!!
  14. 52 - 算法 - 数据结构 vector
  15. ERROR: No matching distribution found for numpy
  16. 优化性能一点总结,供大家参考
  17. Bat 无限弹窗(慎用)
  18. 【Python的自学之路】(八):文字游戏分享
  19. 海思Hi3519AV100 emmc flash方式 linux系统移植 hitool工具烧写
  20. TransE模型的简单介绍TransE模型的python代码实现

热门文章

  1. taocat服务器的作用,随笔2_tww
  2. “人人皆可成为AI开发者”!百度世界大会官宣百度松果学堂成立
  3. 利用计算机指令清理垃圾,系统运维---教你用dos命令清除系统垃圾的快速方法
  4. 【深入理解C++】析构函数
  5. P1157 组合的输出(#define mian main)
  6. MJPEG和MP4——视频转换随想
  7. word公式大括号内容对齐
  8. Tomcat部署及负载均衡_wuli大世界_新浪博客
  9. Transactions
  10. CocosCreator之绳索摆动效果