An o-pi Pioneer sensor library
Bindings for a fair bit of a vanilla Pioneer3
The Pioneer3 has a number of sensors available; while Player/Stage provides a way to access them directly, we have wrapped t hem up, as well as provided a number of processes to manage the data flowing out from those sensors. In particular, we've tried to provide some common, useful functions you might want to perform on the different sensors available.
The LMS200 (or SICK, as we like to call it) laser rangefinder has a range of 8 meters; in the library, we've converted this to an integer value from 0 to 800cm (therefore, limiting the resolution of the laser to 1cm). We've tried to anticipate a few w ays you might want to use this data. Note that the laser data is indexed from 0 (leftmost) to 180 (rightmost).
laser.min(CHAN LASER in?, CHAN INT out!)Returns the minimum value in the entire laser sweep.
laser.max(CHAN LASER in?, CHAN INT out!)Returns the maximum value in the entire laser sweep.
laser.average(CHAN LASER in?, CHAN INT out!)Returns the average value in the entire laser sweep, rounded to the nearest cm.
laser.*.slice(CHAN LASER in?, CHAN INT out!, INT start, length)The min, max, and average functions are all available in a "sliced" version as well.
start indicates an index into the LASER array (0-181) where the slice will begin; the length is the n
umber of elements to include from that point forward, modulo the length of the array. This means that
laser.min.slice(in?, out!, 120, 120)
Will provide the minimum value in the leftmost and rightmost 60 degrees of the laser:
laser.delta(CHAN LASER in?, out1!, out2!)A delta splits one stream of data into two. Handy for building process networks.
laser.black.hole(CHAN LASER in?)Consumes data. Nothing comes out. Ever.
The Pioneer has a number of ultrasonic rangefinders arrayed around the chassis. There are six in the front and back, and two on each of the sides. We have provided accessors for each of these sides. They have a range of 5m, which we scale to a value f rom 0 to 500, meaning we force them to a maximum resolution of 1cm. They are far less precise than the LMS200, although tend to behave perfectly in our virtual machine.
As the sonar functions all mirror the laser functions, we will not describe them in detail. Valid constants for side include sonar.front (0), sonar.left (2), sonar.right (3), and sonar.back
(1).
sonar.min(CHAN SONAR in?, VAL INT side, CHAN INT out!)sonar.max(CHAN SONAR in?, VAL INT side, CHAN INT out!)sonar.average(CHAN SONAR in?, VAL INT side, CHAN INT out!)sonar.delta(CHAN SONAR in?, out1!, out2!)sonar.black.hole(CHAN SONAR in?)If you wish to access the sonars individually, you can write code like:
INT the.value: SONAR array: SEQ in ? array the.value := array[3]
Assuming you had an incoming channel of type SONAR called in, this would read the rangefinder data into a variable called array, and then assign the value of the third ultrasound rangefinder to the variable the.value.
sleep(VAL INT amount)Sleeps for the indicated number of nanoseconds. We have also provided the constants one.ms, one.tenth</co
de>, and <code>one.sec. Therefore, a typical call might look like:
sleep(5 * one.tenth)
to sleep for half of a second. This blocks the process making the call. When running on the RoboDeb VM, be aware that time i s a very funny thing. We have not explored this fully, but there is definitely some funny schtuffs going on with the VM's clock .
How to use the blobfinder (once we implement it), the power sensor (ibid), and anything else we can provide a sane wrapper f or.