Welcome to Synthiam!

The easiest way to program the most powerful robots. Use technologies by leading industry experts. ARC is a free-to-use robot programming software that makes servo automation, computer vision, autonomous navigation, and artificial intelligence easy.

Get Started
Resolved Resolved by Dave Schulpius!

Getp Command For Kangaroox2 For Use With If/Endif??

Hello everyone,

I am trying to create a simple condition using a Kangaroox2 and two motors with independent control.  I found a really great forum dialogue from a few years ago that helped me get started but I am now currently stuck and my EZB is disconnecting at the same point in the code.  I am finishing up code for a working periscope and lifter in my R2 unit.

Here is the original link...  


Thanks to help from Dave, I was able to get my setup working fairly well but there are times when the periscope is out of alignment and crashes into the dome when I try to lower it.  So, I managed to tweak the code from Dave and DJ in the article to get position values from the kangaroo but have hit a wall.   

Here's my attempted code for monitoring the position of the rotary motor so the periscope can lower without crashing.   I have notated where the code crashes and the EZB disconnects.  I believe it is related with the $Roo_position = Split ($GetP.....) command along with the following If/Endif condition.

Thank you for any help!


$Rotary_Position = 43 #Rotary Home position Kangaroo is shooting for
$GetP = "Getp" # Command to get position from Roo

uartWrite(2, 0, "2, Getp", 0x0d)


$x = UartAvailable(2, 2)
print("Bytes in buffer: " + $x)

if ($x < 4)
# Go back and wait for data again because we did not receive the least number of expected bytes

$GetP = UARTRead(2, 0, $x)
print("Received: " + $GetP)

Sleep( 1000 )

# Getting stuck below this line and EZB gets goobered and disconnects from the wifi

$Roo_position = Split($GetP, "P",1) #2,pXXXX is returned. Get everything after the P as P is case senceitive

# Send script to proper subscript depending on if position is above or below center
if($Roo_position = $Rotary_Position)

:CenterDown #If Rotary is at correct position than lifter will lower
uartWrite(2, 0, "1, P798 s600", 0x0d)
uartWrite(2, 0, "1, Powerdown", 0x0d)

:Centerup #If Rotry is in the wrong position then lifter will rise
uartWrite(2, 0, "1, P1 s600", 0x0d)
uartWrite(2, 0, "1, Powerdown", 0x0d)


Anyone have a solution?

Related Hardware EZ-B v4


Upgrade to ARC Pro

Harnessing the power of ARC Pro, your robot can be more than just a simple automated machine.

#17   — Edited
Please keep us posted on your adventure. I'm very curious to see how it works out for you. 

I'm just tossing this around in my head; my concern (like you) is getting the motor back to "Home" or a certain exact spot. We need the arm (or in your case, a periscope) to safely retracted into the body of the robot. With the Roo in "Position and Speed mode" it uses the encoder to first Home to know exactly where the motor is positioned. We then can park the appendage in the exactly position once the animation is completed. With servo control, theoretically, once set up in the proper position, we can return the servo back exactly to that spot. When we again restart the animation and the servo hasn't settled or moved, ARC will assume it knows it's position on the next start up and all will be well. The problem is "what if" the servo has moved when powered down? How do you get it back to the exact parked position before sending it out on it animation adventure? The servo will park where it started out and may not now be in alignment with the hole it needs to enter. Disaster and destruction will ensue as everything gets sucked in. One thing I tried was to install a limit switch to let ARC know the arm is centered. If not it would not retract. However then I had a arm sticking out that I needed to manually retract.   

I'm very interested in how you overcome this. I really want to start using ARC's servo commands instead of Simple Serial. So much simpler.
#18   — Edited

You hit the nail on the head.  The animation mounting system that I created is modular and allows the user to mount hardware magnetically onto a plate that is also the seat for R2’s dome.  The periscope you see is magnetically seated on the plate and can be literally pulled off for maintenance and traveling to philanthropic venues and conventions.  So this module’s motor system is absolutely going to shift during transport.  

Unless ARC can use a limit switch to reassign home servo position, I don’t know how else it can be accomplished outside of    simp serial.

Heres a link to my YouTube channel so you can see the Warp Core Base Plate I created for the Warp Core Dome System.  

The kangaroo handles the positioning - and the kangaroo also has input for limit switching. The idea of the kangaroo was to make anything a servo. They did a wonderful job at the design. So you would connect the limit switches to the kangaroo, not the ezb. And it would calibrate itself on startup to know the position.

from: https://www.dimensionengineering.com/datasheets/KangarooManual.pdf

User-inserted image
Hi D.J.,

