Asked
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...

https://synthiam.com/Community/Questions/Help-Using-A-Returned-Position-Value-From-Kangaroo-In-Ez-script-4618

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!

Douglas


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

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

:waitForData

$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

goto(waitForData) endif

$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) goto(CenterDown) ELSE goto(Centerup) endif

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

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


Anyone have a solution?


Related Hardware EZ-B v4

ARC Pro

Upgrade to ARC Pro

Become a Synthiam ARC Pro subscriber to unleash the power of easy and powerful robot programming

PRO
Synthiam
#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

Cool!

2,E1\r\n       If requested after initializing baud rate but before homing

2,P43\r\n     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.

PRO
Synthiam
#29   — Edited

Thanks! Next questions...

  1. 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?

  2. 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 )
#print("B")
:waitForData
$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
  goto(waitForData)
endif

$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)
ELSE
  goto (Centerup)
endif

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

:Centerup #If Rotary is in the wrong position then lifter will rise
print("Centerup") 
uartWrite(2, 0, "1, P1 s600", 0x0d)
Sleep(4000)
uartWrite(2, 0, "1, Powerdown", 0x0d)
Halt()
#31  

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!!

#32  

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!