Lynxmotion SES V2 Hexapod Robot

Good Morning @cbenson

Wondering if there is any status on the firmware update. Can do limited testing but in the middle of another beta as well another Hexapod project with the @zenta and @kurte Float code that seems to be working.

2 Likes

@cyberpalin Everyone here’s waiting for the update since there are quite a few issues which it can potentially resolved, which explains why the chat’s pretty quiet. Checking to see when the update might be ready and will get back to people here with any news.

1 Like

There’s one final stubborn bug which the firmware developer is working on, which we’d prefer that everyone here not experience. This is causing an unfortunate delay, but rest assured an update will be released as soon as it’s available. Will continue to keep everyone posted here. Really sorry for the inconvenience.

4 Likes

Any update on the new firmware ?

The firmware dev working on it compares it to whackamole: find one bug and another pops up:

image

We’re testing what we receive. Really sorry for the delay and hope you all find the changes well worth the wait :slight_smile:

2 Likes

LOL! typical… where is the fun other wise… :wink:

@madmax @cmackenzie @kurte @xan @zenta @cyberpalin @dickel @geraldinebc15 @scharette @dialfonzo @cbenson

V370 (Experimental)

The long awaited (experimental) v370 firmware update is finally available! You can find details about what’s included in the update here:
Wiki - Version 370 (EXPERIMENTAL)
The LSS-Protocol page on the Lynxmotion Wiki has not been updated since the firmware is still experimental.

The update is available via the LSS Config software (clicking EXP in the firmware window). It should be safe to update the firmware of all servos at the same time (they’ll retain their ID), so after you scan the LSS Bus, be sure to click “LSS-ALL” before clicking the firmware update (otherwise you’ll update the firmware only for the selected servo).

This has been quite a labor of love and hate from our firmware devs, but we hope that the new functionality was well worth the wait. We’ve tested quicker than normal to get it to everyone here so projects can resume, but there may (or rather, will likely be) bugs which are found, but try not to confuse them with “undocumented features” ;o) Should you encounter bugs which can be reproduced, report them here. However, since the focus of this thread is really the SES V2 Hexapod, if the bug troubleshooting gets long, we may push it to a separate thread.

The serial processing has been rewritten from scratch so it’s much more efficient but that’s why we expect some bugs may pop up.

Other robots like the SES V2 humanoid, quadruped are also affected, so those BETA developers will be informed of this update from this post as well. There will be subsequent updates to the firmware (ex. increasing the serial baud rate to 2MB and 3MB), but there needs to be some R&R before resuming FRW development.

5 Likes

Hi @CBenson,

Hopefully over the next few days, I will get a chance to try out the new firmware.

Sounds like your developer(s) have been busy. It will be interesting to see how well this improves some of the IO going to and from the servos.

Sorry I know it is probably just me, but some of the information is not clear to me on how I would use it, in our current hexapod code base. Do you have some example sketches that show how it works.

For example, the release notes talk about group commands, but does not mention at all, how this applies to servo position commands.
That is from the SSC-32 we have: Servo Group Move Example: "#5 P1600 #10 P750 T2500 "
I am assuming from what I read or did not read, that maybe now you can get closer to this, with the new release, obviously changing the P to D, but my guess is that the T2500 would still need to be repeated for each servo?
Will all of the servos tart when the final is sent? Can I delay sending the for 50ms after the rest has been output…

Has anything change on how these commands work? That is if EM=1, it will ramp up, coast, ramp down… So start/stop for each move, which then caused us to go to EM=0
In which case then the other attributes like T250 don’t do anything?

On the Query end: There are many things here that are unclear to me on how this works.
My impression is that when the is received, Each servo will respond in their slot order, that there is no collision detection, but simply a timing offset, where at:
+SLOT*

a servo will respond with it’s response.

So questions that come to mind include: Note: lets assume I setup where slots 1-18 are setup for servo ids 1-18… Not sure about time between responses setting
Unclear from document what is milliseconds (ms) and what is Microseconds (us):
• Servos use a simple formula to delay their response: 200usec + * 120usec, where is their servo ID 0 to 253.
• The first parameter (ex. 120) indicates how many milliseconds to delay between IDs and 120usec is a safe number.
But let’s say 120us for discussion

A) Suppose I do a simple: #18QV - Will this return the data as quickly as possible, or will it delay 200 + 18*120us ? Probably in this case I want as quick as possible
B) If I query 3 servos: #10QD#5QD#0QD\r - Note: I did these in not slot order. Does the items come back in order specified or in slot order?
C) Does #10QD\r#5QD\r#0QD\r – behave differently then B) ?
D) Can I issue other commands while the servos are waiting to send their response… That is suppose on each pass through I wish to query 6 of the servos Temp, but not wait for responses before I issue the next position command?
E) If I query the same servo for multiple things, does it output all of the responses in one slot or does it then wait for the next time slot?

Again sorry, I am just trying to understand how this update applies to the issues we have run into with the current code.

Kurt

1 Like

Appreciate the reply and the questions! It’s completely understandable given the lack of details, so we’ll take a look at each question and write something out in more detail.

