Reputation: 23
I'm working on an assignment on the turtlesim tutorials from ROS.
The launch file ex74.launch
launches 4 nodes:
-the turtlesim node (animates the movement of the turtle)
- pubvel (publishes random angular and linear velocity commands)
- vel_filter (subscribes to the topic on which pubvel publishes. This node filters the angular velocities and publishes only the messages with an angular velocity smaller than the parameter max_ang_vel)
- vel_printer (prints the filtered velocities)
The scripts and the launch file are given at the end of my question.
The goal is now to set an initial value for max_ang_vel
and change it from the command line.
However, when I run the launch file, i get the following error:
Also all angular and linear velocities from vel_filter
and vel_printer
are 0.
Can anyone help me to solve this?
Thanks in advance!
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();
}
Upvotes: 1
Views: 3131
Reputation: 1042
You have two errors in your code.
1.) The error you are getting is there because you are listening to the wrong message type. In the turtlesim documentation you can see that the topic you are listening to in the vel_printer is not of type geometry_msgs::Twist as you wrote, but of type turtlesim/Pose. This is the reason for your error. Also I suggest you use ConstPtr for receiving messages. Your callback function for the turtle pose should therefore be:
void printVelocityReceived(const turtlesim::Pose::ConstPtr& msg){
... do your magic ...
}
2.) The parameters. In the launch file you are publishing the parameter max_ang_vel to the parameter server. Because you are doing this inside the tags you are therefore making it private for this node. In order to read the private parameters of a node you need to specify another node handle, a private one. Then you can use node handle's functions to access the parameter.
Example of this:
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
}
And for changing the maxAngVel from the console, you can just use standard C++ and read the input into the console and then change the variable accordingly.
Upvotes: 0