我正在进行使用Turtlesim工具的练习。
我必须创建一个节点vel_filter,它订阅pubvel节点发布的消息(来自O' Kane的书“A Gentle Introduction to Ros”)并立即重新发布那些具有正角速度的消息。
pubvel代码如下:
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <stdlib.h>
int main(int argc, char**argv){
ros::init(argc, argv, "publish_velocity");
ros::NodeHandle nh;
ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("turtle1/cmd_vel", 1000);
srand(time(0));
ros::Rate rate(2);
while(ros::ok()){
geometry_msgs::Twist msg;
msg.linear.x = double(rand())/double(RAND_MAX);
msg.angular.z = 2*double(rand())/double(RAND_MAX) - 1;
pub.publish(msg);
ROS_INFO_STREAM("Sending random velocity command:"<<" linear="<<msg.linear.x<<" angular="<<msg.angular.z);
rate.sleep();
}
}
这会在turtle1 / cmd_vel主题上发布几何/ Twist类型的随机线性和角度移动消息。现在我想创建一个节点vel_filter,订阅此主题以接收这些消息,并仅在不同主题上发布具有正角速度的消息。 (我不确定我应该发布哪个主题)。
到目前为止,我为vel_filter节点写的是:
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Pose.h>
void filterVelocityCallback(const geometry_msgs::Twist& msg){
if (msg.angular.z > 0){
ROS_INFO_STREAM("Subscriber velocities:"<<" linear="<<msg.linear.x<<" angular="<<msg.angular.z);
}
}
int main(int argc, char **argv){
ros::init(argc, argv, "filter_velocity");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("turtle1/cmd_vel",1000,&filterVelocityCallback);
ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("turtle1/pose", 1000);
ros::Rate rate(2);
while(ros::ok()){
geometry_msgs::Twist msg;
pub.publish(msg);
ROS_INFO_STREAM("Filtered velocities:"<<" linear="<<msg.linear.x<<" angular="<<msg.angular.z);
rate.sleep();
}
ros:
:spin();
}
但这给了我以下内容:
[ INFO] [1492674948.750695494]: Filtered velocities: linear=0 angular=0
[ INFO] [1492674949.250756910]: Filtered velocities: linear=0 angular=0
[ INFO] [1492674949.750739740]: Filtered velocities: linear=0 angular=0
[ INFO] [1492674950.250739795]: Filtered velocities: linear=0 angular=0
[ INFO] [1492674950.750736997]: Filtered velocities: linear=0 angular=0
[ INFO] [1492674951.250766297]: Filtered velocities: linear=0 angular=0
请注意,我还没有应用过滤器。我使用turtle1 / pose主题发布(如果这是正确的,我有疑问)。如果我只应用订阅者,它可以正常工作,但是当我添加发布者时,它不再能够达到回调函数。
我的CMakeLists看起来像这样(不要担心vel_printer):
cmake_minimum_required(VERSION 2.8.3)
project(me41025_33)
find_package(catkin REQUIRED COMPONENTS roscpp geometry_msgs turtlesim)
catkin_package()
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(${PROJECT_NAME}_pubvel pubvel.cpp)
add_executable(${PROJECT_NAME}_vel_printer vel_printer.cpp)
add_executable(${PROJECT_NAME}_vel_filter vel_filter.cpp)
target_link_libraries(${PROJECT_NAME}_pubvel ${catkin_LIBRARIES})
target_link_libraries(${PROJECT_NAME}_vel_printer ${catkin_LIBRARIES})
target_link_libraries(${PROJECT_NAME}_vel_filter ${catkin_LIBRARIES})
set_target_properties(${PROJECT_NAME}_pubvel PROPERTIES OUTPUT_NAME pubvel PREFIX "")
set_target_properties(${PROJECT_NAME}_vel_printer PROPERTIES OUTPUT_NAME vel_printer PREFIX "")
set_target_properties(${PROJECT_NAME}_vel_filter PROPERTIES OUTPUT_NAME vel_filter PREFIX "")
我的package.xml看起来像这样:
<?xml version="1.0"?>
<package>
<name>me41025_33</name>
<version>0.0.0</version>
<description>The agitr package</description>
<maintainer email="stijn@todo.todo">stijn</maintainer>
<license>TODO</license>
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<build_depend>geometry_msgs</build_depend>
<run_depend>geometry_msgs</run_depend>
<build_depend>turtlesim</build_depend>
<run_depend>turtlesim</run_depend>
<buildtool_depend>catkin</buildtool_depend>
</package>
提前感谢您的帮助!
答案 0 :(得分:1)
此处您不需要ros::spin()
。 ros::spinOnce();
循环中需要while
。请阅读documentation以获取解释。
另请注意,您将pubvel
和vel_filter
称为帖子中的节点。这些不是节点。 publish_velocity
和filter_velocity
分别是此处的节点。
此外,如果不在回调函数中应用条件并在主函数的while
循环内执行此操作,那会更好。
Sp你固定的vel_filter.cpp
文件将是:
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Pose.h>
float linx, angZ;
void filterVelocityCallback(const geometry_msgs::Twist& msg){
//Using the callback function just for subscribing
//Subscribing the message and storing it in 'linx' and 'angZ'
linx = msg.linear.x; angZ = msg.angular.z;
}
int main(int argc, char **argv){
ros::init(argc, argv, "filter_velocity");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("turtle1/cmd_vel",1000,&filterVelocityCallback);
ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("turtle1/pose", 1000);
ros::Rate rate(2);
while(ros::ok()){
geometry_msgs::Twist msg;
msg.linear.x = linx; msg.angular.z = angZ;
//It would be better to apply the conditions within the main function and use the
//Callback function just for subscribing
if (angZ > 0){
ROS_INFO_STREAM("Subscriber velocities:"<<" linear="<<linx<<" angular="<<angZ);
//The above line doesn't publish. It's like printf (but not exactly)
pub.publish(msg); //This line is for publishing. It publishes to 'turtle1/pose'
}
rate.sleep();
ros::spinOnce(); //Notice this
}
}
推荐阅读: