ROS API使用

单纯为了用的时候可以找到,并不详细。

API官方文档

http://wiki.ros.org/APIs
https://docs.ros.org/en/api/roscpp/html/

1. 初始化-init

argc, argv, name

argc 参数个数, (1+n个,1是运行文件的名字,n是传入的参数)。
argv 参数列表,n个参数会被添加到参数服务器中。
name 节点名称,需要保证其唯一性,不允许包含命名空间。

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

终端指定参数到参数服务器

argc, argv可以通过在终端启动时添加。

rosrun pkg node _param1:=value1 _param2:=value2 

用例

使用以下代码编写cpp文件,Cmake正常编译。

#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char *argv[])
{
    setlocale(LC_ALL, "");
    //优化实现,获取命令中的参数
    std::stringstream ss;
    for (int i = 0; i < argc; i++)
        ss << "\n      第" << i << "个参数对应内容为: " << argv[i] << ";";
    ROS_INFO_STREAM(ss.str());
    ros::init(argc, argv, "erGouzi"); //节点名字唯一
    ros::NodeHandle nh;
    ros::Publisher client = nh.advertise<std_msgs::String>("fang",10);

    return 0;
}

终端运行:

rosrun plumbing_apis demo01_apis_init _length:=2 _width:=5

然后分别运行:

rosparam get /erGouzi/length
rosparam get /erGouzi/width

可以查看到刚刚自己添加的参数已经成功。

options

options 节点启动选项,重名节点启动时,之前的节点会被关闭。
使用ros::init_options::AnonymousName可以自动为节点添加时间后缀,防止重复。

使用

ros::init(argc, argv, "erGouzi", ros::init_options::AnonymousName); 

rosnode list结果:

/erGouzi_1712628973497673621
/erGouzi_1712628984491861251

Python中

rospy.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)

2. 发布-advertise 和 订阅-subscribe

topic, queue_size

topic 发布消息使用的话题
queue_size 等待发送给订阅者的最大消息数量。

template <class M>
Publisher advertise(const std::string& topic, uint32_t queue_size, bool latch = false)

使用:

ros::Publisher pub = nh.advertise<plumbing_msg::Msg>("liaotian", 1000);
ros::Subscriber sub = nh.subscribe("liaotian", 10, doMsg);
pub.publish(msg)

latch

latch (optional) 如果为 true,该话题发布的最后一条消息将被保存,并且后期当有新的订阅者连接时会将该消息发送给订阅者。如果是false,则不保存。
使用场景
通常,如果要发送一个静态的数据(比如地图),不用latch时:要固定频率一直发送(否则新加入的订阅者可能接受不到该数据),浪费资源;使用latch时:保存好数据,当新的订阅者加入时自动发送一次,不浪费资源。

Python中

class Publisher(Topic):
    def __init__(self, name, data_class, subscriber_listener=None, tcp_nodelay=False, latch=False, headers=None, queue_size=None):

class Subscriber(Topic):
    def __init__(self, name, data_class, callback=None, callback_args=None, queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False):

3. 服务-advertiseService 和 客户-serviceClient

ServiceServer advertiseService(const std::string& service, bool(*srv_func)(MReq&, MRes&))

ServiceClient serviceClient(const std::string& service_name, bool persistent = false, 
                              const M_string& header_values = M_string())

persistent

persistent标志用于指示服务是否应该保持持久性连接。
如果将此标志设置为True,则服务将保持连接状态,直到调用方显式断开连接为止。这意味着一旦服务被调用,连接将保持打开状态,直到调用方决定关闭它,而不是在每次请求之间重新建立连接。

使用:

ros::ServiceServer server = nh.advertiseService("AddInts",doReq);
ros::ServiceClient client = nh.serviceClient<demo03_server_client::AddInts>("AddInts");
client.waitForExistence();
client.call(srv);

Python中

class Service(ServiceImpl):
    def __init__(self, name, service_class, handler, buff_size=DEFAULT_BUFF_SIZE, error_handler=None):

class ServiceProxy(_Service):
    def __init__(self, name, service_class, persistent=False, headers=None):

4. 回旋函数-spin&spinOnce

为处理回调函数而使用。

spin

spin:一直检查队列中的回调函数并执行然后继续检查,会堵塞到当前行。

spinOnce

spinOnce:运行到spinOnce时,将队列中所有回调函数都执行完(不是只执行队列里的最后一个),然后继续执行其他代码,不会堵塞。

5. 时间戳-Time

获取的是以1970年01月01日为起始时间到现在的时间差。
使用时,必须提前调用ros::NodeHandle nh初始化相关函数。

时刻

当前时刻

ros::Time now = ros::Time::now();
double now_time = now.toSec();
ROS_INFO("当前时刻: %.2f", now.toSec());
ROS_INFO("当前时刻-秒部分: %d", now.sec);
ROS_INFO("当前时刻-纳秒部分: %d", now.nsec);

设置固定时刻

就是使用构造函数,有两种

    ros::Time t1(100, 35); // 参数1:秒数  参数2:纳秒
    ros::Time t2(100.35);//就是上面的两者相加
    ROS_INFO("t1时刻: %.2f", t1.toSec());
    ROS_INFO("t2时刻: %.2f", t2.toSec());

持续时间

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());

时刻与持续时间的运算

包含 :

  • 时刻与持续时间的加减。
  • 持续时间与持续时间的加减。

没有时刻与时刻的加减。

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;//异常

睡眠

Rate

ros::Rate rate(10);  //指定频率
rate.sleep(); //睡眠时间为: 1/10=0.1s

Duration

ros::Duration du(10);//持续10秒钟
du.sleep();//睡眠时间为: 10s

定时器

period 时间间隔
callback 回调函数
oneshot 如果设置为 true,只执行一次回调函数,设置为 false, 就循环执行。
autostart 如果为true,返回已经启动的定时器,设置为 false,需要手动启动。

Timer createTimer(Duration period, const TimerCallback& callback, bool oneshot = false, bool autostart = true) const;

启动 timer.start();
停止 timer.stop();

用例

void print_time(const ros::TimerEvent event)
{
    std::time_t current_time = ros::Time::now().toSec();
    struct std::tm* local_time = localtime(&current_time);
    char buffer[80];
    std::strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", local_time);
    std::cout << "Current Time: " << buffer << std::endl;
}
// main函数下
ros::Timer timer = nh.createTimer(ros::Duration(2), print_time);
ros::spin(); //处理回调函数

5. 节点状态

节点状态判断

ros::ok();

true:节点还健在;
false:节点已经停止。

关闭节点函数

ros::shutdown();

python中是 rospy.signal_shutdown()

6.日志函数

ROS_DEBUG("hello,DEBUG"); //不会输出在控制台,调试时才显示
ROS_INFO("hello,INFO"); //默认白色字体
ROS_WARN("Hello,WARN"); //默认黄色字体
ROS_ERROR("hello,ERROR");//默认红色字体
ROS_FATAL("hello,FATAL");//默认红色字体
  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值