Lynxmotion SES V2 Hexapod Robot

I figure a future group move would need to have all servos to have a way of starting at the same time. Thinking of the current control loop, they may all be off of each other by ±1-2 ms.

Sounds good.

Yes that can help especially when you are talking about 18+ servos.

And side note: this can really be amplified when USB is involved. That is if for example you are outputting on average of say 12 characters per servo and 18 servos, you are transferring maybe: 216 characters, which for many USB devices like most FTDI most Arduinos and Teensies up to T4, this will require 4 USB packets to be sent (64 bytes)… With T4.x we now can have USB transfers of 512…

But in the simple test case I was only sending to one servo.

Found one of the batteries that would charge some. Probably not much, but was able to power SSC-32u with it. So plugged it into T4.1 using USB… This way did not have to worry about converting the UARTS 5v on SSC-32 to Teensy 4.1 which is not 5v…

Also found the one 645mg I had bouncing around lose in box… Also did not work (will be in trash soon), so stole a HS0475HB off of a foot of a Brat:


Which had a prototype Botboarduino board in it…

Anyway I updated the sketch to run both. I did not worry too much about exactly mapping angles, but just did a map function from a angle range to a pulse range.

I again pushed up the changes

#include <LSS.h>
// ID set to default LSS ID = 0
#define LSS_ID		(0)
#define LSS_BAUD	(LSS_DefaultBaud)
#define SERVO_MAX 1800
#define SERVO_MIN -1800
#define NUMBER_STEPS 36
#define DELTA_PER_MOVE ((SERVO_MAX - SERVO_MIN)/ NUMBER_STEPS)
#define TIME_PER_STEP (4000/NUMBER_STEPS)

#define USE_USB_RC_SERVOS
#define RC_SERVO_MIN 600
#define RC_SERVO_MAX 2400

// Choose the proper serial port for your platform
//#define LSS_SERIAL	(Serial)	// ex: Many Arduino boards
#define LSS_SERIAL	(Serial1)	// ex: Teensy

#if defined( USE_USB_RC_SERVOS)
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
#include "USBHost_t36.h"
#define USBBAUD 115200
uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBSerial userial(myusb);  // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
bool userial_prev = false;
#else
#undef USE_USB_RC_SERVOS
#endif
#endif


LSS myLSS = LSS(LSS_ID);
void setup()
{
  while (!Serial && millis() < 5000) ;
  Serial.println("Servo continuous time moves test");
  Serial.println("Press any key to pause test");
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
  myusb.begin();
#endif

  // Initialize the LSS bus
  LSS::initBus(LSS_SERIAL, LSS_BAUD);

  // Initialize LSS to position 0.0 °
  myLSS.move(SERVO_MIN);

  // Wait for it to get there
  delay(2000);
}

void pause_test() {
  if (Serial.available()) {
    Serial.println("Test Paused, press any key to continue");
    while (Serial.read() != -1) ;
    while (Serial.read() == -1) ;
    while (Serial.read() != -1) ;
  }
}

void moveTSSC32(uint8_t servo, int pos, uint32_t time) {
#if defined(USE_USB_RC_SERVOS)
  int pos_pulse = map(pos, SERVO_MIN, SERVO_MAX, RC_SERVO_MIN, RC_SERVO_MAX);
  userial.printf("#%uP%uT%u\r\n", servo, pos_pulse, time);
  userial.flush();
#endif
}

