Lynxmotion SES V2 Hexapod Robot

Thanks @kurte will give it try and see what happens. In going through your test sketch, it made me think a few basic questions regarding the legs, i.e., axis orientations, definition of some of var’s you have. Sure some of this stuff is somewhere in the forum but going to ask here to be sure.

So simple questions first:

  1. What default baud rate should I set up with to test: Seen 500K or 250K?
  2. In the sketch I see this: IKPinsNames, put now sure what that corresponds to?

Also is this right for axis orientation on the legs:

EDIT: A couple of notes:

  1. Axes shown assume leg is actually stretch out but the foot still points down.
  2. In the schematic of the leg if beta is positive up the the axis shown for femur has to be rotated - just need confirmation.
  3. Did find my notebook on the IK I did for my robot arm so trying to remember everything :slight_smile:
2 Likes

Morning @cyberpalin and all:

Baud Rate: As fast as possible that is reliable :wink: Their LSS test sketch and elsewhere I believe said it could go up to 921.6K and they also show 750K. But I started at 500K and was getting a reasonable number of packets not looking right.
As the data sent back and forth is simply ASCII text with no formatting other than starts with # or * and ends with \r and no checksums or the like, probably don’t want to push it very far. So right now I am testing at 250K. But that is why I have the test sketch to change all of the servos baud rates, so easy to experiment.

IKPinNames minus some stuff:

const char* IKPinsNames[] = {
  "LFC", "LFF", "LFT",
  "LMC", "LMF", "LMT",
  "LRC", "LRF", "LRT",
  "RFC", "RFF", "RFT",
  "RMC", "RMF", "RMT",
  "RRC", "RRF", "RRT",
};

LFC - Left Front Coxa, LFF - Left - Front Femur, LFT - Left Front Tiba
LM - Left Middle
LR – Left Rear
RF - Right Front

For me it helped that in test program for example you turn tracking on, and you move a servo it shows the logical name,
which for example made sure my servo numbers were set properly. Or on the Old RC ones that I got the servo plugged into the right pins on the SSC-32… (Yes have had a hacked up sketch like this for a long time :wink: )

Note Some version had a 4th degree of freedom TARS.

Orientations and Math (I forgot what math is :wink: ) Some of this is best answered by @zenta and @xan but the original setup and code was originally done by Kåre (Zenta) using Excel:
The details of that are up at: http://www.lynxmotion.com/images/html/proj098.htm
And then Jeroen (Xan) made the first version for Basic Atom Pro: http://www.lynxmotion.com/images/html/proj102.htm

I know there are discussions in this thread about converting to a more standard coordinate system. Probably along the same line that is used in ROS, which I believe uses the Right Hand Rule: https://en.wikipedia.org/wiki/Right-hand_rule

1 Like

I just pushed up a version of this program to my LSS Test project.

It has more ability to show you what is received on the Serial port and the USB port and show that data on
the SerialUSB1 port if you build for dual or triple serial.

You can turn on/off the echo type typing in something on the USB1 port.

Note; I am using Tycommander, and I tell it to show me stuff on the secondary port, but not connect to the primary port, I can then load the LSS sketch and do a connect…

Again simply entering nothring(cr) will toggle the echo on or off.
entering a ‘d’ will do a quick and dirty hex dumps… Not it dumps each buffer as it receives it so for Serial port it may only show one character per line

Oops sorry forgot to mention this part.

The setServoID means nothing to the servos, it just sets a variable in the sketch to know which servo your commands to write something to or receive data from…

Now on to implementing the actually update the servo ID: by outputting the command CID
like: #0CID5\r
to change the servo currently id 0 to id 5.

After this I believe I will need to send a reset command and then wait for a couple of seconds for the servo(s) to reboot and be ready to talk

Thanks Kurt. Just got done installing AC. In the 90s today - tomorrow 68 - then back up to 80’s. Crazy temp range.

Any downloaded the PEP spreadsheet and looks like that will be a big help. Really like that spread sheet :slight_smile:

EDIT: Ok think I got the femur and tibia axes corrected - I messed up the right-hand rule when I drew the axes.

