United Kingdom
Asked — Edited

Controlling A Kangaroo With The V4

For Dave and Richard and anyone else who is interested, here is fully working and tested code for using the Kangaroo (with bi-directional comms) via the UART on the V4 with encoder feedback.

I am still quite new with EZ scripting so the code may not be as elegant as I would like, I could not find an ASCII to decimal function in ARC so I had to write a block of code to do this DJ maybe I am missing something here?

Anyway I think this does show how fantastic and versatile the V4 is, well done DJ and team!

Tony


# -------------------------------------------------
# Name    : V4_Roo_serial
# Author  : Tony Ellis
# Date    : 01/07/2014
# Version : 1.0
# -------------------------------------------------

definearray($byte,10)
$wheel_turn=63890
$dly=50
$FLAG=0
uartinit(0,0,19200)          # initalise UART

# ***** Initalise Kangaroo
uartwrite(0,0,"D,start",13)  # drive channel start
uartwrite(0,0,"T,start",13)  # turn channel start
uartwrite(0,0,"T,p0",13)     # this is also needed at start

#goto(START)

$val=2*$wheel_turn   # load position
$COMM_CHR="DF3"      # D=drive channel - F=move forward - 3=speed 3
goto(INC_POS)
halt()

:START

$val=$wheel_turn-500
$position=0
$unit=round($val/8)
$str="4000"
$x=1
goto(RAMP)
$str="7000"
$x=2
goto(RAMP)
$str="10000"
$x=3
goto(RAMP)
$str="7500"
$x=6
goto(RAMP)
$str="5500"
$x=7
goto(RAMP)
$str="2500"
$x=8
goto(RAMP)
uartwrite(0,0,"D,s0",13)
halt()


:RAMP
uartwrite(0,0,"D,s"+$str,13)
$v=$unit*$x
REPEATUNTIL($position>$v)
  goto(GET_POS)
ENDREPEATUNTIL 
print("position="+$position)
print("speed="+$str)
return

# -------------------------------------------------
# Subroutines

# ***** POSITION commands *****

:INC_POS                           # increment position subroutine
$str=tostring($val)                # convert variable to string
$COMM="pi"                         # determine direction
IF (getcharat($COMM_CHR,1)="R")
  $COMM="pi-"
ENDIF 
goto(SEND_DATA)
goto(GET_POS)
REPEATUNTIL($FLAG=1)
  goto(GET_POS)
ENDREPEATUNTIL 
print("POSITION = "+$position)
return

:GET_POS                           # get current position subroutine
uartwrite(0,0,"D,getp",13)
sleep($dly)
goto(GET_DATA)
print($position)
return

# -------------------------------------------------
:SEND_DATA
$M_SPEED=(getbyteat($COMM_CHR,2)-48)*1200
$string=(getcharat($COMM_CHR,0)+","+$COMM+$str+"s"+$M_SPEED) # build data packet
uartwrite(0,0,$string,13)                                    # send packet
sleep($dly)                                                  # delay required
return

# -------------------------------------------------
:GET_DATA
$num_bytes=uartavailable(0,0)

$data=uartread(0,0,$num_bytes)

$byte1=getbyteat($data,0)    # byte 1 = command
$byte2=getbyteat($data,1)    # byte 2 = ","
$byte3=getbyteat($data,2)    # byte 3 = command completed status

# ***** Convert ASCII digits to decimal number
$total=0
$multiplier=1
$x=$num_bytes-2
REPEATUNTIL($x=3)#$num_bytes-7)
  $byte[$x]=getbyteat($data,($x-1))
  $byte[$x]=($byte[$x]-48)*$multiplier
  $total=$total+$byte[$x]
  $multiplier=$multiplier*10
  $x--
ENDREPEATUNTIL 
  
  # ***** Determine byte 3
  # $FLAG=0
IF ($byte3=80)
  $FLAG=1      # "P" returned so move completed
ELSEIF ($byte3=112)
  $FLAG=2      # lowercase "p" so move not completed
ELSEIF ($byte3=83)
  $FLAG=3      # "S" returned so speed reached
ELSEIF ($byte3=115)
  $FLAG=4      # lowercase "s" so still accelerating
