Sabertooth Kangaroo packetized serial programing questions

Hi, I have a Dimension Engineering (DE) Sabertooth / Kangaroo setup driving my mixed mode 2 wheel differential drive bot.

I am more of a hardware guy and am having trouble understanding how to use the packetized serial library that Dimension Engineering provides.

I am using an arduino mega2560 to sentd packetized serial commands to the kangaroo. I have it driving forward and reverse with velocity (S) commands and turning with position (Pi) commands.

I have not figured out how to process the return values from the Drive and Turn commands and am lost with how to use the Status and Monitor commands.

Has anybody figured out these things? I am hoping that someone here will point me in the right direction.

The DE Kangaroo arduino class libraries appear to be written by a C++ genius which I am not. I can't make out how to use the error, status and monitoring objects. If anybody that knows C++ could download their class libraries and take a look at them I would really appreciate it.

I can share my kangaroo test code if anybody wants to take a look.

There is a video by DE showing Kangaroo Drive Mode Autotune procedure. The Kangaroo user manual does not document this procedure. I wrote a 'How To' procedure which describes my 2 wheel differential drive (aka Kangaroo Mixed Mode) setup and the steps to do the autotune. The robot can now be driven using a RC transmitter and receiver or packetized serial commands or 2 PWM signals from a microcontroller.

I will post my 'How To' word doc if anyone would like to use it.

Thanks in advance for your help.

If you want others to look at the driver and other stuff, you should post links to them.

I have not figured out how to process the return values from the Drive and Turn commands and am lost with how to use the Status and Monitor commands.

Do you have any use for those features?

Here are the links to the Dimension Engineering Kangaroo arduino library and user manuals:

http://www.dimensionengineering.com/products/kangaroo the above has links to the user manual and how to download the library

www.dimensionengineering.com/software/KangarooArduinoLibrary/html/ www.dimensionengineering.com/datasheets/KangarooPacketSerialReference.pdf

Only the GET command reference in the kangaroopacketserialreference mentions returning an error code.

None of the example arduino sketches show how to retrieve and process the returned values from any of the kangaroo commands.

In the KangarooChannel.cpp file the following commands show that they return an object of KangarooError: start, units, powerDown, powerDownAll, and serialTimeout.

In the KangarooChannle.cpp file the following commands show that they return an object of KangarooMonitor: home, p, pi, s, si, motion, set.

In the KangarooChannel.cpp file the following commands show that they return an object of KangarooStatus: get, getSpecial

What I am asking for help with is: (see the Mixmode.ino file in the Examples/Basic folder of the arduino lib).

examples of how to declare variables of these objects types in relation to my KangarooChannel objects KangarooChannel Drive(K, 'D'); and KangarooChannel Turn(K, 'T'); and then process there contents for the following commands:

errors: start, units, powerDown, powerDownAll, and serialTimeout

errors and monitoring: home, p, pi, s, si

errors and status: getp, getpi, gets, getsi, getmin, getmax

Yes I have a use for these features. I would like to know if a command succeeded, timedout or some other error occurred. Some Move commands take time to get up to full speed, I think this is where the Status and Monitoring features come into play.

Really appreciate any help in understanding how to check for errors, check status, and how to use monitoring.

Thanks again

Hello tomega3
I have a mega, sabertooth and kangaroo and have the same unanswered questions. I have just received an encoder and will be mounting it this week.

I am also new to C++ and I agree the code is difficult to understand to the untrained eye. From what I can make out the getP(),getS(), getSI(), getPI() methods return a KangarooStatus Object.

I believe the idea is to initialize a Status object. When status data is wanted set the status object equal to the KangarooChannel Objects’s get method (i.e. getP(),getS(), getSI(), getPI()) and then use one of the KangarooStatus Methods to get the data you want.

I also notice that for any of the Kangaroo Get methods you must use a “KangarooGetFlag” of which you have two options.

  • KANGAROO_GET_DEFAULT – Normal behavior.
  • KANGAROO_GET_RAW_UNITS – Use raw units. For analog, raw units are millivolts. For quadrature, 4 raw units equal 1 line

thats copied straight from the documentation and I think you can just enter 0 or 1… or maybe 1 or 2. don’t quote me though.

I have modified the mixedmode example code to how I think this will work but I cannot test until I mount the Encoder. take a look and tell me what you think.

#include <SoftwareSerial.h>
#include <Kangaroo.h>

#define TX_PIN 11
#define RX_PIN 10

// Mixed mode channels on Kangaroo are, by default, 'D' and 'T'.
SoftwareSerial  SerialPort(RX_PIN, TX_PIN);
KangarooSerial  K(SerialPort);
KangarooChannel Drive(K, 'D');
KangarooChannel Turn(K, 'T');
/*
 * from what I understand of the h file you can call constructor w/ no parameters 
 * and the library will take care of the magic behind the status object
 */