@cmackenzie @scharette have also been able to take a look “under the hood” (under NDA), and can likely offer some additional insights.

Here is an example of Query the 18 servos on the Hexapod.

Firmware: 368
Baud rate: 500000
Time: 89.34ms (always possible that multiple servos answer at the same time)

Here is the result

If I zoom on the answers (see how the answers are split)

Using code

  Serial1.print("#1QV\r");
  Serial1.print("#1QT\r");
  Serial1.print("#1QC\r");
  Serial1.print("#1QS\r");
  Serial1.print("#1QP\r");
  delay(5);
  Serial1.print("#2QV\r");
  Serial1.print("#2QT\r");
  Serial1.print("#2QC\r");
  Serial1.print("#2QS\r");
  Serial1.print("#2QP\r");
  delay(5);

And so on for all 18 servos

Firmware: 370 (experimental)
Baud rate: 921600
Time: 20.74ms (and not possibility of errors)

Here is the result

If I zoom on one answer

Using code (I’ve split it into multiple lines to make it easier to read but the \r is at the end of the last)

  Serial1.print("#1QV0QT0QC0QS0QP0");
  Serial1.print("#2QV0QT0QC0QS0QP0");
  Serial1.print("#3QV0QT0QC0QS0QP0");
  Serial1.print("#4QV0QT0QC0QS0QP0");
  Serial1.print("#5QV0QT0QC0QS0QP0");
  Serial1.print("#6QV0QT0QC0QS0QP0");
  Serial1.print("#7QV0QT0QC0QS0QP0");
  Serial1.print("#8QV0QT0QC0QS0QP0");
  Serial1.print("#9QV0QT0QC0QS0QP0");
  Serial1.print("#10QV0QT0QC0QS0QP0");
  Serial1.print("#11QV0QT0QC0QS0QP0");
  Serial1.print("#12QV0QT0QC0QS0QP0");
  Serial1.print("#13QV0QT0QC0QS0QP0");
  Serial1.print("#14QV0QT0QC0QS0QP0");
  Serial1.print("#15QV0QT0QC0QS0QP0");
  Serial1.print("#16QV0QT0QC0QS0QP0");
  Serial1.print("#17QV0QT0QC0QS0QP0");
  Serial1.print("#18QV0QT0QC0QS0QP0\r");

Firmware 370 (experimental)
Baud rate: 921600
Time: 13.99ms

Same thing but using the “Slot” feature by having each servos on a different Slot and using #254 to query

Using code (slot need to be setup once in the Setup)

  // configure the slots
  Serial1.print("#254SLOTCOUNT18\r");
  Serial1.print("#1SLOT0\r");
  Serial1.print("#2SLOT1\r");
  Serial1.print("#3SLOT2\r");
  Serial1.print("#4SLOT3\r");
  Serial1.print("#5SLOT4\r");
  Serial1.print("#6SLOT5\r");
  Serial1.print("#7SLOT6\r");
  Serial1.print("#8SLOT7\r");
  Serial1.print("#9SLOT8\r");
  Serial1.print("#10SLOT9\r");
  Serial1.print("#11SLOT10\r");
  Serial1.print("#12SLOT11\r");
  Serial1.print("#13SLOT12\r");
  Serial1.print("#14SLOT13\r");
  Serial1.print("#15SLOT14\r");
  Serial1.print("#16SLOT15\r");
  Serial1.print("#17SLOT16\r");
  Serial1.print("#18SLOT17\r");
  // main loop - single broadcast command
  Serial1.print("#254QV0QT0QC0QS0QP0\r");

LSS_Query_hack.zip (813 Bytes)

1 Like

Q1) Do you have some example sketches that show how it works.

  • Unfortunately not yet. Looking to have more of a writeup soon, but hopefully dialfonzo’s explanation above helped.

Q2) I am assuming from what I read or did not read, that maybe now you can get closer to this, with the new release, obviously changing the P to D, but my guess is that the T2500 would still need to be repeated for each servo?

  • Yes, for the moment T would be needed for each (more to write out in the command, but desired end effect of moving all servos at the same time).

Q3a) Will all of the servos start when the final is sent?

  • Indeed. That’s the idea.

Q3b) Can I delay sending the for 50ms after the rest has been output.

  • Can you describe a use case?

Q4) Has anything change on how these commands work? That is if EM=1, it will ramp up, coast, ramp down… So start/stop for each move, which then caused us to go to EM=0. In which case then the other attributes like T250 don’t do anything?

  • The motion controller(s) has not changed - the main fix has been a huge decrease in the error rate, increase in baud rate and multiple commands per line.

Q5) My impression is that when the is received, Each servo will respond in their slot order, that there is no collision detection, but simply a timing offset

  • That’s for the responses to queries (to the best of my understanding).

The Original Phoenix code, we would output everything we could before time, and then right at the time we wanted the servos to start reacting, we would send the to say do it now

@dialfonzo - thanks for the sketch… Will play some more with it soon.
Like in your NewFirmware …
What happens in cases like:
// output them by joint types…