ENDIF 

IF ($FLAG<3)
  $position=$total
ELSEIF ($FLAG>2)
  $speed=$total
ENDIF   
return


ARC Pro

Upgrade to ARC Pro

ARC Pro will give you immediate updates and new features needed to unleash your robot's potential!

United Kingdom
#1  

That is strange something in the UBB code is forcing a "click to watch video" piece of text in my listing? That part should read as below.

:RAMP uartwrite(0,0,"D,s"+$str,13) $v=$unit*$x

Thats even odder I cannot write that line of code down even outside the UBB code, it always converts it to that text note?

As I cannot give the line of code here, anyone that wants a full listing just send me a email.

Tony

United Kingdom
#2  

Tony,

When I find the forum takes over the code I post it to pastebin.com or upload a project to the cloud which can then be merged in to another project easily.

I only wish I could try this out, one day I'll get there with a sabertooth and kangaroo though (too many other things pushing it to the side currently)

#3  

Hi @Tony(Toymaker),

This is grand news! Thanks so much for taking the time to do this. You have no idea how much I appreciate your help. Very timely also as I was going to spend this weekend trying to get the script worked out to turn my motor to points and add ramping. You probably saw my post yesterday evening asking for help getting the right script commands to get the Kangaroo to return it's position information. With the understanding of what I was doing wrong with that script and your work I truly think I can get ramping to work on my motor (I had the wrong board numbered in the command as I'm using two EZB's and then one I want to operate is Board 1 not 0).

I've just quickly looked over your script above and it looks like a work of art. I do understand I need to change a few values to get it to work as needed for me. Things like what board I want to initiate and the channel names. Looks like you changed the Kangaroo channel names from 1 and 2 to T and D. I'm sure I'll have to make a few other tweaks but we'll see. There is a bunch of other commands I have no earthly idea how they work or do (like definearray) but that's why you decided to help and while working this through it's how I learn. ;)

I will however need to see that one command that won't show properly in this thread. I wish they would work on fixing this annoyance. Hopefully when they get some extra time it will happen. I'll send you a private e-mail as requested.

Again, Thanks so much! :)

#4  

I would love to have a copy:) I do not have Tony's email addy.

Old-FireFighter138(at)neo(dot)rr(dot)com

Please & Thankyou

United Kingdom
#5  

Dave, yes I saw your post and that triggered me into posting the script.

I have sent you the whole ARC project so you can play with it all.

Some things to remember

  1. Your wheel turn value would will be lower (probably half) as you are using the motors with a different gearbox,

  2. The baud rate I use is 19200, you may want to change this to 9600

  3. The "D" (Drive) and "T" (Turn) channels are because I am using the Kangaroo in mixed mode for 2 motor locomotion, for single motors you will need to change this to "1" or "2" etc

  4. You will need to autotune the Kangaroo first, I use the DEscribe software where it is much easier to do than by using the small push switch on the board. You can also change the baud rate here.

  5. The definearray is for the byte array that is required in the ASCII to decimal subroutine.

There should be everything you need in that script to do what you want.

Tony

#6  

Thanks again Tony! You've been an unbelievable assist and help. I hope I haven't been to much of a pain.

I have been into and used the DEscribe software and am fairly familiar with it. It does work great and I do like using it to tune instead of the button pushing method. However it's less then intuitive and user friendly for a Techno-dud like me but I seem to muddle through with persistence and little help from my friends. :D

#7  

Well @Tony, I suppose you kinda knew this was going to happen but I'm lost in your script and cant quite wrap my head around it. blush I feel real bad as you it looks like you put a lot of work into this and a boob like me cant understand it. tired

I kinda see what your doing here and maybe it my application but I'm sure it's just my lack of experience with code. After going through it a few times and changing the things you told me I just cant get it to do anything but loop. I went through the script but lost your logic path about half way through.

It looks like this script is set up to drive a couple wheels at different speeds for turning? Could you take a look at the printout below I copied from the script console window and see if you notice anything. It should be everything from start-up to the second loop. As I said it just keeps looping till I manually stop it and the motor does not turn.

