Lynxmotion SES V2 Hexapod Robot

Morning @kurte
Think your explanation is enough to start me off as I set things up. Learned from experience if I don’t ask while I am thinking of it I forget :slight_smile:

So thanks - it does help. Now to finish my coffee.

1 Like

Evening all
Got the parts for the leg assembly today from RobotShop and just finished putting it together. Tomorrow will do the wiring and testing the servos:

Cheers

3 Likes

Dear all…

I got my hex frame and few other bits a couple of days back. A bit of feedback. In some boxes the container for the servo leads is upside down making it a bit tricky to access the leads. I opened up all the servo boxes and saw that there are 2 different flavours of the servo ST1 Seems like a mixed batch ??

The one on the right feels quite substantial and is more sturdy. The one on the left may be plastic but, certainly feels like it weights a bit less…

The hex centre frame needs a bit of sanding if trying to fit on the servo with metal body. It may need an additional 0.1 - 0.2 mm. However, it fits the one with plastic body with ease. Might be worth considering if designing the final ones if the newer servos are all metal body ? Figures below

Finally managed to complete the central portion.

One thing I must say is that with the screw packs the stickers on it have the right amount of adhesive for the tiny screws to stick on to. Pretty useful !!

Then in a few days I got another packet with my brackets. So I started mounting the legs and everything to put this one together. Overall the build took 2-3 hours.

Also, regarding the brackets. I got 2 brackets which are of different form than the rest of the set. Not sure if they are the new designs or old. I prefer the ones on the right aesthetically.



Some images of my WIP assembly. I still have 2 servos remaining which are in transit now…



@cbenson Are these the correct mounting pillars for the breakout boards ? They seem really long, looks like a skyscrapper on the bot. Also, I seem to be missing some screws for the mounting pillars. I have used the 3mm ones for the leg clamp and have left with just 4 screws now. So, I have used only 2 mounting pillars to support the board. I need to get more.
Also, the magnetic clips for holding the servo leads are really nice. However, I fail to understand the use of the magnet there. What is its use ? The magnets don’t cling to the fibreglass or the Aluminium so I did not understand. May be a stupid question…

Also where do the Unthreaded rubber things go ? Couldn’t locate any image with it.

I then tried to play with the shield and the Teensy break out board. Tried to plug in my battery. It was 4s 5000mah. It sparked and kind off smoked the connector. Not sure why that happened with the high discharge battery. I have used this board with a lower discharge rate 3s LiPo and it was all fine.

I checked the board later with another battery and tried to use the configuration tool. However, the tool found just one servo and complained about collision. I guess that is down to all servos having the same id. Do I need to configure each servo separately ? I guess the LSS sketch configures this for each session is that right ?

Next thing would be to load the sketch and use it…

@kurte

If I am not using Xbee and just want to play with your sketch what is the minimum board modifications that I have to do ?
Also, is there any difference between the kitchen sink board and the Teensy breakout that I have ?

@cbenson Do you think it might be worth using post #2 to put in this info and any other such useful info for easy access.

3 Likes

Those are LSS-ST1 in Aluminum body and LSS-HS1 which are still in plastic.
Future production should be all aluminum too but we have less sales on the HS1.

NB: The other testers received the ST1 in plastic since the Aluminum were not released yet when they got their material.

Good point, I’ll have to take a look on that for sure.

Not intentional but funny…!

That’s not normal, how many of those you have ? Those are BETA brackets and i am not sure how it ended up in your box.

This is not a final frame and hardware, we just thrown some standoffs to mount electronics.

You can mount them under the frame with the M3 screw under the servo.

Yes you do, otherwise they all respond to the same ID which is “0” by default

NO - You should not connect a 4S LiPo as it will be above the maximum voltage of the LSS.

1 Like

Since most of the post relates to mechanics which will change, it’s not really relevant to others in the future. Nice complete post though!

Hi @cbenson

Sorry for the misunderstanding. I meant the information regarding the Teensy break out that @kurte may post / have posted for the modifications required to the board

1 Like

@dialfonzo

Only the 2 that I have posted pictures for.

Got you !

Ooh oaky… cool… Also, what about the magnets in the clips what are they used for ?

Okay… don’t want to fry the servos… Will keep that in mind… Will it be better for the LSS adapter board to have a voltage regulator on it to supply constant voltage to the servos bearing in mind the current requirements. On my hexapod I had used…

1 Like

I have played around with a few different boards:

The one that @dialfonzo assembled, started off as simple to assemble board, which uses the LSS adapter board to control the servos and talk to the servos and the like:

The Kitchen Sink, is different in that it does not require the LSS adapter and it has an XBee connector on it, but again in either case you don’t need to use XBees.

Here is the 3d… @cyberpalin beat me to assemble one.
It has it’s own DC/DC converter , lots of IO pins to play with. If you do use XBees it has three LEDS to show RX, TX, and connections. But again I will mostly use USB Host connection. I did still have the parts for 4 3.3v to 5v conversions. The first two are used like the other board for the Servos. Unlike the other board, I don’t need them for XBees as both the T4.1 and XBees run on 3.3v, but I setup optionally to populate the other two to bring out 5v versions of IO ins 24 and 25, which for example could be used for Neopixels or as these pins can be I2C could be used for DotStar, and as these pins are also UART pins I might experiment with RC receiver that does iBus… both have simple sound output and possible to hook up Adafruit/Sparkfun QWIIC devices

1 Like

Would love to be working on this with you guys, but too many other project underway which need my attention.

1 Like

@cyberpalin Keep in mind that the leg design being used is not actually the one shown in the wiki. Use the design (photos) at the top of this post. Since there’s no walking algorithm yet, the zero positions have not yet been determined.

1 Like

Those are cable clips which can be used to attach things with the magnets.
Created for the LSS 4 DoF Arm which do have shells on it. HERE

You can see one use on the mechDOG wiring HERE.

Having a big BEC on the LSS-Adapter would increase it’s size and price.
Usually a 3s LiPo or similar will provide the right voltage.

Found that out last night when I was assembly the leg :). Did exactly as you said, used the photos to assemble in post 2 to assemble the leg. :slight_smile:

Too bad. Think at some point RobotShop may need to update the firmware based on what we find. Believe @kurte mentioned some. Is that a possibility?

If there are issues found with the servo’s communication, our firmware team will certainly investigate and work on it.

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.

Quite a few tests were done before the servos were released, and the suggested baud rate ended up at 115200 with a very low rate of packet loss. You may be encountering the same issues we encountered during testing at higher baud rates.

1 Like

I’ve had some professional & personal delays, but I’m mostly at the end of “catching-up” to things. I should be able to get on with testing this stuff on my end in a few days.

Things noted so far:
a) some query functions error out often screwing up the Serial bus. In particular Serial Number a high percentage of the time.

b) Earlier it was suggested that if you wish to query multiple values from a servo, by writing out your complete set of query functions and then wait for the responses to come back. My simple tests showed that there did not appear to be any speed up at all. It is like for each logical servo cycle, it would output one result at a time.

c) Speed: I assume you are using hardware UART of the STM32 on the servo. So again not sure why you would need to go down to 115200? As mentioned before with old AX12 servos I typically ran at 1MBS. WIth their newer ones ran often at 2MBS, sometimes faster. They have setups that go up to 6…

d) Reliable communications: It might just be me, but I personally believe you need some form of reliable communications. Especially when you have motors and the like running in an electrically noisy setup. Personally I wish you implemented some form of packet setup, with some form of checksum or CRC and optionally some form of ACK/NAK.

Again I understand you like the idea of simple ASCII so one can easily read the stuff. Also I understand your desire for SSC-32 compatibility. That is I can totally understand the goal that you should be able to take an SES V1 design with RC servos and an SSC-32 , swap in the LSS2 servos and a goal that the software should just work. But at a minimum that would have required you to implement the group moves.

And for example with some devices you have that option, like the RoboClaw or XBee or … But with many of these, you then have the option to turn on some form of packets.

Would love to be working on this with you guys, but too many other project underway which need my attention.

Personally I think you do need an SES/LSS Advocate, where one of their primary Job responsibilities is to drive things like this… Probably said enough :wink:

2 Likes

Did something interesting this morning. I used the PEP v2.02 spreadsheet to generate a gait - all I changed were the lengths for the coxa, femur and tibia - I will post something on that config later.

Using the gait angles for the RF I added a gait generator to @kurte’s example sketch and noticed something (note for the session I changed the speed to 30 from 60). For each gait position I did a getPositions for each servo. When I ran it I did not see any noticeable movement of the leg which is kind of confirmed by the dump:
Position 1:
2:-2 1773
4:6 776
6:2 778
Position 2:
2:-2 1739
4:6 750
6:2 755
Position 3:
2:-2 1568
4:6 751
6:2 845
Position 4:
2:-2 1713
4:6 747
6:2 784
Position 5:
2:-2 1743
4:6 782
6:2 779
If I add a 1 second delay between positions:
Position 1:
2:70 1846
4:-303 880
6:-340 886
Position 2:
2:-52 1884
4:9 763
6:107 843
Position 3:
2:-24 1633
4:6 763
6:48 814
Position 4:
2:-2 1716
4:-1 885
6:-1 821
Position 5:
2:35 1733
4:-1 815
6:-42 872

