• SLAM从入门到精通(ROS应用开发)


    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

            前面我们陆陆续续学习了关于ros的一些知识点,比如如何创建包、如何进行消息访问、如何注册服务、如何访问参数等等。那么对于我们使用者来说,应该如何进行ros开发呢?其实就是把之前的功能整合起来,那就是一个基本的ros应用了。

    1、创建头文件book_class.h

    1. #ifndef _BOOK_CLASS_H
    2. #define _BOOK_CLASS_H
    3. #include "ros/ros.h"
    4. #include "std_msgs/String.h"
    5. #include "std_msgs/Float64.h"
    6. #include "std_msgs/Int32.h"
    7. #include "beginner_tutorials/PassWord.h"
    8. using namespace std;
    9. class RosBasics
    10. {
    11. public:
    12. RosBasics();
    13. RosBasics(ros::NodeHandle& nh);
    14. ~RosBasics();
    15. void initPublish();
    16. void initSubscribe();
    17. void initServer();
    18. bool serverCallback(beginner_tutorials::PassWord::Request& req,
    19. beginner_tutorials::PassWord::Response& res);
    20. void msgCallback(const std_msgs::Float64& stdmsg);
    21. void paramTest();
    22. private:
    23. ros::NodeHandle nh_;
    24. ros::Publisher pub_;
    25. ros::Subscriber sub_;
    26. ros::ServiceServer serv_;
    27. };
    28. #endif

            头文件一般是为了其他模块方便调用而创建的。如果应用比较简单,不创建头文件也是可以的。

    2、创建book_class.cpp文件

    1. #include "book_class.h"
    2. RosBasics::RosBasics():nh_("~")
    3. {
    4. initPublish();
    5. initServer();
    6. initSubscribe();
    7. paramTest();
    8. }
    9. RosBasics::RosBasics(ros::NodeHandle& nh):nh_(nh)
    10. {
    11. initPublish();
    12. initServer();
    13. initSubscribe();
    14. paramTest();
    15. }
    16. RosBasics::~RosBasics()
    17. {
    18. return;
    19. }
    20. void RosBasics::initPublish()
    21. {
    22. ROS_INFO("publish initializing!");
    23. pub_ = nh_.advertise<std_msgs::Float64>("Topic2", 100);
    24. }
    25. void RosBasics::initSubscribe()
    26. {
    27. ROS_INFO("subscribe initializing");
    28. sub_ = nh_.subscribe("Topic1", 1, &RosBasics::msgCallback, this);
    29. }
    30. void RosBasics::initServer()
    31. {
    32. ROS_INFO("server initializing");
    33. serv_ = nh_.advertiseService("pwdcheck", &RosBasics::serverCallback, this);
    34. }
    35. bool RosBasics::serverCallback(beginner_tutorials::PassWord::Request& req,
    36. beginner_tutorials::PassWord::Response& res)
    37. {
    38. res.result = (req.password == 123456) ? true: false;
    39. if(res.result)
    40. {
    41. ROS_INFO("Welcom, password correct!");
    42. }
    43. else
    44. {
    45. ROS_INFO("Sorry, password error");
    46. }
    47. return true;
    48. }
    49. void RosBasics::msgCallback(const std_msgs::Float64& stdmsg)
    50. {
    51. std_msgs::Float64 msgpub;
    52. msgpub.data = stdmsg.data + 2;
    53. ROS_INFO("Receive date from Topic1 content is:%f", stdmsg.data);
    54. ROS_INFO("Publish date with Topic2 content is:%f", msgpub.data);
    55. pub_.publish(msgpub);
    56. }
    57. void RosBasics::paramTest()
    58. {
    59. int Age;
    60. bool checkAge;
    61. checkAge = nh_.getParam("Age", Age);
    62. if(checkAge)
    63. {
    64. ROS_INFO("Welcom, Get Param Success");
    65. if(Age > 18)
    66. {
    67. ROS_INFO("You are adult!");
    68. }
    69. else
    70. {
    71. ROS_INFO("Your are children!");
    72. }
    73. }
    74. else
    75. {
    76. ROS_INFO("Sorry, Get Param Fail!");
    77. }
    78. }

            整个应用类名叫RosBasics。初始化的部分主要是构造函数RosBasics(),里面有四个基本动作,分别是initPublish、initServer、initSubscribe、paramTest。除了paramTest是为了验证参数设置的,其他的函数都是为了发布某种信息,或者是订阅某种消息。除了这些函数之外,还有两个函数比较重要,分别是serverCallback和msgCallback,前者是服务响应的时候被调用,后者是消息订阅的时候被响应。

    3、添加main函数

    1. int main(int argc, char* argv[])
    2. {
    3. ros::init(argc, argv, "node_classdemo");
    4. ros::NodeHandle nh;
    5. RosBasics classdemo(nh);
    6. ros::spin();
    7. return 0;
    8. }

    4、添加编译脚本

    1. add_executable(book_class src/book_class.cpp)
    2. target_link_libraries(book_class ${catkin_LIBRARIES})
    3. add_dependencies(book_class beginner_tutorials_generate_messages_cpp)

            添加了编译脚本之后,就可以使用catkin_make命令去处理了。

    5、测试

            测试之前首先启动roscore、初始化./devel/setup.sh环境。接着就是启动book_class应用,即,

    1. feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws$ rosrun beginner_tutorials book_class
    2. [ INFO] [1695373247.361995894]: publish initializing!
    3. [ INFO] [1695373247.362640551]: server initializing
    4. [ INFO] [1695373247.362935090]: subscrbe initializing
    5. [ INFO] [1695373247.363917937]: Sorry, Get Param Fail!

            针对这个程序,测试一般有三个。第一,通过rosparam增加Age参数,重启book_class,查看param是否发生改变,

    1. feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws/src/beginner_tutorials/src$ rosparam set Age 18
    2. Cfeixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws$ rosrun beginner_tutorials book_class
    3. [ INFO] [1695373270.010051953]: publish initializing!
    4. [ INFO] [1695373270.010738103]: server initializing
    5. [ INFO] [1695373270.011012052]: subscrbe initializing
    6. [ INFO] [1695373270.011977071]: Welcom, Get Param Success
    7. [ INFO] [1695373270.012022883]: Your are children!

            第二,利用rosservice调用pwdcheck,判断是否有对应打印,

    1. feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws/src/beginner_tutorials/src$ rosservice call pwdcheck 123456
    2. result: True

            第三,用rostopic发布Topic1消息,查看是否有对应的打印,

    1. feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws/src/beginner_tutorials/src$ rostopic pub -r 10 /Topic1 std_msgs/Float64 1
    2. feixiaoxing@feixiaoxing-VirtualBox:~/Desktop/catkin_ws$ rosrun beginner_tutorials book_class
    3. [ INFO] [1695373395.125181843]: publish initializing!
    4. [ INFO] [1695373395.125854890]: server initializing
    5. [ INFO] [1695373395.126141408]: subscrbe initializing
    6. [ INFO] [1695373395.127212501]: Welcom, Get Param Success
    7. [ INFO] [1695373395.127267569]: Your are children!
    8. [ INFO] [1695373410.061866408]: Welcom, password correct!
    9. [ INFO] [1695373443.247473790]: Receive date from Topic1 content is:1.000000
    10. [ INFO] [1695373443.247526881]: Publish date with Topic2 content is:3.000000

    6、关于launch文件的小技巧

            经过之前的学习我们知道,如果node节点比较多,那么一个一个起来很麻烦。这个时候,我们就可以通过写一个launch文件,来解决这个问题。如下面脚本所示,有这么一个beginner.launch这个文件,

    1. <launch>
    2. <node pkg="beginner_tutorials" type="listener" name="listener" />
    3. </launch>

            这个时候,就可以输入roslaunch beginner.launch文件,就可以直接验证了。如果它发现roscore没有启动,也会帮助我们先把roscore启动起来的。当然,如果launch文件时保存在package下面,那么启动的时候,带上package名字就好了,

    rosrun beginner_tutorials beginner.launch

            其他需要注意的是,

    1. 1)arg相当于公共变量;
    2. 2)node就是package中的程序,提供package和type就行;
    3. 3)param是参数,放在全局就是全局变量,node里面就是私有变量;
    4. 可以通过ros::param::param<string>(“data_type”, data_type, “images”)访问
    5. 其中data_typestring类型,如果没有,“images”是默认类型,有就读取。
    6. 如果是私有类型,param放在node中间;
    7. ros::param::param<string>(“~data_type”, data_type, “images”)
    8. 4)include嵌套其他launch文件。

  • 相关阅读:
    有关神经网络的训练算法,人工神经网络优化算法
    html中image 区域点击的优点
    Chrome开发者模式去除时间轴
    【鸿蒙应用ArkTS开发系列】- 云开发入门简介
    会话管理 : Cookie和Session
    NVIDIA NCCL 源码学习(六)- channel搜索
    跑步运动戴哪种耳机最好?跑步骨传导耳机推荐
    如何在电脑和 SD 卡上恢复已删除 MOV等视频文件
    DFS-4-N皇后问题
    Centos磁盘问题小纪
  • 原文地址:https://blog.csdn.net/feixiaoxing/article/details/133177655