How does this script get the position value I want to stop at and the speed I want it to max out at? For example after tuning the Kangaroo it tells me my position spread is between 0 and 157307 and speeds between 0 and 22000. Lets say i want only one motor (channel 1) to go to position 79440 at a speed of 10000. How do I get that into this script?

BTW, I do see the yellow LED flash on the Kangaroo when it receives the "Start" commands so I know it's receiving the code.

Thanks!

here's the printout


Start
8: definearray($byte,10)
9: $wheel_turn=31449
10: $dly=50
11: $FLAG=0
12: uartinit(1,0,9600)
15: uartwrite(1,0,"1,start",13)
16: uartwrite(1,0,"2,start",13)
17: uartwrite(1,0,"1,p0",13)
19: goto(START)
26: :START
28: $val=$wheel_turn-500
29: $position=0
30: $unit=round($val/8)
31: $str="4000"
32: $x=1
33: goto(RAMP)
53: :RAMP
54: uartwrite(1,0,"1,s"+$str,13)
55: $v=$unit*$x
56: REPEATUNTIL($position>$v)
57: goto(GET_POS)
82: :GET_POS
83: uartwrite(1,0,"1,getp",13)
84: sleep($dly)
85: goto(GET_DATA)
98: :GET_DATA
99: $num_bytes=uartavailable(1,0)
101: $data=uartread(1,0,$num_bytes)
103: $byte1=getbyteat($data,0)
104: $byte2=getbyteat($data,1)
105: $byte3=getbyteat($data,2)
108: $total=0
109: $multiplier=1
110: $x=$num_bytes-2
111: REPEATUNTIL($x=3)
112: $byte[$x]=getbyteat($data,($x-1))
113: $byte[$x]=($byte[$x]-48)*$multiplier
114: $total=$total+$byte[$x]
115: $multiplier=$multiplier*10
116: $x--
117: ENDREPEATUNTIL
121: IF ($byte3=80)
123: ELSEIF ($byte3=112)
125: ELSEIF ($byte3=83)
127: ELSEIF ($byte3=115)
129: ENDIF
131: IF ($FLAG<3)
132: $position=$total
135: ENDIF
136: return
86: print($position)
> 2
87: return
58: ENDREPEATUNTIL
57: goto(GET_POS)
82: :GET_POS
83: uartwrite(1,0,"1,getp",13)
84: sleep($dly)
85: goto(GET_DATA)
98: :GET_DATA
99: $num_bytes=uartavailable(1,0)
101: $data=uartread(1,0,$num_bytes)
103: $byte1=getbyteat($data,0)
104: $byte2=getbyteat($data,1)
105: $byte3=getbyteat($data,2)
108: $total=0
109: $multiplier=1
110: $x=$num_bytes-2
111: REPEATUNTIL($x=3)
112: $byte[$x]=getbyteat($data,($x-1))
113: $byte[$x]=($byte[$x]-48)*$multiplier
114: $total=$total+$byte[$x]
115: $multiplier=$multiplier*10
116: $x--
117: ENDREPEATUNTIL
121: IF ($byte3=80)
123: ELSEIF ($byte3=112)
125: ELSEIF ($byte3=83)
127: ELSEIF ($byte3=115)
129: ENDIF
131: IF ($FLAG<3)
132: $position=$total
135: ENDIF
136: return
86: print($position)
> 2
87: return 

Here's the code you wrote with the changes I made:


# -------------------------------------------------
# Name    : V4_Roo_serial
# Author  : Tony Ellis
# Date    : 01/07/2014
# Version : 1.0
# -------------------------------------------------

definearray($byte,10)
$wheel_turn=31449
$dly=50
$FLAG=0
uartinit(1,0,9600)           #initalise UART

# ***** Initalise Kangaroo
uartwrite(1,0,"1,start",13)   #drive channel start
uartwrite(1,0,"2,start",13)   #turn channel start
uartwrite(1,0,"1,p0",13)      #this is also needed at start

#goto(START)

$val=2*$wheel_turn   # load position
$COMM_CHR="1F3"      # 1=drive channel - F=move forward - 3=speed 3
goto(INC_POS)
halt()