KangarooStatus Feedback;  

void setup()
{
  SerialPort.begin(9600);
  SerialPort.listen();
  
  Drive.start();
  Turn.start();
  
  Drive.si(0);
  Turn.si(0);
}

void loop()
{
  ////////////////////////FIRST TEST KANGAROOSTATUS//////////////////////////////////////////////////
  /*
   * I believe all the propertis are set to zero in intialization....
   * Lets find out!
   */
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT); //Can't understand documenation=>need to play around with the getflgs
  Serial.println(Feedback.value());// This returns a int32_t => might need some formating/casting before printing
  Serial.print('The Kangaroo is'); 
  if(Feedback.ok()){
    Serial.println('good to go');
  }
  else{
    Serial.println('not ok');
  }
  ////////////////////////FIRST TEST KANGAROOSTATUS//////////////////////////////////////////////////
  
  // Drive 500 ticks (relative to where we are right now), then wait 1 second.
  Drive.pi(500).wait();
  delay(1000);
  
  ////////////////////////SECOND TEST KANGAROOSTATUS//////////////////////////////////////////////////
  //lets see what the values are Now.
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Drive.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.gets(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Turn Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Turn Value is:');
  Serial.println(Feedback.value());
 ////////////////////////SECOND TEST KANGAROOSTATUS//////////////////////////////////////////////////
 
  // Turn 500 ticks (relative to where we are right now), then wait 1 second.
  Turn.pi(500).wait();  
  delay(1000);
  
  ////////////////////////THIRD TEST KANGAROOSTATUS//////////////////////////////////////////////////
  //lets see what the values are Now.
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Drive.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.gets(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Turn Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Turn Value is:');
  Serial.println(Feedback.value());
  ////////////////////////THIRD TEST KANGAROOSTATUS//////////////////////////////////////////////////
}

Sorry if that is hard to read I tried to add some comments to make it more clear

You wrote that the DE website has a video on tunning and that you have written a document describing the steps could you please share this link and document?

CHEERS!
Pablo

Just realized that the computer serial commnication neeeds to be set

#include <SoftwareSerial.h>
#include <Kangaroo.h>

#define TX_PIN 11
#define RX_PIN 10

// Mixed mode channels on Kangaroo are, by default, 'D' and 'T'.
SoftwareSerial  SerialPort(RX_PIN, TX_PIN);
KangarooSerial  K(SerialPort);
KangarooChannel Drive(K, 'D');
KangarooChannel Turn(K, 'T');
/*
 * from what I understand of the h file you can call constructor w/ no parameters 
 * and the library will take care of the magic behind the status object
 */
KangarooStatus Feedback;  

void setup()
{
  Serial.begin(9600);
  SerialPort.begin(9600);
  SerialPort.listen();
  
  Drive.start();
  Turn.start();
  
  Drive.si(0);
  Turn.si(0);
}

void loop()
{
  ////////////////////////FIRST TEST KANGAROOSTATUS//////////////////////////////////////////////////
  /*
   * I believe all the propertis are set to zero in intialization....
   * Lets find out!
   */
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT); //Can't understand documenation=>need to play around with the getflgs
  Serial.println(Feedback.value());// This returns a int32_t => might need some formating/casting before printing
  Serial.print('The Kangaroo is'); 
  if(Feedback.ok()){
    Serial.println('good to go');
  }
  else{
    Serial.println('not ok');
  }
  ////////////////////////FIRST TEST KANGAROOSTATUS//////////////////////////////////////////////////
  
  // Drive 500 ticks (relative to where we are right now), then wait 1 second.
  Drive.pi(500).wait();
  delay(1000);
  
  ////////////////////////SECOND TEST KANGAROOSTATUS//////////////////////////////////////////////////
  //lets see what the values are Now.
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Drive.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.gets(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Turn Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Turn Value is:');
  Serial.println(Feedback.value());
 ////////////////////////SECOND TEST KANGAROOSTATUS//////////////////////////////////////////////////
 
  // Turn 500 ticks (relative to where we are right now), then wait 1 second.
  Turn.pi(500).wait();  
  delay(1000);
  
  ////////////////////////THIRD TEST KANGAROOSTATUS//////////////////////////////////////////////////
  //lets see what the values are Now.
  Feedback = Drive.getS(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Drive.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Drive Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.gets(KANGAROO_GET_DEFAULT);
  Serial.print('The getS Turn Value is:');
  Serial.println(Feedback.value());
  Feedback = Turn.getP(KANGAROO_GET_DEFAULT);
  Serial.print('The getP Turn Value is:');
  Serial.println(Feedback.value());
  ////////////////////////THIRD TEST KANGAROOSTATUS//////////////////////////////////////////////////
}