Add Cliff Sensors to Turtlebot 3 (Waffle Pi ish)

As I have mentioned in a few postings, both here as well as Robotis Forum and Trossen Forum, before I let my turtlebot 3 roam, I want to make sure it does not fall down the stairs. So I have been playing around with distance sensors as well as the OpenCR board. Also from these conversations, I know that Robotis is working on adding support for cliff sensors, which is great. However as a learning exercise, I have been experimenting with some different solutions.

However with projects like this, I often get distracted, and keep trying out different things, which can both be good or bad.

My first approach has been to use some VL6180 sensors connected up to I2C. I tried first with just one sensor, and I modified the Arduino code base to read this sensor, and publish a new topic, which I had working. I discussed this in the thread:

Currently I am experimenting with maybe using up to 4 of these. One near the front of the two wheels, plus one probably centered near front and maybe fourth centered near rear, in case you decide to backup from danger only to fall of behind you… As I mentioned up on Trossen, I have a simple Arduino App, that allows me to have the OpenCR board read three (easy to add 4th). Again more details up in the thread:

Note: There is an Arduino created ZIP file with test app, including my version of VL6180 library code, that allows me to do reads Asynch…

But, I am now trying to decide if I want to mount these sensors, or go with Analog sensors as it has been mentioned that the up coming Cliff sensors will be probably IR and using Analog… So to prepare for this, I have purchased, 4 each of:

Your DMS-80 sensors - Issue here is I think these will have to be mounted probably higher than top deck. Not sure yet how to mount, I have now 3d printed a 3x5 12mm like plate, which I think I can use Rivets to attach.

Your IR Sensor IRSS-10 sensors - Look like they work OK for this. Not sure what to use to mount these. Hopefully some simple thing to 3d print.

Sharp GP2Y0A51SK0F Analog Distance Sensor 2-15cm from Pololu - May have issue that these want input voltage of 4.5-5.5v. Will see how well they work at 3.3v. Could probably make cables to run 5v to them, but then analog would be out of range… Also would need to setup 3d printout for them.

I should have all of these sensors within the next week. So lots to experiment with.

Once I settle on one (or more of these), next up will be again to do integration into Arduino sketch and ROS.

Things like:
a) Should I/we create a new topic or topics where the user can get RAW data from these sensors, and/or integrate into Sensors message.

b) Assume use data to fill in cliff value in the sensors messages.

c) Parameters for this. Do I hard code limits into Arduino code? Or should I use ROS Parameters. If Ros Parameters what to do when ROS is not running? Use defaults? Or maybe some how when we get a new ROS parameter we store it in EEPROM to read as default? …

d) Who processes the data? Should the Arduino code base sometimes subscribe to the generated data and if you are driving the Turtle without ROS, maybe Stop and/or make Noise… But by default I am assuming that there will be some ROS node/nodes who will process the generated topic data and do simple things like stop forward motion if it finds a cliff…

Again I am using this as a learning exercise, so who knows where it will end up. All suggestions are welcome, including maybe best to wait until you are done. But hopefully maybe some of the things I learn along the way might be useful.

And the main point is, I am having fun!

Edit: Thought I would show a prototype 3d printed bracket to hold the VL6180 sensor. Hopefully setup to use your standard rivets as shown. I am printing a new one naw that has a slightly larger gap from where the 6mm mounting holes are to where the sensor mounts (it was a little tight)

Also it will use 2nd of the two part rivets, Currently waiting for shipment, which hopefully has the right ones.

My shipments arrived Friday :D, And looks like I may need to do another order,but…

I have doing some experimenting with a few of the different sensors, and will probably start off using either the Robotis IR Sensor:

Or the Sharp short range IR sensor:

I have 4 of each of these. I may want to purchase the longer cables for the IR sensor

I may also wish to pick up a few of the touch sensors…

Now the question is how best to integrate this?

I see that there is a lot of nice additions to the new Turtlebot 3 software. Like the ability to add a few sensors.

But I am wanting to maybe add a different set of sensors than this release is setup for and am thinking maybe I would like to make some of it a little more generic and maybe closer to some of the stuff that the Turtlebot 2 has.

In particular, if we look at the Kobuki messages: kobuki_msgs - ROS Wiki

There Sensor state message, has a cliff field were there are three bits defined for (left, right, center) for any of the cliffs that are triggered.

If you want additional information on the Cliff events, they have a separate message that get sent when you first sense a cliff and when you are no-longer at a cliff. It has additional information, like how far down it sensed…

They have a specific message for Cliff messages:

So what I would like to be able to do, is have my config file, specify which devices I have and maybe on which pins. Also not sure if I want to limit these to only the OLLO pins as we have only 4, and I may wish to have:

3 or 4 Cliff sensors and 2 bumpers… May also want Bumper Even message?

Well now to continue playing :smiley: Just ordered a few more things!

Mostly notes to self:

So far, I have done the following:
a) Disabled the creating/initializing of the Cliff and Bumper objects in the library code, as they are fixed to only one Cliff and fixed on how they are connected.
b) Created my own Cliff objects, currently look like:

class Turtlebot3CliffSensor 
	Turtlebot3CliffSensor(int pin, uint8_t mask, uint16_t boundary): 
			_pin(pin), _mask(mask), _boundary(boundary) {};
	~Turtlebot3CliffSensor() {};
	void 	init();
	bool	update(turtlebot3_msgs::SensorState &sensor_state_msg);
	int 		_pin;
	uint8_t		_mask;
	uint16_t	_boundary;
	OLLO 		_ollo;		// Probably won't use later.

I have the sketches config file with definitions for them

// Define sensors we are using - Pass 1 not Ros Parameters
#define CLIFF_RIGHT_TRIGGER				800			// Need to experiment - 
#define CLIFF_RIGHT_PIN					-1			// DEFINE as OLLO connector 1
#define CLIFF_FRONT_TRIGGER				800			// Need to experiment - 
#define CLIFF_FRONT_PIN					-2			// OLLO 2
#define CLIFF_LEFT_TRIGGER				800			// Need to experiment - 
#define CLIFF_LEFT_PIN					-3			// OLLO 3
#define CLIFF_REAR_TRIGGER				800			// Need to experiment - 
#define CLIFF_REAR_PIN					-4			// Ollo 4  
//#define BUMPER_FRONT					

I then create and do stuff with the ones that are defined like:

Turtlebot3CliffSensor cliff_right(CLIFF_RIGHT_PIN, 0x1, CLIFF_RIGHT_TRIGGER);
Turtlebot3CliffSensor cliff_front(CLIFF_FRONT_PIN, 0x2, CLIFF_FRONT_TRIGGER);
Turtlebot3CliffSensor cliff_left(CLIFF_LEFT_PIN, 0x4, CLIFF_LEFT_TRIGGER);
Turtlebot3CliffSensor cliff_rear(CLIFF_REAR_PIN, 0x8, CLIFF_REAR_TRIGGER);

Likewise for the init() and update() calls. In the Update, I have not changed the Sensor message, although I only output uint8_t data, which gets mapped currently into the float variables… I may change it back in the actual message

c) Will introduce the CliffEvent message like the Kobuki has that gets triggered only when we reach cliff and leave cliff. Mine is slightly modified from theirs… But only on the constants…

# Provides a cliff sensor event.
# This event has the same format as the one for the Kobuki Turtlebot 2 message.
# This message is generated whenever a particular cliff sensor signals that the
# robot approaches or moves away from a cliff.
# Note that, despite cliff field on SensorState messages, state field is not a
# bitmask, but the new state of a single sensor.

# cliff sensor - changed to have same value as bitmask added optional REAR sensor
uint8 LEFT   = 1
uint8 CENTER = 2
uint8 RIGHT  = 4
uint8 REAR   = 8

# cliff sensor state
uint8 FLOOR = 0
uint8 CLIFF = 1

uint8 sensor
uint8 state

# distance to floor when cliff was detected
uint16 bottom

I was able to have ROS build the header file, by downloading this msg file as well as update the CmakeLists.txt file

d) But need an Arduino version of this header file… Started hand editing one, then though ROS should be able to do this for me… So on UP board: I did:

sudo apt-get install ros-kinetic-rosserial-client
rm -r ~/sketchbook/libraries/ros_lib
rosrun rosserial_client make_libraries ~/sketchbook/libraries

Which created all of the header files in the ros_lib folder, so I could copy those back up to my main dev machine, which then updated the header files in my fork/branch of the OpenCR project.

Next things to do:
a) Have my new class either automatically publish the new message or have the caller do it.

b) Test out the hardware and software to see that I am generating the proper updated Sensor Message plus the new Cliff messages. Will do same for Bumper Sensor as well

c) Introduce something like the kobuki_safety_controller. Which when it senses that one of the cliff sensors has been triggered, it either stops the turtle or maybe try to in different direction… Not sure if it should be a NODE or a Nodelet?

d) Setup launch files where I can then hopefully try it out to maybe map part of my house, without falling down stairs and run into too many things.

Again mostly notes for self… Will push up new branches of OpenCR, Turtlebot3 and Turtlebot3_msgs with these changes.

1 Like

Hi…as per my knowledge, it’s true, the code only outputs a trace. The problem is I don’t see the trace when I run the program (and the turtlebot collides with something), so I have to conclude that the processBump() function is not being called.

rapid smt assembly

Sorry, I have not played around with this for awhile. Currently off doing some other stuff.

Some of the later stuff was on the UP board, that I fried and I have not yet gone back to figuring out what was lost.

If I remember correctly I was running into issues where there was some support added into Turtlebot3 for some sensors, but it was very specific, to one configuration of sensors. I was(am at some point) going to pick this up again and make it work. But it might be awhile from now. (Currently spending my free time on PJRC Teensy 4 beta stuff)