:START

$val=$wheel_turn-500
$position=0
$unit=round($val/8)
$str="4000"
$x=1
goto(RAMP)
$str="7000"
$x=2
goto(RAMP)
$str="10000"
$x=3
goto(RAMP)
$str="7500"
$x=6
goto(RAMP)
$str="5500"
$x=7
goto(RAMP)
$str="2500"
$x=8
goto(RAMP)
uartwrite(1,0,"1,s0",13)
halt()


:RAMP
uartwrite(1,0,"1,s"+$str,13)
$v=$unit*$x
REPEATUNTIL($position>$v)
  goto(GET_POS)
ENDREPEATUNTIL 
print("position="+$position)
print("speed="+$str)
return

# -------------------------------------------------
# Subroutines

# ***** POSITION commands *****

:INC_POS                           # increment position subroutine
$str=tostring($val)                # convert variable to string
$COMM="pi"                         # determine direction
IF (getcharat($COMM_CHR,1)="R")
  $COMM="pi-"
ENDIF 
goto(SEND_DATA)
goto(GET_POS)
REPEATUNTIL($FLAG=1)
  goto(GET_POS)
ENDREPEATUNTIL 
print("POSITION = "+$position)
return

:GET_POS                           # get current position subroutine
uartwrite(1,0,"1,getp",13)
sleep($dly)
goto(GET_DATA)
print($position)
return

# -------------------------------------------------
:SEND_DATA
$M_SPEED=(getbyteat($COMM_CHR,2)-48)*1200
$string=(getcharat($COMM_CHR,0)+","+$COMM+$str+"s"+$M_SPEED) # build data packet
uartwrite(1,0,$string,13)                                    # send packet
sleep($dly)                                                  # delay required
return

# -------------------------------------------------
:GET_DATA
$num_bytes=uartavailable(1,0)

$data=uartread(1,0,$num_bytes)

$byte1=getbyteat($data,0)    # byte 1 = command
$byte2=getbyteat($data,1)    # byte 2 = ","
$byte3=getbyteat($data,2)    # byte 3 = command completed status

# ***** Convert ASCII digits to decimal number
$total=0
$multiplier=1
$x=$num_bytes-2
REPEATUNTIL($x=3)#$num_bytes-7)
  $byte[$x]=getbyteat($data,($x-1))
  $byte[$x]=($byte[$x]-48)*$multiplier
  $total=$total+$byte[$x]
  $multiplier=$multiplier*10
  $x--
ENDREPEATUNTIL 
  
  # ***** Determine byte 3
  # $FLAG=0
IF ($byte3=80)
  $FLAG=1      # "P" returned so move completed
ELSEIF ($byte3=112)
  $FLAG=2      # lowercase "p" so move not completed
ELSEIF ($byte3=83)
  $FLAG=3      # "S" returned so speed reached
ELSEIF ($byte3=115)
  $FLAG=4      # lowercase "s" so still accelerating
ENDIF 
  
IF ($FLAG<3)
  $position=$total
ELSEIF ($FLAG>2)
  $speed=$total
ENDIF   

United Kingdom
#8  

Dave, because I am using the Kangaroo for 2 motor locomotion I have only tested it in "mixed mode", I have not tried it in "independent mode" (single motor). Have you got 2 motor units? If so could you try my original code in mixed mode to see if you can get that working, and then we can work from there.

If not, I will set up my system to independent mode and try here. But please bear with me, I am redesigning my multi-million selling toy product "Cube World" Cube World first US TV advert to bring it back to the market after 7 years and its taking most of my time! But I will try to make some time later this week and maybe do a video which may help.

Don't worry Dave working together, we will get your rig working, its just a matter of time.

My example shows 2 ways of using the Kangaroo subroutines you need to enable the "goto(START)" line to use the second.

To explain the first

  1. $val holds the position that you want to get to, in the example it is 2 complete wheel revolutions

  2. $COMM_CHR is a string that holds a simple way that I devised to build a motion command Example "DF3" D = drive channel it could also be T for turn channel (in mixed mode) F = move forward it could also be R for reverse 3 = speed 3 I use speeds 0 to 9 this gets converted to actual speed ($M_SPEED) in the first line of the SEND_DATA subroutine So "TR9" would give TURN, REVERSE, SPEED 9

  3. Goto(INC_POS) is go to the increment position subroutine (and other nested subroutines) where everything gets converted into detail that the Kangaroo is looking for.

