ROSNOTE : ros::spin() / ros::spinOnce() /rospy.spin()

如果写了消息订阅函数,那一定要写ros::spin() 或者ros::spinOnce(),不然是得不到另一边发出的消息或者信息

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
 
int main(int argc, char **argv)
{
    //ROS节点初始化,节点名称是talker
    ros::init(argc, argv, "talker");
    //创建节点的句柄
    ros::NodeHandle n;
    //创建一个Publisher ,发布名为chatter的topic,消息类型是std_msgs::String,1000是消息发布队列的大小
    ros::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类似与print,用来打印信息
        ROS_INFO("%s", msg.data.c_str());
 
        /**
         * 向 Topic: chatter 发送消息, 发送频率为10Hz(1秒发10次);消息池最大容量1000。
         */
        chatter_pub.publish(msg);
        //循环等待回调函数,用来处理节点订阅话题的所有回调函数
        ros::spinOnce();
        //按照循环频率延时,publisher一个周期工作完成后,可以让节点休息一段时间,调用休眠函数让节点进入休眠状态,设置休眠的时间,休息后在开始下一个周期的工作
        loop_rate.sleep();
        ++count;
    }
    return 0;
}

接受端:

#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)
{
    //初始化节点listener
    ros::init(argc, argv, "listener");
    //初始化节点句柄
    ros::NodeHandle n;
    //创建一个Subscriber,订阅chatter的话题,注册回调函数
    ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
 
    /**
     * ros::spin() 将会进入循环, 一直调用回调函数chatterCallback(),每次调用1000个数据。
     * 当用户输入Ctrl+C或者ROS主进程关闭时退出,
     */
    ros::spin();
    return 0;
}

 接受端:

#include "ros/ros.h"
#include "std_msgs/String.h"
  
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
    /*...TODO...*/ 
}
  
int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle n;
    ros::Subscriber sub = n.subscribe("chatter", 2, chatterCallback);
  
    ros::Rate loop_rate(5);
    while (ros::ok())
    {
        /*...TODO...*/ 
 
        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

 

 

用python写ros代码

1.关于rospy.spin()调用多次callback ,程序若无rospy.spin(),也无上面黄色部分,则订阅一次发布消息会调用多次callback。

2.当接收到订阅消息时,ballback在r.sleep()时间空隙的时候调用,所以callback的执行时间不能超过r.sleep()提供的间隙时间,例如在callback里设置sleep(1),则会消耗完r.sleep(),然后运行print 'after sleep 1s',此时flg=0,因此跳出while循环,结束程序。直接用sleep()代替rospy.Rate和r.sleep(),也是可以的。

3.最好使用:

while not rospy.is_shutdown(): #True:
         if self.flg==1: #encoder_list[0]='e':

 

#!/usr/bin/env python
import rospy
from bzrobot_msgs.msg import bzr_WheelLinearVels

#from threading import Thread
from time import sleep

class RS232MotorComm():

    def callback(self, data):
        print '****************************************start callback'
        self.flg=0
        sleep(0.05)
        rospy.loginfo("speed %f %f",data.leftWheelLinearVel, data.rightWheelLinearVel)
        self.flg=1
    
    def motor_listener(self):
        self.flg=1
        rospy.init_node('rs232_motor_comm', anonymous=True)

        rospy.Subscriber("control_wheel_linear_vel", bzr_WheelLinearVels, self.callback)
        #sleep(1)
    
        r = rospy.Rate(10) # 10hz
        while self.flg==1:#not rospy.is_shutdown():#True:
            print'where'
            r.sleep()  #time must enough for callback,or it will out while loop
            print'after sleep 1s'

if __name__ == '__main__':
    
    motor_controller = RS232MotorComm()
    print'the1'

    motor_controller.motor_listener()
    #rospy.spin()
    print'end'

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值