The rotary motor has a single limit switch that I use to register the home position when sought out by the home command.  Are you saying there is a way to use servo commands to seek out and find the home switch?  For example, when I send a movement command in serial (2, p3000 s2000) to the Roo, it takes a few revolutions to get there and the Roo ignores the limit switch every time it hits it.  Yet, if I send the home command (2, Home) the rotary moves until it hits the switch and at that point Home is re-established and the p3000 is cleared as the home is now P0 no matter how many revolutions it took to get there.  

Presently, if I tune the Roo with the limit switch in servo mode, the switch will register as position 180.  This effectively limits the rotary to a single rotation.  A mechanical stop tune may be better but I would need to literally grab the periscope at certain points during the tune to establish the end points of the rotation because currently there are none.  A Teach Tune is not possible due to the gear ratios within the rotary mech.

That would be super awesome if a servo command can take the place of the serial commands.  However, the Roo does not currently calibrate at setup.  It only calibrates during the initial Tune.  Currently, I have launch commands upon connection that start the baud rate, start the motors, raise the lifter, home the rotary, all before lowering the periscope into the dome; all done in simple serial. 

Does that make sense?

Thank you,

Oh, so the rotary motor has a limit switch that you're not able to use because you want multiple rotations of the output?

If so, we'll have to not call it a limit switch. If that's the case, then yeah we can't use it at all.

So I'm not sure how the "servo mode" works with the kangaroo when using an encoder and the shaft is moved without power on. How does it recalibrate itself. I did read that it can recognize rubber stoppers because the current is monitored.
That’s a good question.  The Roo has serial commands to initialize and home which has to be done whenever the system power cycles.  There are no commands for that in servo mode, that I know of.   In any case, here’s a video I made to explain it.    The other advantage reason I need the condition is to ensure the periscope doesn’t rotate prior to being raised.   That can cause a real mess.  

#23   — Edited
First I gotta say wow. What a beautiful work of craftsmanship and engineering. 

You are working on the same problems I was when I built my B9 robot arm. If the arm retracted into the torso without being completely centered then it would hit the arm hole and stall. Thank God the Kangaroo detects the stall (or runaway) and stops. However I found damage can still happen to the structure or motors. 

The only solution I could come up with was to add a center switch that was monitored by an ADC port on the EZB. I had the main animation script wait and check that switch ADC voltage first before the arm was allowed to retract. If after sending the command to center and retract and that switch was not closed it would not retract.  

A few things I didn't like about that solution;
*One, I had to come up with a second animation script that would start up automatically (using If/Else If commands) upon failure that trys to re-center the arm and close that switch. 
*Two, there was a pause while the script checked that script. 
*Three, the animation took longer then wanted if centering failed. 
*Four, If the arm couldn't ultimately find center I had to park the arm manually with ARC movement controls. 

I wish I was in the position and had time to work on this here on my robot along with you. However I'm currently neck deep in another project I can't stop. However finding a solution to this issue or better way to command a Roo may help make my current project more elegant. I'll stay tuned. Please keep us up to date. I'll help if I can and learn from you along the way.
Thank you so much Dave!   I really appreciate the information you shared.  The Roos Getp command is specifically there for a conditional script.  Perhaps DJ can help us get the position registered to be digested by ARC.  I’ve added an extra home command to my scripts but it’s a poor substitute for an if/elseif scenario because the lowering script still assumes the rotary is in the roper position with no way to verify it.
#25   — Edited
The servo feature of the kangaroo is meant to create the protocol for ARC to integrate with. I'm not quite sure how to do it otherwise, because the ascii GetP commands don't relate to servos at all. 

Have you loaded the kangaroo software and read the manual? Let me ask questions because i think there's a lot of information in this thread that I'm missing. I'll ask more questions per each response.

1) When you power-on the robot and query GetP, what does GetP return? Is it a 0? I'm not asking about your initialization script or anything. Just when you apply power to the kangaroo, what does GetP return
#26   — Edited

If requested after initializing baud rate but before homing

if requested after initialization of baud rate and after homing

And here’s what the manual says it is....

Get position. (Getp) : Returns the channel number, followed by a comma, followed by a capital P if the move is completed or a lowercase p if the move is still going on, followed by the position in units (plain text) followed by a return and a newline
#28   — Edited
I and a friend have figured it all out!    I’ll post the code tomorrow.   We were able to isolate the data we needed and even add tolerances. We now have it successfully working.  He is also going to help me streamline a function command of sorts.
#29   — Edited
Thanks! Next questions...

2) Does "homing" use a limit switch or something? How do you know what physical position "home" is? Is that simply using the encoder or is there a switch of some sort that you use?