void NewFirmware(){
  Serial1.print("#1QV0QT0QC0QS0QP0");
  Serial1.print("#4QV0QT0QC0QS0QP0");
  Serial1.print("#7QV0QT0QC0QS0QP0");
  Serial1.print("#10QV0QT0QC0QS0QP0");
  Serial1.print("#13QV0QT0QC0QS0QP0");
  Serial1.print("#16QV0QT0QC0QS0QP0");

  Serial1.print("#2QV0QT0QC0QS0QP0");
  Serial1.print("#5QV0QT0QC0QS0QP0");
  Serial1.print("#8QV0QT0QC0QS0QP0");
  Serial1.print("#11QV0QT0QC0QS0QP0");
  Serial1.print("#14QV0QT0QC0QS0QP0");
  Serial1.print("#17QV0QT0QC0QS0QP0");

  Serial1.print("#3QV0QT0QC0QS0QP0");
  Serial1.print("#6QV0QT0QC0QS0QP0")
  Serial1.print("#9QV0QT0QC0QS0QP0");
  Serial1.print("#12QV0QT0QC0QS0QP0");
  Serial1.print("#15QV0QT0QC0QS0QP0");
  Serial1.print("#18QV0QT0QC0QS0QP0\r");
}

Or sorry I am lazy, but maybe same query as above, but instead of ordering by servo, I order it by Query…
Sort of like your:

void NewFirmwareSlot(){
  // main loop - single broadcast command
  Serial1.print("#254QV0QT0QC0QS0QP0\r");
}

But I spell out which of the servos I want the data for…
Again more when I get a chance to do more experimenting.

I’m unsure if i understood you right.
The order in which they are query is not important.

Here with your order, I just get the answers in that order:

Thanks,

It was unclear from the descriptions, what things that are influenced or not influenced by setting the slot numbers…

Also unclear, but I can guess, is what happens if I put a CR after each of the lines… That is do I still need to wait until all of the data is returned before issuing a new query or will it know to wait… Before the next logical query starts trying to do an output.

Maybe asked a different way: These examples so far make it look like at least for the Query functions, the Servo Serial port is logically running as Half duplex. That is first the TX line first runs for everything and then the RX line runs for everything, so you are not gaining any time by having the two IO pins. So the question is can the code be arranged, such that I can start issuing a query and have it start responding as fast as it can as to best reduce the overall time it takes for the whole query to complete.

There are two options here:

1 - Group which allows the above, all queries under the same “\r” which gives the output as shown.
2 - Use Slots to kind of reserve a section and do a #254 for all of them at once. (only works with an #254)

Both give similar results and the Slots allows for a slightly shorter answer.

Here I setup servo id’s 1 to 9 for slots 0 to 8 and servos 10 to 18 with slots 12 to 20. This makes a gap of “available slots” in the middle.

Code:

  // configure the slots
  Serial1.print("#254SLOTCOUNT18\r");
  Serial1.print("#1SLOT0\r");
  Serial1.print("#2SLOT1\r");
  Serial1.print("#3SLOT2\r");
  Serial1.print("#4SLOT3\r");
  Serial1.print("#5SLOT4\r");
  Serial1.print("#6SLOT5\r");
  Serial1.print("#7SLOT6\r");
  Serial1.print("#8SLOT7\r");
  Serial1.print("#9SLOT8\r");
  Serial1.print("#10SLOT12\r");
  Serial1.print("#11SLOT13\r");
  Serial1.print("#12SLOT14\r");
  Serial1.print("#13SLOT15\r");
  Serial1.print("#14SLOT16\r");
  Serial1.print("#15SLOT17\r");
  Serial1.print("#16SLOT18\r");
  Serial1.print("#17SLOT19\r");
  Serial1.print("#18SLOT20\r");

If one do a CR after each line, it will be problematic as each servos will answer on the bus just like before.
That’s why the Group make sense.

Example using CR on each lines, I zoomed to see the answers that are corrupted

I got the URDF done for the hexapod. Here’s a video. I setup some ros nodes and python to detect when I saved the URDF file and automatically reload the robot in RViz and sliders to test the joints…very handy.

4 Likes

@cmackenzie Well done! I can imagine your experience with the SES V2 humanoid model and all the work done there will help this advance rapidly.
@madmax Exactly what you’re looking to do correct?

Well done! I can imagine your experience with the SES V2 humanoid model and all the work done there will help this advance rapidly.

Yes, for sure. All the motor control work, all the dynamics stuff. Here is a quick todo list:

  • Update my ros2_controls node to use the latest servo firmware features
  • Robot dynamics node has limb config hard-coded to humanoid so need to read this config from the SDF file which has it. Simple to do, just never needed to before. All the code was written for any number of arms and legs so I don’t anticipate anything more than the startup config change.
  • Write the walking algorithm - fun!
  • Integrate my controller, a Radiolink T8S.
1 Like

Yes correct… I saw this video and immediately contacted @cmackenzie. Its amazing. His knowledge and experience on Ros2 is simply amazing!!

Looks like you are having some good fun with ROS2!

Nice models!