将ros中suscriber和publisher写入class中
相比于笨拙的全局变量和全局函数,将suscriber和publisher成一个class,形式更加简洁和容易管理,一个节点就是一个类
参考资料
http://answers.ros.org/question/59725/publishing-to-a-topic-via-subscriber-callback-function/
http://wiki.ros.org/roscpp_tutorials/Tutorials/UsingClassMethodsAsCallbacks
下面是自己写的示例代码:
#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <geometry_msgs/Pose2D.h>
#include <tf/transform_listener.h>
#include <stdio.h>
class test
{
private:
ros::NodeHandle nh_;
ros::Subscriber sub_;
tf::TransformBroadcaster br_;
bool data_ready; public:
test(ros::NodeHandle& nh)
{
nh_=nh;
sub_ = nh_.subscribe("/user_set", , &test::call_back,this);
data_ready = false;
}
//注意这里需要加const
void call_back(const geometry_msgs::Pose2DPtr& msgs)
{
ROS_INFO("recive");
tf::Transform dest_transform;
dest_transform.setOrigin(tf::Vector3(msgs->x,msgs->y,));
tf::Quaternion q;
q.setRPY(, , msgs->theta);
dest_transform.setRotation(q);
br_.sendTransform(tf::StampedTransform(dest_transform,ros::Time::now(),"world","user_set_frame"));
data_ready = true;
} bool is_data_ready()
{
if(data_ready)
return true;
else
return false;
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "tf_broadcaster");
ros::NodeHandle node;
test Otest(node);
tf::TransformListener listener;
tf::StampedTransform transform; while(ros::ok())
{
if(!Otest.is_data_ready())
{
ros::spinOnce(); continue;
}
ROS_INFO("lookup_transfoem;");
try
{
listener.waitForTransform("world","user_set_frame",ros::Time::now(), ros::Duration(1.0));
listener.lookupTransform("world","user_set_frame",ros::Time(),transform);
}
catch (tf::TransformException ex)
{
ROS_ERROR("%s",ex.what());
break;
}
tf::Vector3 vectortf = transform.getOrigin();
ROS_INFO("transform.x:%f,transform.y:%f,transform.z:%f",vectortf.x(),vectortf.y(),vectortf.z());
ros::spinOnce();
}
return ;
}
下面是publisher,上面那段代码调好了,下面还没有
#include <iostream> #include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Pose2D.h>
#include <tf/transform_listener.h>
#include <tf/transform_broadcaster.h> class RobotDriver
{
private:
//! The node handle we'll be using
ros::NodeHandle nh_;
//! We will be publishing to the "cmd_vel" topic to issue commands
ros::Publisher cmd_vel_pub_;
//! we will be suscribing the topic "pos_dest"
ros::Subscriber sub = n.subscribe("pos_dest", 10, pos_dest_callback);
//! pos_dest_callback
tf::Transform dest_transform;
void pos_dest_callback(geometry_msgs::Pose2DPtr& msgs)
{
static tf::TransformBroadcaster br;
dest_transform.setOrigin(tf::Vector3(msgs->x,msgs->y,0));
tf::Quaternion q;
q.setRPY(0, 0, msgs->theta);
dest_transform.setRotation(q);
br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "odom", "pos_dest")); }
//! We will be listening to TF transforms as well
tf::TransformListener listener_;
//! cmd
geometry_msgs::Twist base_cmd_straight;
geometry_msgs::Twist base_cmd_turn;
geometry_msgs::Twist stop_cmd;
tf::Transform current_transform; public:
//! ROS node initialization
RobotDriver(ros::NodeHandle &nh)
{
nh_ = nh;
//set up the publisher for the cmd_vel topic
cmd_vel_pub_ = nh_.advertise<geometry_msgs::Twist>("cmd_vel", 1);
//cmd
//the command will be to go forward at 0.25 m/s
base_cmd_straight.linear.y = base_cmd_straight.angular.z = 0;
base_cmd.base_cmd_straight.x = 0.1; base_cmd_turn.linear.x = base_cmd_turn.linear.y = 0.0;
base_cmd_turn.angular.z = 0.75; stop_cmd.linear.y = stop_cmd.angular.z = 0;
stop_cmd.linear.x = 0;
} bool turnOdom(bool clockwise, double radians)
{
while(radians < 0) radians += 2*M_PI;
while(radians > 2*M_PI) radians -= 2*M_PI; //wait for the listener to get the first message
listener_.waitForTransform("base_link", "odom",
ros::Time(0), ros::Duration(1.0)); //we will record transforms here
tf::StampedTransform start_transform;
tf::StampedTransform current_transform; //record the starting transform from the odometry to the base frame
listener_.lookupTransform("base_link", "odom",
ros::Time(0), start_transform); //we will be sending commands of type "twist"
geometry_msgs::Twist base_cmd;
//the command will be to turn at 0.75 rad/s
base_cmd.linear.x = base_cmd.linear.y = 0.0;
base_cmd.angular.z = 0.75; geometry_msgs::Twist stop_cmd;
stop_cmd.linear.y = stop_cmd.angular.z = 0;
stop_cmd.linear.x = 0; if (clockwise) base_cmd.angular.z = -base_cmd.angular.z; //the axis we want to be rotating by
tf::Vector3 desired_turn_axis(0,0,1);
if (!clockwise) desired_turn_axis = -desired_turn_axis; ros::Rate rate(10.0);
bool done = false;
while (!done && nh_.ok())
{
//send the drive command
cmd_vel_pub_.publish(base_cmd);
rate.sleep();
//get the current transform
try
{
listener_.lookupTransform("base_link", "odom",
ros::Time(0), current_transform);
}
catch (tf::TransformException ex)
{
ROS_ERROR("%s",ex.what());
break;
}
tf::Transform global_transform =
current_transform;
tf::Vector3 actual_turn_axis =
global_transform.getRotation().getAxis();
ROS_INFO("actual_turn_axis.x=%f,actual_turn_axis.y=%f,actual_turn_axis.z=%f",(float)actual_turn_axis.getX(),(float)actual_turn_axis.getY(),(float)actual_turn_axis.getZ());
double angle_turned = global_transform.getRotation().getAngle();
if ( fabs(angle_turned) < 1.0e-2) continue; if ( actual_turn_axis.dot( desired_turn_axis ) < 0 )
angle_turned = 2 * M_PI - angle_turned; if (angle_turned > radians) done = true;
}
if (done)
{
cmd_vel_pub_.publish(stop_cmd); return true;
}
return false;
} }; int main(int argc, char** argv)
{
//init the ROS node
ros::init(argc, argv, "robot_driver");
ros::NodeHandle nh; RobotDriver driver(nh);
driver.driveForwardOdom(0.2);
}
将ros中suscriber和publisher写入class中的更多相关文章
- elasticsearch备份与恢复4_使用ES-Hadoop将ES中的索引数据写入HDFS中
背景知识见链接:elasticsearch备份与恢复3_使用ES-Hadoop将HDFS数据写入Elasticsearch中 项目参考<Elasticsearch集成Hadoop最佳实践> ...
- ListView中的数据表格写入Excel中
SaveFileDialog sfd = new SaveFileDialog(); sfd.DefaultExt = "xls"; sfd.Filter = "Exce ...
- Excelvba从文件中逐行读取并写入excel中
Sub 読み込む() Dim result As Long Dim dialog As FileDialog Set dialog = Application.FileDialog(msoFileDi ...
- 将Datagridview中的数据导出至Excel中
首先添加一个模块ImportToExcel,并添加引用 然后导入命名空间: Imports Microsoft.Office.Interop Imports System.Da ...
- 将gridFS中的图片文件写入硬盘
开启用户验证下的gridfs 连接使用,在执行脚本前可以在python shell中 from pymongo import Connectionfrom gridfs import *con = C ...
- 简单通过java的socket&serversocket以及多线程技术实现多客户端的数据的传输,并将数据写入hbase中
业务需求说明,由于公司数据中心处于刚开始部署的阶段,这需要涉及其它部分将数据全部汇总到数据中心,这实现的方式是同上传json文件,通过采用socket&serversocket实现传输. 其中 ...
- Java基础知识强化之IO流笔记51:IO流练习之 键盘录入学生信息按照总分排序写入文本文件中的案例
1. 键盘录入学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分排序写入文本文件中 分析: A:创建学生类 B:创建集合对象 TreeSet<Student> ...
- Scrapy基础(九)————将不定长度的URL进行固定长度写入Item中
前面讲到将每篇文章的URL写入Item,但是每个url的长度是不同的,可以在Item中设置一个字段怎样使得每个URL的长度相同,这就需要对每个URL进行md5运算,使得长度统一,再加入到设定的Item ...
- spark读取 kafka nginx网站日志消息 并写入HDFS中(转)
原文链接:spark读取 kafka nginx网站日志消息 并写入HDFS中 spark 版本为1.0 kafka 版本为0.8 首先来看看kafka的架构图 详细了解请参考官方 我这边有三台机器用 ...
随机推荐
- 腾讯QQ空间穿越时光轴3D特效
<DOCTYPE html> <html> <head> <title>腾讯QQ空间穿越光轴3D特效</title> <style&g ...
- Android学习笔记(四)之碎片化Fragment实现仿人人客户端的侧边栏
其实一种好的UI布局,可以使用户感到更加的亲切与方便.最近非常流行的莫过于侧边栏了,其实我也做过很多侧边栏的应用,但是那些侧边栏的使用我 都不是很满意,现在重新整理,重新写了一个相对来说我比较满意的侧 ...
- 用Fragment实现如新浪微博一样的底部菜单的切换
像我这个有强迫症的人来说,自从TabActivity抛弃之后,再使用看到一个个警告和一条条划着的横线,心里很不舒服,现在终于下定决心用Fragment来替换掉TabActivity了!我的研究成果如下 ...
- windows版本cloudbase-init流程说明
源码流程说明 - 程序首先判断操作系统类型,加载对应的模块 - 加载服务,服务共分为四种: 'cloudbaseinit.metadata.services.httpservice.HttpServi ...
- css background-size与背景图片填满div
background-size与背景图片填满div 在开发中,常有需要将一张图片作为一个div的背景图片充满div的需求 background-size的取值及解释 background-size共有 ...
- 基于TensorFlow的循环神经网络(RNN)
RNN适用场景 循环神经网络(Recurrent Neural Network)适合处理和预测时序数据 RNN的特点 RNN的隐藏层之间的节点是有连接的,他的输入是输入层的输出向量.extend(上一 ...
- JavaScript各种数据类型
(一)JavaScript跟Java.Python等语言一样,也是一门编程语言,配合着html,css等可以让画面动起来, 在页面中导入方式主要有两种,如图 可以自己写在文件里面,一般写在body标签 ...
- django之HTTPResponse和JsonResponse详解
HttpResponse对象 Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数.那么视图函数在处理完相关的逻辑后,也需要返回一个响 ...
- sqlalchemy presto 时间比较
大数据统计时,需要计算开仓订单减掉经纪商时间差,等于n 小时 或 星期几的订单. presto sql语句如下: select sum(profit) from t_table where open_ ...
- Python中的返回函数与闭包
返回函数,顾名思义,就是高阶函数可以把函数作为return值返回.与闭包的关系是:闭包需要以返回函数的形式实现. 一. 返回函数 比如我们有一个求和函数: >>> def calc_ ...