It is sort of cold (like 55) and misty here right now

Yep sort of interesting what you can do with Excel with their embed basic.

Note: I just pushed up changes to my test program, that now allows you to change servo ids.

Now out to play

Hi @kurte
Finally got around to hooking up the ST1 I have configure for servoID 2 and 250K baud rate. So started looking at the outputs for the various commands using the LA8.

Tried repeating the 9 2 test with a single servo, sends seemed to between 1 and 1.5 seconds apart (not sure that matters since I did one run as fast as I could with out fails) and didn’t seem to get any fails like you were getting? Timings were the same:

Cmd: 9 2

Servo 2 values
  Q(-1) - 6 t:660
  QO(-1) - 0 t:750
  QAR(-1) - 1800 t:1018
  QP(-1) - 1601 t:971
  QD(-1) - 91 t:820
  QWD(-1) - 0 t:869
  QWR(-1) - 0 t:859
  QS(-1) - 0 t:770
  QSD(-1) - 360 t:983
  QSR(-1) - 60 t:898
  QLED(-1) - 0 t:996
  QG(-1) - 1 t:779
  QID(-1) - 2 t:891
  QB(-1) - -12144 t:1418
  QFD(-1) - DIS t:1864
  QMS(-1) - LSS-ST1 t:1104
  QF(-1) - 368 t:887
  QV(-1) - 12292 t:1107
  QT(-1) - 391 t:1055
  QC(-1) - 0 t:886
  QAS(-1) - 0 t:908
  QAH(-1) - 4 t:910
  QAA(-1) - 100 t:1085
  QAD(-1) - 100 t:985
  QEM(-1) - 1 t:897
  QF(1) - 29 t:895
  QF(2) - 16 t:889
  QF(3) - 368.29.16 t:1168
Total Time: 27445

Want to so some more testing with 2 servos attached and but think that will be a project for tomorrow.

Would be nice to be able to send a series of commands from txt file or something to see what happens - but think that will be on my todo list for now.

Note the 9 (and 8) commands are driven by table:

const LSSQLIST query_list[] = {
  {LSQ_S16, LSS_QueryStatus, -1},
  {LSQ_S16, LSS_QueryOriginOffset, -1},
  {LSQ_S16, LSS_QueryAngularRange, -1},
  {LSQ_S16, LSS_QueryPositionPulse, -1},
  {LSQ_S16, LSS_QueryPosition, -1},
  {LSQ_S16, LSS_QuerySpeed, -1},
  {LSQ_S16, LSS_QuerySpeedRPM, -1},
  {LSQ_S16, LSS_QuerySpeedPulse, -1},
  {LSQ_S16, LSS_QueryMaxSpeed, -1},
  {LSQ_S16, LSS_QueryMaxSpeedRPM, -1},
  {LSQ_S16, LSS_QueryColorLED, -1},
  {LSQ_S16, LSS_QueryGyre, -1},
  {LSQ_S16, LSS_QueryID, -1},
  {LSQ_S16, LSS_QueryBaud, -1},
  {LSQ_STR, LSS_QueryFirstPosition, -1},
  {LSQ_STR, LSS_QueryModelString, -1},
//  {LSQ_STR, LSS_QuerySerialNumber, -1},
  {LSQ_S16, LSS_QueryFirmwareVersion, -1},
  {LSQ_S16, LSS_QueryVoltage, -1},
  {LSQ_S16, LSS_QueryTemperature, -1},
  {LSQ_S16, LSS_QueryCurrent, -1},
//  {LSQ_S16, LSS_QueryAnalog, 0},
  {LSQ_S16, LSS_QueryAngularStiffness, -1},
  {LSQ_S16, LSS_QueryAngularHoldingStiffness, -1},
  {LSQ_S16, LSS_QueryAngularAcceleration, -1},
  {LSQ_S16, LSS_QueryAngularDeceleration, -1},
  {LSQ_S16, LSS_QueryEnableMotionControl, -1},
  {LSQ_STR, LSS_QueryFirmwareVersion, 1},
  {LSQ_STR, LSS_QueryFirmwareVersion, 2},
  {LSQ_STR, LSS_QueryFirmwareVersion, 3}
//  {LSQ_S16, LSS_QueryBlinkingLED}
};