So it looks like between positions will need a query to ensure that the servo is finished moving before the next position.

Guess it would have to be something Query Status and see if its moving and when finished move on?

Good morning @cyberpalin and others

Looks like someone is having some fun!
Is your output in PWM (RC) like servo positions centered at 1500 or in angles (10ths of a degree) Actually looks like maybe both…

There were a couple ways of doing some of this.

That is suppose Servo 2 wants to move from 70 to -52 in 100ms (Or what the step time is).
And so you output something like: #2D-52T100\r
Which hopefully will start moving that servo to that position and should arrive at that position in specific time.

However if you output a new command, it will override that…

Two ways we handled this. We detected that the servo made it to it’s position.

Do some form of Query. On SSC-32 this was the Q command… Which returned something like a . when done and something like a + if the last. With the LSS we do still have the Q command, which returns a byte showing different status.

Note: with the SSC-32 we only needed to talk to the SSC-32 as it controlled the servos, here we would maybe have to ask all of the servos are you done yet…

When we went with this approach (again only one Serial command: Probably just Q\r and one byte back, we found that the servo movements were not fluid but sort of jerky as each servo would start and stop, and then you had to wait for a full Query to complete, before you would start them to their next position.

So we went to our own timed output code. That is if I say that the move is supposed to last 100ms, I will output the next command 100ms from the time I started this move. We also worked to make this time as accurate as possible, as the SSC-32 would not execute the data, until it received the CR. So earlier we output everything but the CR and when that time came we output the final CR to start the next move.

However on Dynamixels, I think the code outputs the whole Group move command at the specified time. But the timing was reasonably the same, as we always output the exact same number of bytes per step.
Which usually worked reasonably well when run from Microcontroller. At times though I have seen issues when run through something like RPI, especially through USB, where the timing may be different when the RPI may be doing something else.

Side comment: So at one point, I had made a version of the firmware for the USB2AX device, which allowed me to say here is the next group move command to execute when you finish the previous one. Which removed the USB latency issues. Edit: I believe I also had code like this in my RPI port that used a Teensy to control the servos

My strong guess is that is what we will probably want to do the walking stuff using our own timing code as well. Unless again the LSS has the ability to say here is your next move…

Hope some of this makes sense

1 Like

Yes having some fun, I think :slight_smile:

Anyways. I am using your test sketch and added a ‘g’ command for generate gait. Then in that function I am using the move command to move it to the set angle:
myLSS.move(-48);
Think thats right for the angles if I read your setServoPosition correctly. Who knows with me.

To your other comment about

Do some form of Query. On SSC-32 this was the Q command… Which returned something like a . when done and something like a + if the last. With the LSS we do still have the Q command, which returns a byte showing different status.
I added an additional function called checkStatus to see if all 3 servos got to their hold position:
void checkStatus()
{
int8_t status1 = -1, status2 = -1, status3 = -1;
uint32_t statusTime = 0;
while(status1 != 6 || status2 != 6 || status3 != 6) {
status1 = myLSS.getStatus();
myLSS.setServoID(RF_COXA);
status2 = myLSS.getStatus();
myLSS.setServoID(RF_COXA);
status3 = myLSS.getStatus();
delay(1);
statusTime += 1;
}
Serial.printf(“Status: %d: %d, %d, %d\n”, statusTime, status1, status2, status3);
}

Did add the print loop time - think max time was 103ms in one case. Here is a little table I put together:

The first column is me typing in the angles manually.

Oh just for completeness here is my gait function (started out as a hack - guess should clean it up )
void generateGait()
{
for(int i=0; i < 5; i++) {
//Start position 1 - start position
// -4.8, 1.1, 11 degrees
myLSS.setServoID(RF_COXA);
myLSS.move(-48);
myLSS.setServoID(RF_FEMUR);
myLSS.move(11);
myLSS.setServoID(RF_TIBIA);
myLSS.move(110);
myLSS.setServoID(RF_COXA);

  Serial.println("Position 1: ");
  checkStatus();
  GetServoPositions();

	//position2
	//-2.6, 0.3, 5.1
	myLSS.setServoID(RF_COXA);
	myLSS.move(-26);
	myLSS.setServoID(RF_FEMUR);
	myLSS.move(3);
	myLSS.setServoID(RF_TIBIA);
	myLSS.move(51);

  Serial.println("Position 2: ");
  checkStatus();
  GetServoPositions();

	//position3
	// 0, 0, 0
	myLSS.setServoID(RF_COXA);
	myLSS.move(0);
	myLSS.setServoID(RF_FEMUR);
	myLSS.move(0);
	myLSS.setServoID(RF_TIBIA);
	myLSS.move(0);

  Serial.println("Position 3: ");
  checkStatus();
  GetServoPositions();

	//position4
	// 3.1, 0.3, -4.4
	myLSS.setServoID(RF_COXA);
	myLSS.move(31);
	myLSS.setServoID(RF_FEMUR);
	myLSS.move(3);
	myLSS.setServoID(RF_TIBIA);
	myLSS.move(-44);

Serial.println("Position 4: ");
checkStatus();
GetServoPositions();

	//position5 - end position
	// 6.7, 1, -8.2
	myLSS.setServoID(RF_COXA);
	myLSS.move(67);
	myLSS.setServoID(RF_FEMUR);
	myLSS.move(10);
	myLSS.setServoID(RF_TIBIA);
	myLSS.move(-82);

  Serial.println("Position 5: ");
  checkStatus();
  GetServoPositions();
}
	//leg up start position
	//6.7, -31.2, -34.3
	myLSS.setServoID(RF_COXA);
	myLSS.move(67);
	myLSS.setServoID(RF_FEMUR);
	myLSS.move(-312);
	myLSS.setServoID(RF_TIBIA);
	myLSS.move(343);

  Serial.println("Position Start Leg Up: ");
  checkStatus();
  GetServoPositions();

}
1 Like

@cyberpalin - Another quick update:
I hacked up my test program, to do a “Q” command
that timed how long it would take to do a Q command to all of the servos (Pushed up the change)

void QueryAllServos() {
  LSS_Status servo_status[MAX_SERVO_NUM];
  uint32_t query_time[MAX_SERVO_NUM];

  if (!g_count_servos_found) {
    Serial.println("Previous Find Servos failed to locate any servos: so retry");
    FindServos();
    return;
  }

  Serial.print("\nDo Query(Q) command on all servos ");
  elapsedMicros emTotal = 0;
  for (int i = 0; i < g_count_servos_found; i++) {
    elapsedMicros em = 0;
    myLSS.setServoID(g_ids[i]);
    servo_status[i] = myLSS.getStatus();
    query_time[i] = em;
  }
  Serial.printf("total time: %u\n", (uint32_t)emTotal);
  for (int i = 0; i < g_count_servos_found; i++) {
    Serial.printf("  %u: %u T:%u\n", g_ids[i], servo_status[i], query_time[i]);
  }
}

With all of the servos at default limp state:

Do Query(Q) command on all servos total time: 113096
  1: 1 T:959
  2: 1 T:682
  3: 1 T:674
  4: 1 T:647
  5: 1 T:650
  6: 1 T:676
  7: 1 T:684
  8: 0 T:100650
  9: 1 T:687
  10: 1 T:792
  11: 1 T:759
  12: 1 T:727
  13: 1 T:742
  14: 1 T:741
  15: 1 T:768
  16: 1 T:740
  17: 1 T:768
  18: 1 T:750

Looks like one servo failed and took over second.

I then used command to center all of the servos. and checked their status and their positions:

Cmd: q

Do Query(Q) command on all servos total time: 12717
  1: 6 T:676
  2: 6 T:667
  3: 6 T:646
  4: 6 T:679
  5: 6 T:663
  6: 6 T:649
  7: 6 T:659
  8: 6 T:673
  9: 6 T:687
  10: 6 T:761
  11: 6 T:731
  12: 6 T:746
  13: 6 T:757
  14: 6 T:751
  15: 6 T:732
  16: 6 T:749
  17: 6 T:734
  18: 6 T:755
...
Cmd: 4
1:2 754
2:3 746
3:-3 786
4:1 751
5:4 750
6:4 775
7:0 876
8:5 841
9:-3 830
10:-9 913
11:6 842
12:5 842
13:0 833
14:0 1178
15:6 843
16:1 854
17:4 843
18:-3 929

So in this case it took like 12ms to just find the status. Note: I am running at baud 250000

Looks like you posed message… So hopefully not too much of a cross post