void loop()
{
#if defined(USE_USB_RC_SERVOS)
  myusb.Task();
  if (userial && !userial_prev) {
    userial_prev = true;
    userial.begin(115200);
    Serial.println("USB Serial connected");
    moveTSSC32(0, SERVO_MIN, 2000);
    delay(2000);
  }
#endif
  for (int servo_pos = SERVO_MIN; servo_pos < SERVO_MAX; servo_pos += DELTA_PER_MOVE) {
    pause_test();
    myLSS.moveT(servo_pos, TIME_PER_STEP);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
  for (int servo_pos = SERVO_MAX; servo_pos > SERVO_MIN; servo_pos -= DELTA_PER_MOVE) {
    pause_test();
    myLSS.moveT(servo_pos, TIME_PER_STEP);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
}

@kurte
As a FYI I finally figured out the issue I was having with getting my mods to compile. Simple fix. So got the leg to go up and down no problem. Pushed the changes to the repository: mjs513/LSS_Phoenix_BT (github.com)

Still have debugging to do with the PS4 controller to imitate the DIY commander basic functions and get the display tied in.

Cheers

@cyberpalin Sounds great and fun!

I synced up and still having build issue. I think I know what is going on. Probably the main ino not naming some objects
and/or maybe differences i code.

Like several error messages with `g_InputController not defined…

Probably will continue this in other channels.

Yeah - just realized I uploaded the wrong sketch that why it worked.

Only error I am getting is all associated with g_InputController not defined! and not sure why :frowning:

My guess is that you picked up my version from the SES-V2-Hexapod-Beta\kurte\Zenta_LSS-Phoenix_Phantomx…

I was trying to clean out lots of global like this. So instead of global. The InputController class as a static variable and a static inline method to get the current InputController.

Dito for servo class. I was trying to split out each controller to their own files and classes.

And the main line has

void SketchSetup() {
  //g_InputController = &commander;
  InputController::controller(usbControl);
  ServoDriver::driver(dxlServo);

}

to set it. But I was thinking about changing them to have their constructors set the current one…

Yep thats what I did.

Even if I comment out that g_inputController line its has issues and not sure how to fix it? Well - I do know of a workaround especially since I ditch all the code associated with Dyanmixel anyway which was giving me other problems :slight_smile:

Dont even know if the servo class works since I cant get that far - my guess is not for the same reasons? Dont know maybe will just toss it and wait.

EDIT: What base lib should I be working from if I want to do this.

I pushed up a change to you, that I believe builds now.

Hi All
Need recommendations on some setup numbers for @zenta 's sketch in @kurte repository:
//MIN MAX control definitions:
#define MaxLegLiftHeight 200
#define MedHighLegLiftHeight 150
#define MedLegLiftHeight 100
#define MinLegLiftHeight 70

#define cRRCoxaAngle   -56   //Default Coxa setup angle, 34.280877 degs from center line? atan-1(60.6/88.9)
#define cRMCoxaAngle    0      //Default Coxa setup angle
#define cRFCoxaAngle    56      //Default Coxa setup angle
#define cLRCoxaAngle    -56   //Default Coxa setup angle
#define cLMCoxaAngle    0      //Default Coxa setup angle
#define cLFCoxaAngle    56     //Default Coxa setup angle

#define cHexInitXZ   131
#define CHexInitXZCos60  73    // COS(56) = .707
#define CHexInitXZSin60  109    // sin(56) = .707
#define CHexInitY  116 //30
#define cHexGroundPos 25

Opinions?

1 Like

@kurte
I have tried to run your code and dig into it to understand how it was setup.
Seems like you are only sending new commands at 111ms which will produce the “glitchy” effect because in motion control (EM = 1) mode the servo try to Accelerate & Decelerate in that time period. So it ramp down then ramp up in between position updates.

I suggest doing an update rate which is steady like every 25ms and spread the movement over that to get the right Timing. (if that make sense)
I’ve tried with EM disabled (EM = 0) and a faster update and it’s really smooth.

2 Likes

Thanks @dialfonzo, as you can guess this is not a real normal program. But is just a simple test to see how the servo movements compare versus simple RC servos using SSC-32. My expectations when I see they both speak the same language is I would get a very close movements between the two, which looks like by default not to be the case.

Thanks for mentioning the EM=0.

Actually yesterday I updated that simple test case to alternate for one sweep with it on and one with it off. The program is up on my LSS_Test… github project.
Which looks like:

#include <LSS.h>
// ID set to default LSS ID = 0
#define LSS_ID		(0)
#define LSS_BAUD	(LSS_DefaultBaud)
#define SERVO_MAX 1800
#define SERVO_MIN -1800
#define NUMBER_STEPS 36
#define DELTA_PER_MOVE ((SERVO_MAX - SERVO_MIN)/ NUMBER_STEPS)
#define TIME_PER_STEP (4000/NUMBER_STEPS)

#define USE_USB_RC_SERVOS
#define RC_SERVO_MIN 600
#define RC_SERVO_MAX 2400

// Choose the proper serial port for your platform
//#define LSS_SERIAL	(Serial)	// ex: Many Arduino boards
#define LSS_SERIAL	(Serial1)	// ex: Teensy

#if defined( USE_USB_RC_SERVOS)
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
#include "USBHost_t36.h"
#define USBBAUD 115200
uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBSerial userial(myusb);  // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
bool userial_prev = false;
bool use_em_control = false;
#else
#undef USE_USB_RC_SERVOS
#endif
#endif


LSS myLSS = LSS(LSS_ID);
void setup()
{
  while (!Serial && millis() < 5000) ;
  Serial.println("Servo continuous time moves test");
  Serial.println("Press any key to pause test");
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
  myusb.begin();
#endif

  // Initialize the LSS bus
  LSS::initBus(LSS_SERIAL, LSS_BAUD);

  // Initialize LSS to position 0.0 °
  myLSS.move(SERVO_MIN);

  // Wait for it to get there
  delay(2000);
}

void pause_test() {
  if (Serial.available()) {
    Serial.println("Test Paused, press any key to continue");
    while (Serial.read() != -1) ;
    while (Serial.read() == -1) ;
    while (Serial.read() != -1) ;
  }
}

void moveTSSC32(uint8_t servo, int pos, uint32_t time) {
#if defined(USE_USB_RC_SERVOS)
  int pos_pulse = map(pos, SERVO_MIN, SERVO_MAX, RC_SERVO_MIN, RC_SERVO_MAX);
  userial.printf("#%uP%uT%u\r\n", servo, pos_pulse, time);
  userial.flush();
#endif
}

void loop()
{
  // Play turning on and off em control
  use_em_control = !use_em_control;
  myLSS.setMotionControlEnabled(use_em_control ? 1 : 0);
  Serial.println(use_em_control ? "Using EM Control"
                 : "Not using EM Control");
#if defined(USE_USB_RC_SERVOS)
  myusb.Task();
  if (userial && !userial_prev) {
    userial_prev = true;
    userial.begin(115200);
    Serial.println("USB Serial connected");
    moveTSSC32(0, SERVO_MIN, 2000);
    delay(2000);
  }
#endif
  for (int servo_pos = SERVO_MIN; servo_pos < SERVO_MAX; servo_pos += DELTA_PER_MOVE) {
    pause_test();
    myLSS.moveT(servo_pos, TIME_PER_STEP);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
  for (int servo_pos = SERVO_MAX; servo_pos > SERVO_MIN; servo_pos -= DELTA_PER_MOVE) {
    pause_test();
    myLSS.moveT(servo_pos, TIME_PER_STEP);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
}

The program should work with the T4.1 board with an SSC-32u plugged into it’s USB host port… Could just as easily make it work with Arduino Mega where you use the TTL connections on a hardware serial port. I did not do that with T4.1 as 3.3v vs 5v.

If you run it you will observe that as you mentioned the EM=0 works better through the range, but during the main parts of the movements the EM=1 felt smoother… The problem is I have no idea how to combine.

And again this is not the real movements. But quick and dirty test. Would then be good to build up with 3 servos on both sides. i.e. a leg and have the movements for a step that repeats and see how the two legs respond.

Note: this type of test is something I would normally try to do. For example I did something similar when I was asked about playing with a Trossen Robotics PhantomX built with XL430_w250 servos versus AX servos. Yes both Dynamixels, but one was controlled by AVR chip other STM. One used Protocol 1 other Protocol 2. Different registers sets, like target register was now 4 bytes instead of 2. Positions covered 360 degrees versus 300…

So I did test where I actually built the code, such that I could mix and match legs built with the two different servos and made sure they walked the same. …

Which led me to this test and asking the questions if you already had similar setup.

Glad you are playing :smiley: Let me know what you think of the newer version of the test.

More later but need to do some other diversions.

I’ll say it again, but not being a programmer, I am overwhelmed easily when I try codes.
However I did quite a lot of tests using Arduino and simple programs to get smooth movement with the LSSs.

Just loaded your test program and understand it a bit more by looking at the code.

What i found is in either situation you are sending a “T” movement which mean the servo do not run in EM0 even so you are disabling it. On that i would say that I am unsure why we have a different behavior with and without EM with the “T” parameter sent.

Also, to get a smooth movement in EM0 you might need more than a 111.11ms update rate.

EM - Some things to know

Commands like “T” are only available in EM1 mode, in EM0 there are not motion control so no relation in Time. The servo will try to go as fast as possible to the desired position but still take the stiffness’s in consideration.

In EM0 there is a FPC (Filter Position Count) parameter that can be adjusted to smooth the movement.

That FPC need to be set for a particular update rate of the servo position. If you change that rate, you need to re-adjust the FPC for smooth motion.

Here is a test which is smoot on my side:

#include <LSS.h>
#define LSS_ID    (0)
#define LSS_BAUD  (LSS_DefaultBaud)
#define LSS_SERIAL  (Serial1) // ex: Many Arduino boards

#define SERVO_MAX 1800
#define SERVO_MIN -1800
#define NUMBER_STEPS 36
#define DELTA_PER_MOVE 10

int previousMillisServo = 0;
int pos = 0;  
long servoInterval = 25;
unsigned long currentMillis = 0;

LSS myLSS = LSS(LSS_ID);

void setup() {
  LSS::initBus(LSS_SERIAL, LSS_BAUD);
  delay(2000);
  myLSS.setMotionControlEnabled(0);
  myLSS.setAngularHoldingStiffness(-4);
  myLSS.moveT(-1800, 500);
  delay(2000);
}

void loop() {
  currentMillis = millis();
  servoSweep();  
}

void servoSweep() {
  for (pos = SERVO_MIN; pos < SERVO_MAX; pos += DELTA_PER_MOVE) {  
    Serial.println(pos);
    myLSS.move(pos);           
    previousMillisServo = millis();
    while ((millis() - previousMillisServo) < servoInterval) ;
  }

  for (pos = SERVO_MAX; pos > SERVO_MIN; pos -= DELTA_PER_MOVE) {               
    Serial.println(pos);
    myLSS.move(pos); 
    previousMillisServo = millis();
    while ((millis() - previousMillisServo) < servoInterval) ;
  }
}
2 Likes

Here is a video of the LSS vs SSC32U + HS-422 with the following code running.

Note: i forced the LSS in EM0 in the LSS-Config before and removed the “T” move.

#include <LSS.h>
// ID set to default LSS ID = 0
#define LSS_ID    (0)
#define LSS_BAUD  (LSS_DefaultBaud)
#define SERVO_MAX 900
#define SERVO_MIN -900
#define NUMBER_STEPS 36
#define DELTA_PER_MOVE 10 //((SERVO_MAX - SERVO_MIN)/ NUMBER_STEPS)
#define TIME_PER_STEP 25 //(4000/NUMBER_STEPS)

#define USE_USB_RC_SERVOS
#define RC_SERVO_MIN 600
#define RC_SERVO_MAX 2400

// Choose the proper serial port for your platform
//#define LSS_SERIAL  (Serial)  // ex: Many Arduino boards
#define LSS_SERIAL  (Serial1) // ex: Teensy

#if defined( USE_USB_RC_SERVOS)
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
#include "USBHost_t36.h"
#define USBBAUD 115200
uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;
USBHost myusb;
USBHub hub1(myusb);
USBHub hub2(myusb);
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBSerial userial(myusb);  // works only for those Serial devices who transfer <=64 bytes (like T3.x, FTDI...)
bool userial_prev = false;
bool use_em_control = false;
#else
#undef USE_USB_RC_SERVOS
#endif
#endif


LSS myLSS = LSS(LSS_ID);
void setup()
{
  while (!Serial && millis() < 5000) ;
  Serial.println("Servo continuous time moves test");
  Serial.println("Press any key to pause test");
#if defined(ARDUINO_TEENSY36) || defined(__IMXRT1062__)
  myusb.begin();
#endif

  // Initialize the LSS bus
  LSS::initBus(LSS_SERIAL, LSS_BAUD);

  // Initialize LSS to position 0.0 °
  myLSS.move(SERVO_MIN);

  // Wait for it to get there
  delay(2000);
}

void pause_test() {
  if (Serial.available()) {
    Serial.println("Test Paused, press any key to continue");
    while (Serial.read() != -1) ;
    while (Serial.read() == -1) ;
    while (Serial.read() != -1) ;
  }
}

void moveTSSC32(uint8_t servo, int pos, uint32_t time) {
#if defined(USE_USB_RC_SERVOS)
  int pos_pulse = map(pos, SERVO_MIN, SERVO_MAX, RC_SERVO_MIN, RC_SERVO_MAX);
  userial.printf("#%uP%uT%u\r\n", servo, pos_pulse, time);
  userial.flush();
#endif
}

void loop()
{
  // Play turning on and off em control
//  use_em_control = !use_em_control;
//  myLSS.setMotionControlEnabled(use_em_control ? 1 : 0);
//  Serial.println(use_em_control ? "Using EM Control"
//                 : "Not using EM Control");

#if defined(USE_USB_RC_SERVOS)
  myusb.Task();
  if (userial && !userial_prev) {
    userial_prev = true;
    userial.begin(115200);
    Serial.println("USB Serial connected");
    moveTSSC32(0, SERVO_MIN, 2000);
    delay(2000);
  }
#endif
  for (int servo_pos = SERVO_MIN; servo_pos < SERVO_MAX; servo_pos += DELTA_PER_MOVE) {
    pause_test();
    myLSS.move(servo_pos);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
  for (int servo_pos = SERVO_MAX; servo_pos > SERVO_MIN; servo_pos -= DELTA_PER_MOVE) {
    pause_test();
    myLSS.move(servo_pos);
    moveTSSC32(0, servo_pos, TIME_PER_STEP);
    delay(TIME_PER_STEP);
  }
}
1 Like

@dialfonzon - ok that clears some of it up - I think - have to reread this a few times.

So, moveT is only available when EM is set to 1. So if you do that and set the maxSpeed to 1800 (180deg/sec) I think I read that correctly, what would you recommend for a realistic servo move time? Know this is probably a loaded question I kind of what to test a situation like this with 3 servos in the leg configuration.

Thanks @dialfonzo and @cbenson

But now I am sort of confused on how to use your servos.

Background stuff: probably can be ignored
Disregarding how it is coded, the basics of what the walking code is trying do… example for a leg, suppose a leg is to be lifted moved forward, and lowered and when it hits the ground it pulls the body up by the stride length. Now suppose that the the leg up and down could be in the air a set of points or some curve maybe like a sin wave on the ground flat, but all three servos are still moving as each angle changes as you pull forward…

A lot of the code is setup to do this, where me may break this movement up into N pieces, where then for each step we compute where the tip of the leg should be in 3d space and then we compute the desired angle for each servo and then for each of these output that in the appropriate units for that servo.

I have played with a few different drivers for different servos, where we may do this last part in slightly different ways.

a) SSC=32: we do as I show and output one group move for all 18 servos with the T modifier. And we time when to finish outputting the next step. We actually have the timing setup to as accurate as possible and output everything up to the trailing cr ahead of time and then output the CR at that moment.

b) other RC servos: using something like Servo library (or on teensy can use PWMServo library. I actually had a version ServoEX where I built in the SSC=32 logic into it and the code incremented or decremented the pulse for each servo cycle…

c) Dynamixels who had limited timing control (i.e. AX) We did our own interpolation of movements and output a lot of positions per second… Again using their Group Write instructions, where all of the servos waited for a proper checksum (or CrC) before responding.

d) Smarter Dynamixels: With these again use Group Writes, but in addition we output the move speed, which we computed. Which is not hard (delta change / change time_…

Background off and Back to main confusion:

Unclear to me when you would use EM1 and when you would be EM0.
Also confused from your statement:

I did not get the impression from your wiki that the T modifier usage was dependent on the EM state…

Timed move can be used only as a modifier for a position (P, D, MD) actions. The units are in milliseconds, so a timed move of 2500 milliseconds would cause the servo to rotate from its current position to the desired position in 2.5 seconds. The onboard controller will attempt to ensure that the move is performed entirely at the desired velocity, though differences in torque may cause it to not be exact. This command is in place to ensure backwards compatibility with the SSC-32 / 32U protocol.

My understanding (please correct me if I am not properly understanding) of EM=1 is that it ramps up the speed, travels at some speed, and when it gets close to the target, it ramps down the speed. Which can be very nice for isolated moves.

But not sure how that can be used in movements like we are doing? Where we are not wanting to stop between moves but simply changing where our end point is and how fast to go. Now if instead this was implemented sort of like an autopilot in a boat, where you set waypoints, where the boat aims toward and when it gets near that point it can adjust the boats settings to start toward the next location with the right direction and speed…
But so far I don’t see anyway to tell a servo, my next position will be… But first finish your current stuff…

So my guess is that instead we need to use EM=0. Which as you said is smoother and is smoother with faster frame rates. I also understand the stiffness sort of maybe like the AX servos Compliance Margins (how close does it have to be to say it is at the position…

Again sorry my confusion here Like: the wiki says both the Speed and Time modifiers are backwards compatibility with the SSC-32, which sort of implies there is a better approach we should be doing.

But suppose that with the hexapod we want all 18 servos to move through 20 sub-steps per step. Where we want at each sub step all of the servos to be at specific locations at the specified times and that they should continue on to the next positions again to arrive at the prescribed time?

Another fun usage case, is imagine trying to build this kickstarter 3D printer (which I pledged to):
https://www.kickstarter.com/projects/plybot/plybot/description
I thought it was an interesting design and my other 3D printer kickstarter will never ship. I expect I will receive this one in the next few months.

This one is built sort of like two arms which both hands holding the 3d nozzle. Now you need to coordinate the servos of both arms to move in a very coordinated way such that they are not fighting with each other. You also need the nozzle to move in a very smooth even speed…

So again what approach would be suggested to do this?

Again sorry I know that some of this is my confusion and making wrong assumptions.

My assumption was that if the command set was designed to emulate the SSC=32 commands. Then by default the servos would behave in a similar way to servos that were connected to an SsC-32. Hopefully it may just require the simple changes like turn off the EM…

Kurt

1 Like

@kurte - @dialfonzo
Just did a quick test using the LSS_Test_Servos sketch where we tested several stance positions (close to what showed in the picture for low/med/high stances). Set servo configs for
myLSS.setMotionControlEnabled(0);
myLSS.setAngularHoldingStiffness(-4);
Just copied what you had. And then changed the moveT’s to move command in order to see if we were still getting move errors when we checked status. I also changed the servo speed from 600 to 1800. Since I was using maxSpeed(x).

Results after all that build up was no errors when I cycled the stance.
Cmd: i
Checks Status wait loops 1 in us: 2976
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(-900, 0, -897) T:6(-600, 0, -592)
Checks Status wait loops 1 in us: 3716
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(0, 0, -897) T:6(0, 0, -592)
Checks Status wait loops 1 in us: 2970
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(450, 0, -12) T:6(450, 0, -4)
Checks Status wait loops 1 in us: 2871
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(0, 0, 437) T:6(0, 0, 441)
Checks Status wait loops 1 in us: 3081
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(-900, 0, 7) T:6(-600, 0, 8)

where as before we would be getting position errors. If I run the same test at 600 same results:
Checks Status wait loops 1 in us: 3020
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(-900, 0, -9) T:6(-600, 0, -1)
Checks Status wait loops 1 in us: 3056
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(0, 0, -888) T:6(0, 0, -585)
Checks Status wait loops 1 in us: 2876
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(450, 0, -11) T:6(450, 0, -6)
Checks Status wait loops 1 in us: 2885
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(0, 0, 437) T:6(0, 0, 443)
Checks Status wait loops 1 in us: 2963
Print Servo Positions Joint(Goal, timed, end)
C:2(0, 0, 1) F:4(-900, 0, 7) T:6(-600, 0, 8)
This is just a quick and dirty - didn’t see any jerkiness.

2 Likes

Thanks for your effort @kurte.
The servos are connected to the LSS Board and I’m using a 6Amp 12v powersupply. I’ve also tried a battery.

I added the serial prints and flush code. And the code halts at the same place as before.
It does not print the line “After get Position…” in the FindServos function.
Looks like it halt when performing the first loop of the for function.

I’m puzzled…

// Initialize to no servos…
for (int i = 0; i < MAX_SERVO_NUM; i++) {
myLSS.setServoID(i);
pos = myLSS.getPosition();

Hello @zenta,

Not sure what is going on. I also don’t remember what other goodies you have or don’t have… Like Logic Analyzer or Scope or…

But here is some of the steps I would try.
a) I would double check what all you are building with. That is if me, would maybe verify I am running the Arduino 15 and the latest Teensyduino. And most important make sure you are running the up to date version of the LSS library. That is either the version I put up on the private beta, but then after that they integrated the changes into the official sources (pulled in my Pull request) and did a release… Anyway I would double check that is what I was running.

a1) Make sure that the switch on the Shield is set to the Arduino setting (center) Also that the program is configured to run at same baud rate as you have servos configured to.

b) unplug all of the servos. Does the program make it through the init stuff? If not ???

c) Unplug the shield, set to USB and plug into USB and see if their LSS app sees all of the servos and they all have unique settings.

d) I actually would probably do this earlier. Connect up Logic analyzer to RX and TX pin and see if I am getting any communications through. i.e. do you see the #0Q… show up… Is anything coming back from Servo? …

If none of these work, I would then be tempted to hack up a quick and dirty setup where you jumper TX, RX pins (0, 1) of teensy to a Sparkfun level shifter, and from shifter to shield and see if that works…

Again hard to guess more steps yet.

2 Likes

Hi @zenta
One question - are you using @kurte lastest LSS_Test_servo sketch. He added some code that if servos are not found it lets you know and identifies it as failed. At then end tells you whats missing. Maybe a sketch update would help. Just guessing at this point.

Also probably would just check with 1 servo attached as a quick and dirty as well.

1 Like

I am going to drop that here …
LSS-EM0-Spoof.zip (1.6 KB)

An arduino sketch that was made to spread a movement into sub-angles in order to have a Timed move in EM0.
I know that there is a math error somewhere and I’m not the one who coded it. At the start and end the calculation is wrong and the step is too high and it’s worst if you decrease the rate at which the values are sent.

Not sure if you guys can spot and fix the issue.

It was used for a promotional video:

2 Likes