Looking at your code, I can see the following:
-
You are trying to put your LaserScan message into
lsvalue
, but it seems it’s not being done rightly. But…you don’t even need to do that! In yourlaser_callback
, just print the messages you are printing inmain()
by accessingmsg
directly. -
Your are missing
ros::spin()
inmain()
, so your subscriber is not working properly (spinOnce()
is not enough for this case, as you need to keep subscribing to the laser scan. See the difference betweenspin()
andspinOnce()
in the post below:
What is rospy.spin(), ros::spin(), ros::spinOnce(), and what are they for? -
Don’t stop the robot in
main()
, like you’re doing here:
vel.linear.x=0;
pub.publish(vel);
-
You don’t need the
Rate
object here:
Proper use of rospy.Rate or ros::Rate -
You don’t need to do any publishing in the
main
function - do them in thelaser_callback
, based on the sensor reading. If you must do any publication inmain()
, let it be the initial one and then do the rest in the callback. Your main should be something like:
int main(int argc,char** argv){
ros::init(argc, argv, “topics_quiz_node”);
ros::NodeHandle nh;
pub=nh.advertise<geometry_msgs::Twist>("/cmd_vel", 1000);
sub=nh.subscribe("/kobuki/laser/scan",1000, laser_callback);
// Do just the initial publication here; do the rest in the callback
// Not really necessary though
for(int i=0; i<5;i++){
vel.linear.x=0.2;
pub.publish(vel);
}
// This is necessary for the LaserScan message to keep arriving
// and for the program to keep running
ros::spin();
}
Your laser_callback()
could be something like:
void laser_callback(const sensor_msgs::LaserScan::ConstPtr& msg){
// print your ranges array for debugging.
// the middle values represent the front-center of the robot
// the first and last represent the extreme sides
if (/*robot is not too close for comfort*/) {
vel.linear.x = 0.2; // move forward
vel.anguar.z = 0; // no turning for now
}
else {
vel.angular.z = -0.2 // or 0.2, turn
vel.angular.x = 0; // no forward movement for now
}
pub.publish(vel);
}