3) Can you send a command that moves the rotation into a specific degree? If it starts at 0, and home is 43, can you say "Go to 519"? Or do you tell it to move, keep monitoring the position yourself, and then tell it to stop?
#30   — Edited
Well, here's the solution!  This has been working great and hasn't missed a beat. *cool*

Dave, this could easily be adapted for your application!  Once we emptied the UART we could consistently cut out the data we needed from the returned Getp data.  It kept building up in the system.  Also, the "/r/n" at the end of the data (2,P43/r/n) is only considered 2 characters.

The following code reads the rotary motor position for authorization to lower the periscope.  It has a tolerance of 1 line in either direction otherwise it will raise the periscope to prevent it from crashing into R2's dome.

DJ, thank you for starting the trouble shoot. :)


$GetP = "Getp" # Command to get position from Roo
$Periscope_Home = 43 #Rotary position resulting from sent home command
$Periscope_Tol = 1 #Tolerance in either direction for proper clearance when lowered

#Rotary is channel 2
#Lifter is channel 1

UARTReadAvailable(2, 0) # Empty UART
uartWrite(2, 0, "2, Getp", 0x0d)
#Print( "A" )
#Sleep( 1000 )
$x = UartAvailable(2, 0)
#print("Bytes in buffer: " + $x)

if ($x < 7)
# Go back and wait for data again because we did not receive the least number of expected bytes

$GetP = UARTRead(2, 0, 5)
print("Received: " + $GetP)

# Spit required data from returned string while removing first and last junk characters 
$chan = Split($GetP, ",", 0)
$contents = Split($GetP, ",", 1) #Temp value
$len = Length($contents)
$Periscope_State = SubString($contents, 0, 1) #P is stopped
$Periscope_Position = SubString($contents, 1, $len-1)

print("Position: " + $Periscope_Position)
print("State: " + $Periscope_State)

Sleep( 1000 )

# Send script to proper subscript depending on if position is above or below center using ABS to negate
if (Abs($Periscope_Position - $Periscope_Home) <= $Periscope_Tol AND $Periscope_State = "P")
goto (CenterDown)
goto (Centerup)

:CenterDown #If Rotary is at correct position than lifter will lower
uartWrite(2, 0, "1, P798 s600", 0x0d)
uartWrite(2, 0, "1, Powerdown", 0x0d)

:Centerup #If Rotary is in the wrong position then lifter will rise
uartWrite(2, 0, "1, P1 s600", 0x0d)
uartWrite(2, 0, "1, Powerdown", 0x0d)
Brilliant! Nicely cleaned up compared to my script. I will defiantly edit this for my script and use it. 

Thanks for all your work and sharing this! 

Do you have any thoughts on how to proceed if the periscope does not lower because it didn't line up? Perhaps you could have the script check it the periscope successfully lowered or stopped? If not try the parking sequence again?  Of course you don't want the thing to be spinning around if it has only partially retracted into the body. 

Have fun and thanks again!!
Oh yes!  This is just the base code.   I can change the motor channel and reverse engineer it for all sorts of conditions.  I’ll be modifying it to check the lifter position prior to rotation.  For example, I can add a rotary home command and then a rotary position check prior to lowering the lifter.   The same technique can be modified to have the rotary check the lifter position prior to rotating.  This will avoid internal crashes within the dome.   

The fun is just beginning!
Outstanding. I agree, loads of fun. It's amazing how a small script like this if done right can help you throughout your whole project.Please keep us up to date on what's happening. I love this stuff.

Are you on astromech.net?   Would like to exchange emails for future collaboration if you like.  I don’t see a way on this site to send you a private message.  If you want to see some robotic hobbyists strung out on Star Wars, astromech is a free community working directly with Disney through our 501c3.  We supply the droids for a great many of their events and projects.  You are welcome to join.  I am Warpcell on the site.
Hay @dbickert, somehow I missed your last post. 

Yes I am on astromech.net but I haven't signed on for many years. I cant even remember my ID. I think it's simply "dschulpius". Lots of other stuff has captured my interests. Back then I was dreaming what my next robot build would be. Turns out the B9 robot building universe was and still is capitalizing my time and money. LOL. I'd love to one day build a full sized R2 or even a Robby the Robot from Forbidden Planet. 

It would be great to swap ideas with you ay any time. My email that I share freely is dschulpius@gmail.com. Looking forward to hooking up. 

When I get my next free moment that is not in demand I'll look you up on astromech.net.
Yes.  You are correct with your astromech ID.  I was able to find that call sign on a member search.  I'll send you an email.

Thanks again!