Note the Serial number one is commented out, which is the one that regularly failed. Try un-commenting and see if it works.

Also with multiple servos I think I had it such that you could enter 9 -1
and it would do all of the servos …

OK. You know me - couldn’t wait for tomorrow. Anyway’s I am getting fails just as soon as I send the 9 2:

QID(-1) - 2 t:863
QB(-1) - -12144 t:1384
QFD(-1) - DIS t:1797
QMS(-1) - LSS-ST1 t:1098
QN(-1) - (null) failed(2) t:101162
QF(-1) - 368 t:860
QV(-1) - 12296 t:1132

Looking at the LA output:

Then other times it will work - note I was just send the 9 2 command slowly:

QFD(-1) - DIS t:1630
** QMS(-1) - LSS-ST1 t:1103**
** QN(-1) - 141165252203981277 t:1502**
** QF(-1) - 368 t:891**
Other times:

QN(-1) - LS�������203981277 t:1526

Wonder it that is some sort of firmware issue since it is happening with only QN command? In the last case it looks like its getting part of the QMS command? Curious minds…

1 Like

Yep :smiley:

Yes my earlier captures of this with LA running at fastest speed, looks like at times maybe The signal momentarily drops low just long enough for it to be captured by LA and also our UART also failed to properly read it.

I would get this occasionally with some other query calls bot the QN most of the time.

It is almost like maybe some condition where the Servo asserts it’s TX on to the shared TX, and either some state is not set yet but maybe the next instruction and in between an ISR is called which takes long enough for the change to be noticed.

Or maybe in order to get the Serial number, the state of the processor is changed, sort of like we have to do on T4.x to write to EEPROM… And maybe some cases a glitch …

But again just guessing, as other than knowing that it is on an STM32 processor, that is about as much as I know and of course have never seen the code.

Not sure who (or if) anyone is still actively working on the firmware. Did you update the firmware on yours or did it ship with that version?

Using the firmware version shipped with the servo. Think its at xxx. and LSS Config said there was a firmware update to xxx.29?

Now wondering if its a STM32 issue with SN.

If no one is actively working the firmware then it might be problem. What I would like to do at some point is to simulate the gait motion and watch it at different speeds on the LA to see if we get any errors.

@cbenson
Quick question. In step 8 of SES V2 - Sample Leg A - XWiki (robotshop.com) it shows the final assembly of the sample leg. Am I too assume that is the zero position for all the servos? Have to ask - you what they say about assumptions :slight_smile:

Morning all, I hope everyone in Canada is having a nice Holiday! (Was going to say Victoria Day, but I don’t think that is in all provinces)

@cyberpalin - I think I updated all of my servos to a Beta version… You can detect which one in the 9 command you ran

  QF(-1) - 368 t:887
  QF(1) - 29 t:895
  QF(2) - 16 t:889
  QF(3) - 368.29.16

So QF3 gives you the whole version
QF, QF1 and QF2 give you each piece.

So you are running 368.29.16

Mine or sort of a mix right now:
I think the ones that I updated a year or so ago are: QF(3) - 368.29.14
But the ones that I updated to the beta version are: QF(3) - 368.29.18

Maybe or maybe some interaction or timing… I am thinking of ordering the STM32 Micromod

as I have not done much with STM32… Or wonder if defragster has played with the SN? stuff when he has done stuff with STM?

Sounds good. I have also used LA to monitor the messages. The difficulty is I don’t know any good way to fully verify the communications. As there is nothing like a checksum, the only thing I can visually detect is if the Serial data is so far off, that the Logic Analyzer shows something like a frame error. Also since the servos do not do anything like an ACK, there is no easy way to verify that the Servo properly received the message.

The only way I know to try, is for example output the new position for all 18 servos:
like for servo 2: #2D250T250\r

Then go back and do a query for each servos target: #2QDT\r
And verify it’s target is correct .