The second example shows a different way of using the subroutines

Your listing (first one numbered) does not seem to set $FLAG (lines 123 etc) this is critical (ie FLAG=1) as it allows a return from the INC_POS routine, without this flag the REPEATUNTIL routine will go on for ever.

Tony

#9  

Thanks again Tony for being willing to hang in there with me. I know and understand how busy you must be. You do amazing work and I'm always impressed and inspired by what you come up with. That Cube World looks like a real scream. I hope you have success bringing it to market and I have the opportunity to get a stack of them. I think I remember something about them a while ago. How long ago did they premiere and were they sold in the USA?

What you state makes sense somewhat. I understand you have your Roo in Mixed mode and this script is written for wheels turning in tandem because the Sabertooth has two channels that drives one motor each.

I have my Kangaroo that controls the Sabertooth set on independent mode because I have each motor attached to the Sabertooth operating different functions of the B9 robot. Channel 1 operates the waist turning motor. This is the motor you pointed me to that has this exceptional encoder attached. This is the channel I really need the ramping abilities of this script and where I'll be sending most of my position and speed commands to. Channel 2 of the Sabertooth drives my hip motor that bends the robot over. This motor also has the same type encoder sending feedback but is attached differently. This will be just basic up and down movement with maybe a stop half way once in a while.The need for ramping is not so important here but would be nice as I think it helps with mechanical wear at the least.

So to make a long story short (too late I guess) I'll need to be sending different position and speed commands to each of the channels.

As for my first numbered listing above I see that the position returned is always 2. The section you referenced as not having the flag set looks like the position section. I wonder if somehow I'm not getting the position feedback from the Roo into the script. I see there is a Delay of 50 after the Getp command. Maybe I need more time?


82: :GET_POS
83: uartwrite(1,0,"1,getp",13)
84: sleep($dly)

Also i changed your $COMM_CHR="DF3" to $COMM_CHR="1F3" in my script. Should I have done this since my channels are numbered 1 and 2?

Just for reference here's a couple pics showing the two motors I want to move independently:

Hip Motor, You can see the EZB v4 and the Sabertooth in the background,

User-inserted image

Waist Motor, It's covered in Dynamat to dampen the noise. If I reverse direction to quickly the gears skip teeth and screws up the Home. Ramping will stop this.

User-inserted image

#10  

OK, I've had limited success. I got the motor to move to the assigned position with your script and the print() in the console shows the progressed position as it moves. However the motor moves very slowly with no ramp up to top speed. I'm not sure yet how to set the top speed with this script so that may be that problem. Sadly though the way I got it to work is impracticable for each time I use this script which may be a ton.

I haven't reset my Roo to Mixed mode yet as you suggested but I can't really operate in that mode but I will if you think it will help. However I tried this first; I inserted a command into the beginning of your script to send Kangaroo's "Home" command to each channel and a Sleep() command to let it complete the move. After the Homing was complete and the Sleep() expired the motor took off (very slowly) to the assigned position and stopped.

The start of the modified script looks like this with the added lines:



# -------------------------------------------------
# Name    : V4_Roo_serial
# Author  : Tony Ellis
# Date    : 01/07/2014
# Version : 1.0
# -------------------------------------------------

definearray($byte,10)
$wheel_turn=31449
$dly=50
$FLAG=0
uartinit(1,0,9600)           #initalise UART

# ***** Initalise Kangaroo
uartwrite(1,0,"1,start",13)   #drive channel start
uartwrite(1,0,"2,start",13)   #turn channel start
uartwrite(1,0,"1,p0",13)      #this is also needed at start

#goto(START)

#*******The following three lines were added and made the motor move to position but only once
uartWrite(1, 0, "1, Home", 0x0d)  #Homes Channel 1
uartWrite(1, 0, "2, Home", 0x0d)  #Homes Channel 2
Sleep(24000)

