我正在研究ROS的turtlesim教程。
启动文件ex74.launch
启动4个节点:
-turtlesim节点(动画乌龟的动作)
- pubvel(发布随机角度和线性速度命令)
- vel_filter(订阅pubvel发布的主题。此节点过滤角速度并仅发布消息 角速度小于参数max_ang_vel的车辆 - vel_printer(打印过滤的速度)
脚本和启动文件在我的问题结尾处给出。
现在的目标是为max_ang_vel
设置初始值,并从命令行进行更改。
但是,当我运行启动文件时,我收到以下错误:
来自vel_filter
和vel_printer
的所有角度和线性速度均为0。
任何人都可以帮我解决这个问题吗?
提前致谢!
ex74.launch
<launch>
<node
pkg="turtlesim"
type="turtlesim_node"
name="turtlesim"
/> ## launch animation of turtle
<node
pkg="me41025_74"
type="pubvel"
name="publish_velocity"
required="true"
launch-prefix="xterm -e"
output="screen"
/> ## launch pubvel
<node
pkg="me41025_74"
type="vel_filter"
name="filter_velocity"
required="true"
launch-prefix="xterm -e"
output="screen"
> ## launch vel_filter
<param name="max_ang_vel" value="0.1" />
</node>
<node
pkg="me41025_74"
type="vel_printer"
name="print_velocity"
launch-prefix="xterm -e"
output="screen"
/> ## launch vel_printer
</launch>
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);
int count_pubvel = 1;
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();
}
}
vel_filter
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Pose.h>
#include <stdlib.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);
const std::string PARAM_NAME = "~max_ang_vel";
double maxAngVel;
bool ok = ros::param::get(PARAM_NAME, maxAngVel);
if(!ok) {
ROS_FATAL_STREAM("Could not get parameter " << PARAM_NAME);
exit(1);
}
ros::Rate rate(2);
while(ros::ok()){
geometry_msgs::Twist msg;
msg.linear.x = linx; msg.angular.z = angZ;
if (angZ < maxAngVel){
ROS_INFO_STREAM("Subscriber velocities:"<<" linear="<<linx<<" angular="<<angZ);
pub.publish(msg);
}
rate.sleep();
}
}
vel_printer
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <iomanip>
void printVelocityReceived(const geometry_msgs::Twist& msg){
ROS_INFO_STREAM("Filtered velocities:"<<" linear="<<msg.linear.x<<" angular="<<msg.angular.z);
}
int main(int argc, char **argv){
ros::init(argc, argv, "print_velocity");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe("turtle1/pose",1000,&printVelocityReceived);
ros::spin();
}
答案 0 :(得分:0)
您的代码中有两个错误。
1。)您收到的错误是因为您正在收听错误的消息类型。在turtlesim documentation中,您可以看到 vel_printer 中正在侦听的主题不是您编写的 geometry_msgs :: Twist 类型,而是类型< EM> turtlesim/Pose 的。这是你的错误的原因。另外,我建议您使用ConstPtr接收消息。因此,乌龟姿势的回调函数应为:
void printVelocityReceived(const turtlesim::Pose::ConstPtr& msg){
... do your magic ...
}
2。)参数。在启动文件中,您将参数 max_ang_vel 发布到参数服务器。因为您在 标记内执行此操作,因此您将此视图设为私有。为了读取节点的私有参数,您需要指定另一个节点句柄,即私有节点句柄。然后,您可以使用node handle's functions来访问参数。
示例:
int main(int argc, char** argv)
{
ros::init(argc, argv, "test");
ros::NodeHandle nh; // public node handle
ros::NodeHandle nh_privat("~"); // private node handle
// Get the parameter.
nh_privat.param("max_ang_vel", maxAngVel, 0.0);
// first argument: name of the parameter on the parameter server
// second argument: variable to save it to
// third argument: default value if the parameter is not set
}
要从控制台更改maxAngVel,您只需使用标准C ++并将输入读入控制台,然后相应地更改变量。