Or setup a logical servo that is listening to the traffic. First thought is the micromod I mentioned, but it is an M4 running at I think up to 168mhz, which is probably still a lot different than the STM32 I believe that is in the servos that is probably an M0 running at maybe 48mhz…

But probably not hard to rig something up, that can hook up to example end of chain, like off of a tibia servo and try to monitor all of the RX and TX messages.

Not sure how well they will work, but did order a few of these:


As maybe something I could hack up a quick and dirty…

Think that was the only processor I didn’t order :slight_smile: I do have a STM32H7 dev board but that is really off the mark for this testing.

Think for now going to keep them all the same, i.e., default, then later update them all. At least for this round of testing

Maybe we can convince defragster to test for us :), just found this library for arduino: ArduinoUniqueID - Arduino Reference

Yeah going through the protocol thats the only way but its a start I guess. Really think the firmware needs to be update to ACK when movement is complete, or some sort of confirmation. Haven’t really seen any other way unless there is an undocumented command, doubt it.

Maybe :smiley:

As I mentioned in the last message I did order a few STM32F30 M0 boards from Ebay… So may be able to check those. They ship from USA so maybe have within a week.

Back to playing

Oops - missed that one… sorry

Not a problem… I only mentioned as I thought we maybe had cross posted.

Now back to being one of the lost dogs :wink:

Ok back again with questions. But first should be getting my Leg package today. Now for the fun.

Questions regarding SES-V2-Hexapod-Beta/KurtE/Zenta_LSS_Phoenix_PhantomX_float /

FK and IK depend on several critical dimensions and angles. These all seem to be defined in a single file in that repository: Hex_Cfg.h and pretty closely resembles what I saw in the PEP spreadsheet. So since it looks like I am using a different leg geometry - maybe from those in that file think I am going to have to do some editing.

For the body I probably can still use one of the ones defined:

//#define MXPhoenix //setup for my MX64/106 based hexapod
#define MKIII_AX12 //Setup for the PhantomX MKIII AX-12 based hexapod
//#define MKI_AX18 //Setup for the PhantomX MKI symmetric with orientation sensor

Is the MKIII_AX12 correct for the body folks are using or should this be one of the other ones?

Now it looks like these have to be verified for the new leg and the LSS servos as well:

#define ServoRes 4096
#define VoltRef 1014
//MIN MAX control definitions:
#define MaxLegLiftHeight 200
#define MedHighLegLiftHeight 150
#define MedLegLiftHeight 100
#define MinLegLiftHeight 70
#define cTibiaHornOffset1 -295//Need to measure for MX-Phoenix = 295 or 29,5deg//463

Any thoughts?

Next:

#ifdef MKIII_AX12 //Compared to the PhantomX MKI the Tibia must be reversed
#define cRRTibiaInv 0
#define cRMTibiaInv 0
#define cRFTibiaInv 0
#define cLRTibiaInv 1
#define cLMTibiaInv 1
#define cLFTibiaInv 1
#endif

Not sure what this is doing yet have to dig into the code?

#define DEFAULT_GAIT_SPEED 30 // Default gait speed - Will depend on what Servos you are using…
#define DEFAULT_SLOW_GAIT 50 // Had a couple different speeds…

Are these still good for the LSS servos?

//--------------------------------------------------------------------
//[MIN/MAX ANGLES] - Start off assume same as Phoenix…
//Zenta Changes Tibia min/max
//Must calibrate these for MX-Phoenix!

#ifdef MKIII_AX12
#define cXXTibiaMin1 -150
#define cXXTibiaMax1 150
#define cXXFemurMin -100
#define cXXFemurMax 100
#define cXXCoxaMin -75
#define cXXCoxaMax 75
#endif

Again these are going to depend on the body? so back can I assume the body is the same as in the config?

//--------------------------------------------------------------------
//[Joint offsets]
// This allows us to calibrate servos to some fixed position, and then adjust them by moving theim
// one or more servo horn clicks.  This requires us to adjust the value for those servos by 15 degrees
// per click.  This is used with the T-Hex 4DOF legs
//First calibrate the servos in the 0 deg position using the SSC-32 reg offsets, then:
//--------------------------------------------------------------------
//[LEG DIMENSIONS]
//Universal dimensions for each leg in mm
...
#ifdef MKIII_AX12
#define cXXCoxaLength     53
#define cXXFemurLength    66
#define cXXTibiaLength    131
#endif