$val=2*$wheel_turn   # load position
$COMM_CHR="1F3"      # 1=drive channel - F=move forward - 3=speed 3
goto(INC_POS)
halt()

:START

I tried to run the script again without the Home command and it did nothing till I again added in the commands. This is odd and I have no idea why it is doing this but at least I know the script will move the motor.

As an added note; I have the following commands in my start up script when ARC starts So I shouldn't need them again in your script (I think):


uartWrite(1, 0, "1, Home", 0x0d)  #Homes Channel 1
uartWrite(1, 0, "2, Home", 0x0d)  #Homes Channel 2
uartinit(1,0,9600)                         #initalise UART
uartwrite(1,0,"1,start",13)             #1channel start
uartwrite(1,0,"2,start",13)             #2 channel start

I have no idea what to do now or where to look after this. Hopefully this will aid you with the tweaks. Of course when you have time and ambition to do it. Family, friends, personal enjoyment and the day job always comes first. ;)

PRO
Synthiam
#11  

Tony, what do you mean by Ascii to Decimal?

This will send a single byte with the value of 123...


$x = 123

uartWrite(1, 0, $x)

United Kingdom
#12  

Hi DJ

The Kangaroo returns large numbers (just 10 wheel revolutions would be 638900) in an ASCII string for position (> a byte and would require a Dword var) and I want to convert this into a single decimal number so I devised the routine (***** convert ASCII digits to decimal number) in my listing to do this. I was just not sure if their was a better way? I really like your scripting language and want to use it efficiently.

My code listing got corrupted when it was pasted into the code view. I have looked through and there are a number of omissions/problems caused by pasting it in via the code view, complete lines missing and "<" and ">" directives are even extracted from some lines.

Apologies to anyone trying to use the code but with the corrupted parts its probably unusable, as I said before I am happy to sent the script to anyone that wants it.

Tony

#13  

@Tony, the code I've been using is the one you sent me through the web.

United Kingdom
#14  

Dave, I know you have the full code, but the omissions made my script look completely wrong and it then did not make sense in places so I wanted to alert other forum members. Below is a video that shows the script working, the first demo calls for the Kangaroo to drive forward 2 wheel revolutions at slow speed (3) "DF3" you can see the returned positions from the Kangaroo (in decimal) on the screen. The second demo (on the video) is a kind of course ramp up to speed and then ramp down. I will not be using the V4 to control my Kangaroo as I have a dedicated locomotion PIC that sits as an interface for the V4 so it does not to get "bogged down" with controlling, this is why this script/demo are a bit limited as I just knocked it up quickly to help you guys on the forum.

Cube World sold all over the World, it was huge in the States and also Japan, here is a very cool Japanese TV advert
youtu.be/AotdNHrk0iM Here is my favorite US TV advert for series 4 (sports) youtu.be/fToQbGUT-s8
With our new cubes characters can now jump out of their cube into a tablet device.

Tony

#15  

Thanks Tony for the video. Good luck with your cube project. I hope you keep us informed of its progress.

United Kingdom
#16  

Dave, I have spent a hour and modified my rig to "independent mode" and modified my script and got it to work now in independent mode. I will spend another hour tomorrow (refine the code a bit) and send you the revised script.

Tony

#17  

@Toymaker

Rather than just sending the script to individuals, can I recommend that you put it in an EZ-B project (with nothing else) and attach the project to a post? That way months/years from now, users will still be able to download and work with it without you needing to respond to every request.

Alan

#18  

@Tony, I know how valuable and limited your time is. Your truly an exceptional and top quality person to do this for me and others here. I can't properly express how much this is appreciated. With your workload and a family life I never expected this so quickly. Thanks my friend. I hope that someday, somehow I can return the favor. :)

United Kingdom
#19  

Dave, here is the script for independent mode it works fine here, you will need to set the SPEED_MULTIPLIER var (it probably will be double my value), also wheel_turn will be half. I will send you the project file by email.

