Thirty-five pound Monster released by XBee
My thirty-five pound Madeusa based robot went wild in my wife's spotless fine furnished living room. Damages yes, forgiveness of its operator no. Still under construction, and fine-tuning, I was adjusting down the high speed that the Madeusa - Robot base kit was capable of going when, I inadvertently unplugged the battery from the hand held propeller controller with the Joy Stick and XBee TX that communicates the direction and speed of my 35lb x 32" high robot named "The Parallaxian". Guess what, when the Xbee communication quits the current direction, and speed settings do not.
I need some help, not to get back into the living room -- that is out -- but to figure a way to stop the monster if and when the xbees fail. I have tried a few software changes without much success. Is there a way that the XBee RTS and or CTS connections can be used so that the propeller controller on the robot can take action to stop the unit upon a failure?
I use two XBee Pros, one on the handheld Joy Stick controller and one on the robot.
Transmitting XBee:
XB.Tx("!")
XB.Dec(TURN)
XB.Tx(",")
XB.Dec(SPEED)
XB.CR
Receiving XBee:
repeat
XB.RxFlush
DataIn := XB.RxDecTime (100)
If DataIn == "!"
Val1 := XB.RxDecTime (3000)
Val2 := XB.RxDecTime (3000)
WCtrl.Joystick (Val1, Val2)
Any suggestions appreciated,
Robert
I need some help, not to get back into the living room -- that is out -- but to figure a way to stop the monster if and when the xbees fail. I have tried a few software changes without much success. Is there a way that the XBee RTS and or CTS connections can be used so that the propeller controller on the robot can take action to stop the unit upon a failure?
I use two XBee Pros, one on the handheld Joy Stick controller and one on the robot.
Transmitting XBee:
XB.Tx("!")
XB.Dec(TURN)
XB.Tx(",")
XB.Dec(SPEED)
XB.CR
Receiving XBee:
repeat
XB.RxFlush
DataIn := XB.RxDecTime (100)
If DataIn == "!"
Val1 := XB.RxDecTime (3000)
Val2 := XB.RxDecTime (3000)
WCtrl.Joystick (Val1, Val2)
Any suggestions appreciated,
Robert
Comments
-Phil
Maybe a smart bumper is for you: http://forums.parallax.com/showthread.php?132260
This is "watchdog" technology. The robot needs to expect to hear reassuring words from its controller every so often (every few milliseconds or every few seconds, depending on how much damage it can cause in the meantime). If the robot doesn't hear the reassuring words within the timeout period it shuts down.
That way, it doesn't matter whether it's the controller or the communication channel that fails. The robot can tell that something has gone wrong. and it can stop until the problem is fixed.
Robert
"Shut Down" may not be the best choice, depending on the robot configuration. "Stop" or "Go Safe" (defined per robot) are often better choices. Think about "shutting down" a Medusa or other wheeled robot on an incline might not be a good deal. Shutting down a robot with something like an Arm can have negative consequences. I'd prefer not to think about "shutting down" something with an automatic paint ball gun...
You could increase the initial rx grab to ensure data should be received in that time, if no "!", but a value of -1, stop the bot.
-Martin
Thanks for all the help everyone -- I'll work on it. I'm bound and determined to make this idea work. This safety shut down is important to me -- after the bugs are worked out the ideas are going to be used on my Power Wheel Chair I need when out of the house -- the thought being that a person with the JoyStick could could walk along side and guide the power chair for those that may not be able to satisfactorily guide it themselves or for just a safety standby while out in the real world. Also, I am working on autonomous safety sensors for obstacles, stair wells, etc..
====================
Transmitting XBee:
XB.Tx("!")
XB.Dec(TURN)
XB.Tx(",")
XB.Dec(SPEED)
XB.CR
Receiving XBee:
repeat
XB.RxFlush
DataIn := XB.RxDecTime (100)
If DataIn == "!"
Val1 := XB.RxDecTime (3000)
Val2 := XB.RxDecTime (3000)
WCtrl.Joystick (Val1, Val2)
====================
Robert
Ok, let's try for a "little thought"
I'm making a few assumptions here, but as I see it there are many possible points of failure:
1. Software error in the joystick controller causing loss of transmission.
2. Battery failure in the controller (your original problem...)
3. Hardware failure causing loss of transmission
4. Loss of transmission due to interference or to the remote going out of range of the controller
5. Software error in the remote
6. etc etc
A robust system is going to have to deal with all of these. As I see it, there needs to be a piece of hardware on the remote that will have an input pin that's normally at (say) logic high and that will force the remote into whatever you define as a safe state if that pin ever goes low. No, let's amend that. Better if the hardware expects to see a pulse train and will take action if the pulses stop, whichever state the line remains stuck in.
To check the whole communication chain, the pin can be driven from the processor in the remote, which toggles the pin each time a particular command sequence is received from the joystick controller. The software in the joystick controller is then programmed to transmit the command sequence at regular intervals.
This way, the pulses will stop and the remote will fail safe when any component in the chain fails.
Well, that's my thought for the day anyway :-)
Receive:
repeat
XB.RxFlush
DataIn := XB.RxTime (100) ' Wait for byte with timeout
If DataIn == "!" ' Check if delimiter
Val1 := XB.RxDecTime (3000) ' Wait for 1st decimal value with timeout
Val2 := XB.RxDecTime (3000) ' Wait for next decimal value with timeout
WCtrl.Joystick(Val1, Val2) ' -100% to +100% Speed, -100% to +100% Turn
else
Val1 := (0) ' Turn Motors off
Val2 := (0) ' Turn Motors off
WCtrl.Joystick(Val1, Val2) ' -100% to +100% Speed, -100% to +100% Turn
Transmit:
XB.Tx("!") ' Delimiter
XB.Dec(CH1) ' First value
XB.Tx(",") ' Comma seperator
XB.Dec(CH0) ' Second value
XB.CR
Robert
Sylvie,
Did your robot test work?
Good?
Bad?
Robert
Martin, I'm not sure what you are referring too by "initial rx grab". Even though I believe I have the robot working properly I am interested in your suggestion which appears to be faster and more reliable. I'm not sure yet what happens when I happen to receive a delimiter of "," instead of "!". I am going to set up the program in Viewport and maybe duplicate the scenario.
Robert
RxDecTime returns a -1 if no data received in time.
You could increase the initial rx grab to ensure data should be received in that time, if no "!", but a value of -1, stop the bot.
Martin, let me do some testing -- after review I believe I know what your refering too. I will work on that and give it a try.
Here's the pro's and cons - the way this is done:
If you do an RxFlush in your loop, there's a chance you could be flushing as data is arriving. This would wipe out the start delimiter, and your code would shut your bot down until the next time data arrives.
With out the RxFlush, you may get out of synch, and if the first character you read is not "!" then it will cycle through the rest until if finally hits the "!" or no more data and it has to wait for the next incoming data.
Using a short timeout on that (100mS), if data doesn't get received every 100mS, it will see no data and shutdown the bot until the next packet finally arrives. I don't know how quickly you are sending data, but that time may need to be extended.
Another means to help ensure you receive good, synched data is instead of flushing, to loop while data is in the buffer, looking for the "!" to ensure things are synched:
(may be rusty on my spin, but you can get my meaning)
DataIn = XB.RxTime(100)
If DataIn <> "!"
...Repeat
.....DataIn := XB.Rx
...While (DataIn <> "!" AND DataIn <> -1)
-Martin