ROS实践笔记11

ROS常用API

  1. ROS节点的初始化相关API:

    c++初始化

    void init(int &argc, char **argv, const std::string& name, uint32_t options = 0);
    

    参数列表:

    1. argc ---> 程序调用时传入实参的个数,第一个是文件自身
    2. argv ---> 封装参数的数据
    3. name ---> 为节点命名,节点名称具有唯一性
    4. options ---> 节点启动选项

    使用:

    1. argc 和 argv 的使用

      如果安装ROS中的特定格式传入实参,ROS就能加以使用。

    2. options 的使用

      通过在节点名后添加随机数来实现同名节点的多次启动。第四个参数直接输入ros::init_options::AnonymousName即可。

    python初始化

    def init_node(name, argv=None, anonymous=False, log_level=None, disable_rostime=False, disable_rosout=False, disable_signals=False, xmlrpc_port=0, tcpros_port=0):
    

    参数列表:

    1. name ---> 节点名称,不能使用命名空间(不能包含 '/') type:string
    2. anonymous ---> 取值为 true 时,为节点名称后缀随机编号
    3. argv ---> 使用特定格式传参
  2. 话题与服务相关对象:

    c++

    在 roscpp 中,话题和服务的相关对象一般由 NodeHandle 创建。

    ros::NodeHandle nh;
    

    创建发布者对象:

    Publisher advertise(const std::string& topic, uint32_t queue_size, bool latch = false)
    

    参数列表:

    1. topic ---> 话题名称
    2. queue_size ---> 缓存队列长度
    3. latch ---> 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有订阅者连接时会将该消息发送给订阅者

    使用:

    latch 设置为true的作用:

    以静态地图的发布为例,有两个方案:

    1. 发布方以固定频率发送地图信息,效率偏低。
    2. latch 设置为true 并且只发送一次信息,每当有订阅者订阅消息时,该信息就会发送给该订阅者,效率较高。

    python

    def __init__(self, name, data_class, subscriber_listener=None, tcp_nodelay=False, latch=False, headers=None, queue_size=None):
    
  3. spin()函数:

    c++

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

    ROSCPP_DECL void spinOnce();
    
    ROSCPP_DECL void spin();
    

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

    python

    def spin():
    
  4. 时间:

    1. 时刻:获取时刻,或是设置指定时刻

    c++

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

    python

    # 获取当前时刻
    right_now = rospy.Time.now()
    rospy.loginfo("当前时刻:%.2f",right_now.to_sec())
    rospy.loginfo("当前时刻:%.2f",right_now.to_nsec())
    # 自定义时刻
    some_time1 = rospy.Time(1234.567891011)
    some_time2 = rospy.Time(1234,567891011)
    rospy.loginfo("设置时刻1:%.2f",some_time1.to_sec())
    rospy.loginfo("设置时刻2:%.2f",some_time2.to_sec())
    
    # 从时间创建对象
    # some_time3 = rospy.Time.from_seconds(543.21)
    some_time3 = rospy.Time.from_sec(543.21) # from_sec 替换了 from_seconds
    rospy.loginfo("设置时刻3:%.2f",some_time3.to_sec())
    
    1. 持续时间:设置一个时间区间(间隔)

    c++

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

    python

    # 持续时间相关API
    rospy.loginfo("持续时间测试开始.....")
    du = rospy.Duration(3.3)
    rospy.loginfo("du1 持续时间:%.2f",du.to_sec())
    rospy.sleep(du) #休眠函数
    rospy.loginfo("持续时间测试结束.....")
    
    
    1. 持续时间与时刻运算:为了方便使用,ROS中提供了时间与时刻的运算

      c++

    ROS_INFO("时间运算");
    ros::Time now = ros::Time::now();
    ros::Duration du1(10);
    ros::Duration du2(20);
    ROS_INFO("当前时刻:%.2f",now.toSec());
    //1.time 与 duration 运算
    ros::Time after_now = now + du1;
    ros::Time before_now = now - du1;
    ROS_INFO("当前时刻之后:%.2f",after_now.toSec());
    ROS_INFO("当前时刻之前:%.2f",before_now.toSec());
    
    //2.duration 之间相互运算
    ros::Duration du3 = du1 + du2;
    ros::Duration du4 = du1 - du2;
    ROS_INFO("du3 = %.2f",du3.toSec());
    ROS_INFO("du4 = %.2f",du4.toSec());
    //PS: time 与 time 不可以运算
    // ros::Time nn = now + before_now;//异常
    // ros::Duration = now - before_now;//被允许
    

    python

    rospy.loginfo("时间运算")
    now = rospy.Time.now()
    du1 = rospy.Duration(10)
    du2 = rospy.Duration(20)
    rospy.loginfo("当前时刻:%.2f",now.to_sec())
    before_now = now - du1
    after_now = now + du1
    dd = du1 + du2
    # now = now + now #非法
    rospy.loginfo("之前时刻:%.2f",before_now.to_sec())
    rospy.loginfo("之后时刻:%.2f",after_now.to_sec())
    rospy.loginfo("持续时间相加:%.2f",dd.to_sec())
    
    1. 设置运行频率

    c++

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

    python

    # 设置执行频率
    rate = rospy.Rate(0.5)
    while not rospy.is_shutdown():
    rate.sleep() #休眠
    rospy.loginfo("+++++++++++++++")
    
    1. 定时器:ROS 中内置了专门的定时器,可以实现与 ros::Rate 类似的效果

    c++

     Timer createTimer(Duration period,
     const TimerCallback& callback,
     bool oneshot = false,
     bool autostart = true)
     // timer.start();// 手动启动定时器
     ros::spin()//必须要有spin函数
    

    参数列表:

    1. period ---> 时间间隔
    2. callback ---> 回调函数
    3. oneshot 如果设置为 true,只执行一次回调函数,设置为 false,就循环执行。
    4. autostart 如果为true,返回已经启动的定时器,设置为 false,需要手动启动。
      回调函数:
    void doSomeThing(const ros::TimerEvent &event)
    {
        ROS_INFO("-------------");
        ROS_INFO("event:%s",std::to_string(event.current_real.toSec()).c_str());//打印函数被调用的时刻
    }
    

    python

    def __init__(self, period, callback, oneshot=False, reset=False):
    
    def doMsg(event):
    rospy.loginfo("+++++++++++")
    rospy.loginfo("当前时刻:%s",str(event.current_real))
    
  5. 其他函数:

    在发布实现时,一般会循环发布消息,循环的判断条件一般由节点状态来控制,C++中可以通过 ros::ok() 来判断节点状态是否正常,而 python 中则通过 rospy.is_shutdown() 来实现判断,导致节点退出的原因主要有如下几种:

    1. 节点接收到了关闭信息,比如常用的 ctrl + c 快捷键就是关闭节点的信号;
    2. 同名节点启动,导致现有节点退出;
    3. 程序中的其他部分调用了节点关闭相关的API(C++中是ros::shutdown(),python中是rospy.signal_shutdown())
      另外,日志相关的函数也是极其常用的,在ROS中日志被划分成如下级别:
    4. DEBUG(调试):只在调试时使用,此类消息不会输出到控制台;
    5. INFO(信息):标准消息,一般用于说明系统内正在执行的操作;
    6. WARN(警告):提醒一些异常情况,但程序仍然可以执行;
    7. ERROR(错误):提示错误信息,此类错误会影响程序运行;
    8. FATAL(严重错误):此类错误将阻止节点继续运行。

    c++

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

    python

    rospy.logdebug("hello,debug")  #不会输出
     rospy.loginfo("hello,info")  #默认白色字体
     rospy.logwarn("hello,warn")  #默认黄色字体
     rospy.logerr("hello,error")  #默认红色字体
     rospy.logfatal("hello,fatal") #默认红色字体
    
posted @   一心如旧  阅读(301)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示