The example first goes forward 2 revolutions (at speed 9) and continues to report positions back from the Kangaroo until it reaches the target position. It then goes in reverse for 1 revolution (at speed 3) again reporting back the position. You will see a slight lag in the position printout on the script window, this is because the V4 cannot fully keep up with the Kangaroo at these baud rates so it over-runs a bit, the position will still be got to accurately though.

For channel 2 just change the command string to something like "2F7" etc

As this is a tutorial I will post the script here so all can see.


# -------------------------------------------------
# Name    : V4_Roo_independent
# Author  : Tony Ellis
# Date    : 01/08/2014
# Version : 1.0
# -------------------------------------------------

definearray($byte,10)
$wheel_turn=63890
$dly=50
$FLAG=0
$CHANNEL=1
$SPEED_MULTIPLIER=1200       
uartinit(0,0,9600)  # initalise UART

# ***** Initalise Kangaroo
uartwrite(0,0,&quot;1,start&quot;,13)  # drive channel start
uartwrite(0,0,&quot;2,start&quot;,13)  # drive channel start
uartwrite(0,0,&quot;1,p0&quot;,13)     # this is also needed at start
uartwrite(0,0,&quot;2,p0&quot;,13)     # this is also needed at start

#goto(EXAMPLE_2)

# ***** Example for CHANNEL 1
$val=2*$wheel_turn   # load position = 2 wheel turns
$COMM_CHR=&quot;1F9&quot;      # 1=drive channel - F=move forward - 9=speed 9
goto(INC_POS)
print(&quot;position attained&quot;)
sleep(2000)
$val=$wheel_turn     # load position = 1 wheel turn
$COMM_CHR=&quot;1R3&quot;      # 1=drive channel - R=move forward - 3=speed 3
goto(INC_POS)
print(&quot;position attained&quot;)
halt()


# -------------------------------------------------
# Subroutines

# ***** POSITION commands *****

:INC_POS                           # increment position subroutine
$str=tostring($val)                # convert POSITION variable to string
$COMM_CHR,0=tostring($CHANNEL)     # convert CHANNEL variable to string
$COMM=&quot;pi&quot;                         # determine direction
IF (getcharat($COMM_CHR,1)=&quot;R&quot;)
  $COMM=&quot;pi-&quot;
ENDIF 
goto(SEND_DATA)
goto(GET_POS)
REPEATUNTIL($FLAG=1)
  goto(GET_POS)
ENDREPEATUNTIL 
print(&quot;POSITION = &quot;+$position)
return

# -------------------------------------------------

:GET_POS                           # get current position subroutine
uartwrite(0,0,$CHANNEL+&quot;,getp&quot;,13)
sleep($dly)
goto(GET_DATA)
print($position)
return

# -------------------------------------------------
:SEND_DATA                         # assemble data packet and send to Kangaroo
$M_SPEED=(getbyteat($COMM_CHR,2)-48)*$SPEED_MULTIPLIER
$string=(getcharat($COMM_CHR,0)+&quot;,&quot;+$COMM+$str+&quot;s&quot;+$M_SPEED) # build data packet
uartwrite(0,0,$string,13)                                    # send packet
sleep($dly)                                                  # delay required
return

# -------------------------------------------------
:GET_DATA                          # get data back from Kangaroo
$num_bytes=uartavailable(0,0)

$data=uartread(0,0,$num_bytes)

$byte1=getbyteat($data,0)    # byte 1 = command
$byte2=getbyteat($data,1)    # byte 2 = &quot;,&quot;
$byte3=getbyteat($data,2)    # byte 3 = command completed status

# ***** Convert ASCII digits to decimal number
$total=0
$multiplier=1
$x=$num_bytes-2
REPEATUNTIL($x=3)#$num_bytes-7)
  $byte[$x]=getbyteat($data,($x-1))
  $byte[$x]=($byte[$x]-48)*$multiplier
  $total=$total+$byte[$x]
  $multiplier=$multiplier*10
  $x--
ENDREPEATUNTIL 
  
# ***** Determine byte 3
# $FLAG=0
IF ($byte3=80)
  $FLAG=1      # &quot;P&quot; returned so move completed
ELSEIF ($byte3=112)
  $FLAG=2      # lowercase &quot;p&quot; so move not completed
