ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

rosserial Publish and Subscribe to Ultrasonic Ping Range Data?

asked 2019-01-10 02:32:33 -0500

geistmate gravatar image

Hi, I am very new to ROS and I have a few questions as I am trying to learn it all on my own. I've read the tutorials but there are still some things I need some clarification on.

I want to publish ultrasonic sensor data as a range message to a topic. And then I want the same arduino to subscribe to that topic, and use that data to turn the servo motor depending on the distance read from the ultrasonic sensor. This is the code that I have come up inspired ny the rosserial tutorials.

I am coming to the error on arduino ide that states:

" 'const class sensor_msgs::Range' has no member named 'data'. " I am not sure which type of member it should be. Also, if I have any other noticeable errors that did not appear on verification, kindly let me know as I am doing my best to learn ROS. Thank you very much. Best, Matthew.

#if (ARDUINO >= 100)
 #include <Arduino.h>
#else
 #include <WProgram.h>
#endif

#include <Servo.h>
#include <ros.h>
#include <ros/time.h>
#include <sensor_msgs/Range.h>

Servo servo;
ros::NodeHandle  nh;

sensor_msgs::Range range_msg;

long duration;
int distance;

void servo_cb( const sensor_msgs::Range& range_msg){
  distance = range_msg.data; 

  if (distance < 30) {
    servo.write(0);
  }
  else {
    servo.write(90);
  }
}

ros::Publisher pub_range1("/ultrasound1", &range_msg);
ros::Subscriber<sensor_msgs::Range> sub_range("/ultrasound1", servo_cb);

char frameid[] = "/ultrasound";

void setup()
{
  nh.initNode();
  nh.advertise(pub_range1);
}



long range_time;

void loop()
{
  //publish the adc value every 50 milliseconds
  //since it takes that long for the sensor to stabilize
  if ( millis() >= range_time ){
    range_msg.range = getRange_Ultrasound(14);
    pub_range1.publish(&range_msg);

    range_time =  millis() + 1000;
  }

  nh.spinOnce();
}

float getRange_Ultrasound(int pin_num)
{
  pinMode(pin_num, OUTPUT);
  digitalWrite(pin_num, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_num, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_num, LOW);

  pinMode(pin_num, INPUT);
  duration = pulseIn(pin_num, HIGH);

  return duration/58;
}
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-01-10 02:50:55 -0500

gvdhoorn gravatar image

updated 2019-01-10 03:23:24 -0500

You publish the data as:

void loop()
{
  [..]
  if ( millis() >= range_time ){
    range_msg.range = getRange_Ultrasound(14);
    pub_range1.publish(&range_msg);
    [..]
}

and then you subscribe and try to access it with:

void servo_cb( const sensor_msgs::Range& range_msg){
  distance = range_msg.data; 
  [..]
}

If the former works, then it would seem the field is called range, not data.

Looking at the documentation of sensor_msgs/Range (via wiki/sensor_msgs), we see that is indeed the case:

float32 range           # range data [m]
                        # (Note: values < range_min or > range_max
                        # should be discarded)
                        # Fixed distance rangers only output -Inf or +Inf.
                        # -Inf represents a detection within fixed distance.
                        # (Detection too close to the sensor to quantify)
                        # +Inf represents no detection within the fixed distance.
                        # (Object out of range)

Edit: slightly off-topic, but:

I want to publish ultrasonic sensor data as a range message to a topic. And then I want the same arduino to subscribe to that topic [..]

while this should certainly work, I would perhaps not implement something like this as it would incur quite some latency between publishing the Range message and your subscriber receiving it. Although I'm not intimately familiar with rosserial implementation details, I don't believe it has an optimisation in place where it keeps msgs destined for local subscribers (ie: on-same-device) local instead of serialising them and sending them across the wire. It would probably be good to verify that (or accept the additional latency, if that is ok for your application, of course).

edit flag offensive delete link more

Comments

Hi, thank you for your quick reply. It seems that my IDE properly compiles without any error now. Now, the problem is subscriber My publisher works as I can see its data with rostopic echo, but with rostopic list -v I do not see my subscriber subscribing to the published \ultrasound1.

geistmate gravatar image geistmate  ( 2019-01-10 03:08:32 -0500 )edit

Sorry for double comment if this is not allowed or is frowned upon on ros answers community. But, I have figured out the problem and I simply did not add nh.subscribe(sub_range); in my void_setup. Thank you very much for your kind help today.

geistmate gravatar image geistmate  ( 2019-01-10 03:16:05 -0500 )edit

No need to apologise: you may post as many comments as you'd like. They're free.

We do however ask you to not post follow-up questions under answers to your initial question (as you did with "I don't receive any msgs now that the compiler error is fixed"). It's not that we don't want to help ..

gvdhoorn gravatar image gvdhoorn  ( 2019-01-10 03:19:34 -0500 )edit

.. you, but questions like that in comments (and the responses to those follow-up questions) have very low visibility, which doesn't help future visitors to find the answers to their questions.

It's best to first accept the answer to your original question, and then post a new one.

gvdhoorn gravatar image gvdhoorn  ( 2019-01-10 03:20:24 -0500 )edit
1

Surely will keep that in mind. I hope to continue to grow in this community as well as help it expand in any way possible. :)

geistmate gravatar image geistmate  ( 2019-01-10 03:22:08 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2019-01-10 02:32:33 -0500

Seen: 1,118 times

Last updated: Jan 10 '19