Basically the sensor just expect a high pulse for five microseconds as it's cue to take a measurement and the way it conveys that measurement back to you is: it's an ultrasonic sensor of course it's sonar, it emits high frequency noise and then listens for that noise's echo so what happens when you ask for a reading, is it begins to hold the signal pin high the same pin you sent it in, so this is a bi-directional pin, it holds that pin high when it's emitting the sound and then it drops that pin low when it hears the echo of that sound so in other words: that pulse width is the signal that it's sending out so, it's fairly straight-forward so with that understanding let's go ahead and come up with a quick Wiring sketch so I've pulled up the Wiring environment and we'll start out by just having your basic setup and loop handlers obviously, this is gonna need some way to talk back to the main machine and also ROS, so we'll use a serial begin environment now, even at ninety-six hundred baud this is going to be able to totally come up with a ridiculous number of samples for what we're going to be eventually doing to control a web page so let's go ahead and add a delay to this loop so that it will run at a more reasonable speed forty-two milliseconds is roughly equivalent to twenty-four hertz now, of course, the unit will actually run much slower than that because these measurements actually take time they are after all, based on measuring the speed of sound so let's go ahead and assume that when we've entered this loop that our pin is low so the thing we're gonna need to do is go ahead and do that five microsecond pulse of high to ask for a reading so let's do a pin mode on twelve and get that started so there we have the five microsecond pulse of a pin high followed immediately by a pin low and then we need to get ready to go ahead and read in the incoming pulse width now pulseIn is a built-in Arduino function that will measure pulse width and it outputs an unsigned long, so that's what we'll go ahead and create a variable for, and it also needs to be told what kind of pulse to look for, so in this case, it's going to be a high pulse and then once that's done we'll just go back into the low state, which was our assumption when we began the loop and that is pretty much reading from the sensor about every twenty-fourth of a second and right now, we're not doing any reporting back so it's worth talking about at this point if we were going to use ROS serial we'd begin refactoring this code to contact ROS and we could do the equivalent with rosbridge, we could have we could refactor this code so that it's a full rosbridge client so in other words: we could put the handshake in the setup, and we could then send the JSON messages right from here but the rosbridge approach is much more to push everything into the plumbing and try to have the applications be as ROS-agnostic as possible so instead of that, I'm just gonna have this sketch report the microseconds back as characters right on the serial line and we'll see what implications this has in the next step so let's go ahead and verify this code make sure it compiles alright so, we're done.
let's go ahead and upload that to our Arduino board now I'm using an Arduino Uno which you can also get from Radio-Shack but any Arduino should work with this particular sketch and it's on the board and should be reporting back to us so now that we have it uploaded to the Arduino board and running and communicating back to this machine we need to get the data that it's outputting actually into ROS so, let's start off by making ourselves a little place to work and then we'll start up a a copy of roscore now I like to run rosbridge at a slightly lower sampling rate than is the default just because I like it to use up as little CPU as possible, so let's go ahead and set it's sampling rate to say: two hundred, which considering that the signal we're interested in is twenty-four hertz at the fastest is more than enough and with that done, we're free to start a rosbridge quietly in the background now I mentioned that if that we could have in our sketch implemented a full rosbridge client and had we done that, the advantage to that would have been that now all we'd need to do is connect the serial port to the TCP/IP port that rosbridge is running on.
And we could even use a simple utility we could put in a launch file like, socat for that. It would look something like this and that would really be all there is to it, because the full rosbridge protocol is just ASCII so the serial port's perfectly capable of it and it's both ways and there are advantages to that if you start to do more and more complicated things. When you start to subscribe to more than, say, two things what we're about to do may become a little unfeasible or at least not as elegant but what we're gonna do instead of that since we didn't do a full rosbridge protocol implementation on the sketch we're just going to use the same approach of using socat but put it through a filter so that the data coming off of the Arduino is in the appropriate rosbridge format so we'll get started by starting off with the socat command for that so you can see that we're still of course using the ignore eof option on the serial terminal this is the serial term my Arduino happens to be on and we're piping this through sed now the dash 'U is very important because if sed is not run in unbuffered mode it's not going to be a stream processor since it's in the middle of a pipeline, that's what we want and if we don't do that we'll get starts and stops in our input so now you might be asking: but wait a minute, there's a handshake in the rosbridge protocol how are we going to have that and just this sed transform well a little trick we're going to use is we're just going to ignore the first measurement we get, we're gonna transform that first measurement into the handshake and then we're going to transform all the remaining measurements into the proper JSON/rosbridge format so let's go ahead and do that first measurement and convert it into the handshake and if that syntax is foreign to you, just take a look at our other screencast so basically this is just a request on for rosbridge for a raw socket now we need to actually transform each of the individual incoming data packets, which is just gonna be ASCII number characters so that's easily done now we need to go ahead and pick a topic so why not slash echoTime now, as far as the type is concerned I mentioned that the pulseIn returns an unsigned long there's no unsigned things inside ROS, at least in the standard messages so we're gonna need to use a sixty-four bit interger to hold this so that's gonna be standard messages int sixty-four and that kind of datatype just has a simple data field that contains the value now we're gonna pipe this into netcat obviously eventually, but let's just go ahead and do a sanity check cause obviously this is sort of a complicated regex so we'll just hit enter and you see why the eof ignore option is important.
You see that studder there? That was because the Arduino was coming on-line, and so if you don't have that ignore eof you're gonna get a dropout from this technique look's like we're getting some reasonable data, coming in looks like it's formatted correctly so let's go ahead and pipe that into rosbridge via netcat and we can verify that that's working by looking at the rostopic list and we see that echoTime is indeed there so, let's see if the frame rate or the sample rate is reasonable and we're getting a solid sixteen hertz which is about what's expected because right now of course I'm not near the sensor so it's going out the full three meters that the sensor can read which in computational time is quite alot of time that that sound is traveling out and then never coming back alright, so we have a working rosbridge in other words: the Arduino is talking to ROS just fine so now we just need to do the final part of the project, which is come up with a HTML page that can make use of ros.
But here we're just gonna use no framework so that we can show bare bones using ros.js so we have the handler for onload registered and ready and the first thing it obviously needs to do is connect to rosbridge now here that's a localhost connection to ninety ninety because I don't want to even involve a web-server I'm just gonna open this page directly obviously this could be a remote rosbridge as long as your routing was correct you could pipe this through SSH what-have-you. Here it's local there's no loss of generality for doing this remotely so we have our ROS connection what we need to do is register a handler for when that connection is successful which is done with setOnOpen and that handler's gonna have two important jobs. It's going to register a handler for echoTime remember? The data we're actually interested in and then it's gonna subscribe to that so that that handler actually gets used so we'll start off with just defining a quick handler on echoTime and then we're gonna subscribe to echoTime which is done through the ros.