ELSEIF ($byte3=83)
  $FLAG=3      # &quot;S&quot; returned so speed reached
ELSEIF ($byte3=115)
  $FLAG=4      # lowercase &quot;s&quot; so still accelerating
ENDIF 
  
IF ($FLAG&lt;3)
  $position=$total
ELSEIF ($FLAG&gt;2)
  $speed=$total
ENDIF   
return

#20  

@Tony, I said this to you privately in my last e-mail but I'd like to repeat it here publicly;

I hope I'm not starting to sound too mushy or scripted but I really do appreciate this. I'm honored to be using scripts in my B9 crafted by a designer of your caliber and fame. I really look up to you and respect and amazed at what you can do. I'm looking forward to digging into this script and seeing if I can figure it out and apply it. I'm sure I'll have a question or two. Please don't feel like you need to respond right away and help figure it out. We both have busy lives and lots to do.

I've been showing my family your Cube World commercials and some of them remember them. My 40 yr old son (I was very young when he was born ;-) ) members clearly and got real excited. He says he really wanted to buy a set when they were available but didn't have the opportunity or cash. Good luck on the new roll out when it ready. I hope you are able to let me and others on the forum know when that will be. These and your little dinosaurs would make excellent gifts for my grand kids (and me too).

#21  

Thanks, Tony for sharing this code with us. Mel

#22  

BTW, what is the purpose of the Kangaroo? Is it just for serial communications? Or does it do something else?

thanks,

#23  

Jeez Mel.... have you been under a rock for the last 6 months lol.... What it is a how to use the kangaroo has seen a couple of major threads on the subject (including this one).... just do a search here (Dave stated a major one for his B9)...Also go to Dimension Engineering's web page to read up on it.... Why don't you take the time to read up on it.... then ask the questions...

United Kingdom
#24  

Mel, the Kangaroo is an ingenious device that converts the Sabertooth motorcontroller into a fantastically versatile closed-loop dual motor dive system (closed-loop = feedback of position etc - open loop = no feedback), so a servo is a closed-loop device as it has a feedback potentiometer. The Kangaroo also allows for encoder feedback and I use this (see my threads on it) to make my robots go in totally straight lines and precise distances. It uses an algorithm known a PID (Proportional-Integral-Derivative) which is normally quite difficult to tune, the genius thing about the Kangaroo is that it has an "autotune" function that does the tuning for you. Here is a link

en.wikipedia.org/wiki/PID_controller

Tony

#25  

Hey Mel, The auto tune on the Kangaroo X2 make set up of it very easy. It's important however to have your motor attached properly, have a feedback device like a pot or encoder attached to it and everything wired correctly. If any of these are not present the Kangaroo will sense this and shut down. This can be both good and bad as it's frustrating trying to find what's not working properly but it will also sense a catastrophe situation like a runaway or short and shut it's self down. The auto tune is a wonder and a lot of fun to watch. I love watching my robot twist and turn at different speeds while the tune is going on. Here's a few Ytube vids I found of this:

#26  

Nice , kangaroo sounds like it is an excellent add on for the sabertooth. I should pick on up after ezbs arrive.

#27  

@Joeh, I highly recommend this combination. It would be a snap and a no brainer for a guy with your talent.

United Kingdom
#28  

Josh, I second Dave's comments the Kangaroo/Sabertooth combo is an excellent PID motor controller, look at my earlier parts in this thread where I show coding the Kangaroo from EZ-Script it covers pretty much all you need to know about fully controlling motors and analysing feedback from the encoders etc.

I have though discovered a problem with the Kangaroo in that you cannot use high resolution encoders (of the type I use) in mixed mode (dual motor locomotion), I am having to design a circuit that divides the encoders outputs to get it all to work. With a single motor with high res encoder (independent mode) you should be ok, its just when the Kangaroo has to deal with 2 motors simultaneously it cannot keep up with the counts.

Tony

#29  

OK, I sort of understand now. Thanks , Guys! And, I do crawl under a rock from time to time to rest my eyes and brain.

#30  

@Tony, I can confirm that the kangaroo works perfectly in independent mode useing the high resolution encoder. That's how I'm controlling my motors and they function fine.