Guess I have to break out my ruler :slight_smile:

//--------------------------------------------------------------------
//[BODY DIMENSIONS]
...

Again what body do we assume the one already defined?

//--------------------------------------------------------------------
//[START POSITIONS FEET]
....
#ifdef MKIII_AX12
#define cHexInitXZ	 160
#define CHexInitXZCos60  113       // COS(45) = .707
#define CHexInitXZSin60  113    // sin(45) = .707
#define CHexInitY	 25 //30
#define cHexGroundPos 23 //bug bug no sensors used here yet
#endif

Think I know what this means just can’t visualize this yet…

Any help would be appreciated in furthering my understanding of this stuff

Good Morning @cyberpalin

Some of these questions are maybe best answered by @zenta and the like, but will give a stab at them.

Note Some of this is by trial and error.

Some of the PhantomX-3 may be close enough to start, but probably need to be fine tuned.

These may be out of order, but first thinking about leg assembly and servo inversion. If for example you look at some of the hexapods, thought I would show an appropriate one: The Phoenix

image

You will notice that the left legs are different than the right legs, they are mirrored. So on one leg to move the Femur up you turn the servo clockwise and on the other side counterclockwise. Likewise for the Tibia servo. With different versions of the code we did the inversion at different places. Either in main code or in our servo driver. With the LSS servos we have the option now to tell the servos to do it by using the GYRE (G) setting command.

Note: I still need to play more with Zentas sketch on all of the settings. With my earlier test adapting, I have some of the settings from the PhantomX to closer to what the LSS/SES version. Some of the settings may not be needed at all or maybe something different. Like: #define ServoRes 4096
This will be different as units are different and we can now actually tell the servo in 10ths of degree directly, I doubt if we will use the PWM output for position.

Some of the settings for like Min/Max/MED leg lift is something we will want to play with. Some of these we can get some quick and dirty starting points. by first figuring out what is a good starting point. for the legs. and then see how far up we can go from there. MIN may be set to what it takes to get its body off the ground, MID is what we decide is a good walking height.

Note: with some of these they might be dynamic? That is with Phoenix code, I had/have in place the ability to change the fee positions depending on how tall the robot is standing.

I think some of my initial measurements included:

#define cXXCoxaLength     52    // PhantomX leg dimensions.
#define cXXFemurLength    80    // MEASURE THIS!!! Guessed now :-)
#define cXXTibiaLength    100  // MEASURE THIS!!! Guessed now :-)

You will find my first set of guesses in the Hex_Cfg LSS_Phoenix sketch in my test sketches project.

Initial positions: start positions for feet - This is suppose the Hexapod is sitting on the ground, sort of like the Phoenix I showed. Assume the kegs there are in what you want for the initial positions. How far out is the tip of the servo from the rotation point of the coxa. That is the:

#define cHexInitXZ	 160

The angles mentioned are what angles are the different legs from a sort of zero point: with inline hex they are probably all 0, for a round hex they were -60 0 60 degrees, for these they may be closer to 45 degrees…

Again as I mentioned there are a sometimes multiple foot positions defined. That is we have the initial one, which allows the hexapods body to sit on the ground with the tip of legs on the ground. But once it stands up, a more natural walking position is to have the legs closer in to the body, so we shift these in. Not sure how much of this is still in use in Zenta’s version,
I see some parts like:

const byte g_abHexIntXZ[] PROGMEM = {cHexInitXZ, 200};//Different XZ init positions (try 200 as optional for MXPhoenix) this is Kurt's work not entirely sure how it work yet..
const byte g_abHexMaxBodyY[] PROGMEM = { 20, MAX_BODY_Y};

But he may be doing the initial stuff differently. Before this we had robots you needed to setup where the body was sitting on the legs…

Leg me know if this helps and what things I missed…

More coffee :smiley:

2 Likes