• ROS-API函数介绍


    接上面 ROS入门,因为内容太多另起一篇

    下面只使用C++ 而不使用Python(与自动化专业贴近)

    -----------------------------------------------------------------------------------------------------

    一。初始化

    1. void init(int &argc, char **argv, const std::string& name, uint32_t options = 0);
    2. // 最后一个参数是可选的
    1. /** ROS初始化函数。
    2. *
    3. * 该函数可以解析并使用节点启动时传入的参数(通过参数设置节点名称、命名空间...)
    4. *
    5. * 该函数有多个重载版本,如果使用NodeHandle建议调用该版本。
    6. *
    7. * \param argc 参数个数
    8. * \param argv 参数列表
    9. * \param name 节点名称,需要保证其唯一性,不允许包含命名空间
    10. * \param options 节点启动选项,被封装进了ros::init_options
    11. *
    12. */

    --------------------------------------------------------------------------------

    二。话题与话题服务函数

    在 roscpp 中,话题和服务的相关对象一般由 NodeHandle 创建,NodeHandle有一个重要作用是可以用于设置命名空间。

    1. 发布对象

    Publisher advertise(const std::string& topic, uint32_t queue_size, bool latch = false)
    ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
     ros::Publisher pub = handle.advertise<std_msgs::Empty>("my_topic", 1);
    1. /**
    2. * \brief 根据话题生成发布对象
    3. *
    4. * 在 ROS master 注册并返回一个发布者对象,该对象可以发布消息
    5. *
    6. * 使用示例如下:
    7. *
    8. * ros::Publisher pub = handle.advertise<std_msgs::Empty>("my_topic", 1);
    9. *
    10. * \param topic 发布消息使用的话题
    11. *
    12. * \param queue_size 等待发送给订阅者的最大消息数量
    13. *
    14. * \param latch (optional) 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者
    15. *
    16. * \return 调用成功时,会返回一个发布对象
    17. *
    18. *
    19. */

    2. 订阅对象

    1. void doMsg(const std_msgs::String::ConstPtr& msg_p){
    2. ROS_INFO("我听见:%s",msg_p->data.c_str());
    3. // ROS_INFO("我听见:%s",(*msg_p).data.c_str());
    4. }
    ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
    1. /**
    2. * \brief 生成某个话题的订阅对象
    3. *
    4. * 该函数将根据给定的话题在ROS master 注册,并自动连接相同主题的发布方,每接收到一条消息,都会调用回调
    5. * 函数,并且传入该消息的共享指针,该消息不能被修改,因为可能其他订阅对象也会使用该消息。
    6. * \param M [template] M 是指消息类型
    7. * \param topic 订阅的话题
    8. * \param queue_size 消息队列长度,超出长度时,头部的消息将被弃用
    9. * \param fp 当订阅到一条消息时,需要执行的回调函数
    10. * \return 调用成功时,返回一个订阅者对象,失败时,返回空对象

    3. 服务对象

    为自己所定义内容,服务通信 ---- 有一些前置步骤,需要参考一下ROS入门

    1. bool doReq(demo03_server_client::AddInts::Request& req,
    2. demo03_server_client::AddInts::Response& resp){
    3. int num1 = req.num1;
    4. int num2 = req.num2;
    5. ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);
    6. //逻辑处理
    7. if (num1 < 0 || num2 < 0)
    8. {
    9. ROS_ERROR("提交的数据异常:数据不可以为负数");
    10. return false;
    11. }
    12. //如果没有异常,那么相加并将结果赋值给 resp
    13. resp.sum = num1 + num2;
    14. return true;
    15. }
    16. ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
    1. /**
    2. * \brief 生成服务端对象
    3. *
    4. * 该函数可以连接到 ROS master,并提供一个具有给定名称的服务对象。
    5. *
    6. * 使用示例如下:
    7. \verbatim
    8. bool callback(std_srvs::Empty& request, std_srvs::Empty& response)
    9. {
    10. return true;
    11. }
    12. ros::ServiceServer service = handle.advertiseService("my_service", callback);
    13. \endverbatim
    14. *
    15. * \param service 服务的主题名称
    16. * \param srv_func 接收到请求时,需要处理请求的回调函数
    17. * \return 请求成功时返回服务对象,否则返回空对象:
    18. \verbatim
    19. bool Foo::callback(std_srvs::Empty& request, std_srvs::Empty& response)
    20. {
    21. return true;
    22. }
    23. ros::NodeHandle nodeHandle;
    24. Foo foo_object;
    25. ros::ServiceServer service = nodeHandle.advertiseService("my_service", callback);
    26. if (service) // Enter if advertised service is valid
    27. {
    28. ...
    29. }
    30. \endverbatim
    31. */
    32. template<class MReq, class MRes>
    33. ServiceServer advertiseService(const std::string& service, bool(*srv_func)(MReq&, MRes&))

    -------------------------------------------

    三。 回旋函数

    在ROS程序中,频繁的使用了 ros::spin() 和 ros::spinOnce() 两个回旋函数,可以用于处理回调函数

    :ros::spin() 是进入了循环执行回调函数,而 ros::spinOnce() 只会执行一次回调函数(没有循环),在 ros::spin() 后的语句不会执行到,而 ros::spinOnce() 后的语句可以执行

    所以在发布方中,我们使用的回旋函数也只是使用一次,

    但是在订阅者中,需要不断回旋,所以我们使用spin

    --------------------

    四。 时间函数

    (前面的历程我们并没有使用到,所以这里重新开始说明)

    1. 时刻

    1. ros::init(argc,argv,"hello_time");
    2. ros::NodeHandle nh;//必须创建句柄,否则时间没有初始化,导致后续API调用失败
    3. ros::Time right_now = ros::Time::now();//将当前时刻封装成对象
    4. ROS_INFO("当前时刻:%.2f",right_now.toSec());//获取距离 1970年01月01日 00:00:00 的秒数
    5. ROS_INFO("当前时刻:%d",right_now.sec);//获取距离 1970年01月01日 00:00:00 的秒数
    6. ros::Time someTime(100,100000000);// 参数1:秒数 参数2:纳秒
    7. ROS_INFO("时刻:%.2f",someTime.toSec()); //100.10
    8. ros::Time someTime2(100.3);//直接传入 double 类型的秒数
    9. ROS_INFO("时刻:%.2f",someTime2.toSec()); //100.30

    2。 持续时间

    1. ROS_INFO("当前时刻:%.2f",ros::Time::now().toSec());
    2. ros::Duration du(10);//持续10秒钟,参数是double类型的,以秒为单位
    3. du.sleep();//按照指定的持续时间休眠
    4. ROS_INFO("持续时间:%.2f",du.toSec());//将持续时间换算成秒
    5. ROS_INFO("当前时刻:%.2f",ros::Time::now().toSec());

    3. 设置运行频率(这个是有出现过的,可以决定每一秒发送几次消息)

    1. ros::Rate rate(1);//指定频率
    2. while (true)
    3. {
    4. ROS_INFO("-----------code----------");
    5. rate.sleep();//休眠,休眠时间 = 1 / 频率。
    6. }

    -------------------------

    五。 其他函数

    1. 循环的判断条件一般由节点状态来控制,C++中可以通过 ros::ok() 来判断节点状态是否正常

    1. while(ros::ok())

    2. 日志函数 ---- printf 打印

    1. ROS_DEBUG("hello,DEBUG"); //不会输出
    2. ROS_INFO("hello,INFO"); //默认白色字体
    3. ROS_WARN("Hello,WARN"); //默认黄色字体
    4. ROS_ERROR("hello,ERROR");//默认红色字体
    5. ROS_FATAL("hello,FATAL");//默认红色字体

  • 相关阅读:
    【毕业设计】基于SSM的新闻管理系统
    Jmeter系列-监听器Listeners的介绍(9)
    第二章 关系数据库
    2022-08-05 学习日记(25th day)集合框架---List
    web前端期末大作业 ——电影主题介绍 你好,李焕英 ——html+css+javascript网页设计实例
    mac系统u盘启动盘制作教程,更新至macOS Sonoma 14
    Spring Authorization Server(AS)从 Mysql 中读取客户端、用户
    C++基础入门详解(一)
    测试用例的设计方法(全):边界值分析方法
    基于HFSS的线阵综合分析
  • 原文地址:https://blog.csdn.net/ArtoriaLili/article/details/125553955