I wrote some simple Arduino test code for the LSS (pseudo code below):
during Setup:
myLSS.setAngularStiffness(0); //The following block was obtained from another forum post
myLSS.setAngularHoldingStiffness(0);
myLSS.setMaxSpeed(180); //isn't the maximum supposed to be 72 RPM for the HS1?
myLSS.setAngularAcceleration(1000); //maximum is actually 100 but behaviour is the same
myLSS.setAngularDeceleration(1000);
myLSS.setMotionControlEnabled(false); //increase acceleration and disable motion control
myLSS.move(0); //move to 0 position
during Loop:
if (myLSS.getPosition() < 10) myLSS.move(1800);
else if (myLSS.getPosition() > 1790) myLSS.move(0);
The intent of this test is to have the servo horn moving back and forth. However, the servo halts briefly at each extreme before changing direction. The equivalent RC servos under PWM change direction virtually instantly and I want to replicate this. Is there any way to prevent the pausing? I tried a similar attempt using myLSS.wheelRPM(72), but the pausing persists (and for whatever reason, sometimes some pauses are longer than others). Power supply is 12V.
âsetMaxSpeedâ sets the maximum speed in deg/sec if you want to set it in RPM you have to use âsetMaxSpeedRPMâ
I think the reason the movement is not smooth is because of the condition you are using in the code, maybe 1 degree is a very âdemandingâ condition. You could try 2 degrees, that is:
(myLSS.getPosition() < 20) and (myLSS.getPosition() > 1780)
But that is only a suggestion. It may be better to simply calculate the time it will take to reach the requested position, then send the command to move, wait for the time it will take to do so, and send the other command.
Thanks for clarifying the maxSpeed issue - Iâll correct it in my code and try the 2 degrees tolerance. One interesting thing I observed is that I can send an overwriting command like âgo to 0 degreesâ while the servo is on its way to 180 degrees and itâll change direction instantly. But if it arrives at 180 first then it undergoes a slight delay.
with different code. Something like:
âStart at 0 degreesâ
âCommand to 180 degreesâ
(while servo is on its way to 180)
âCommand to 0 degreesâ
â> servo changes direction instantly
Yes, the servo should change the direction instantly when you send a new move command.
On another note, I see you disabled Motion Control âmyLSS.setMotionControlEnabled(false)â
In that mode, the servo will move at full speed for D/MD action commands. Angular acceleration (AA) and angular deceleration (AD) wonât have an effect on motion and modifiers SD/S (speed) or T (time) cannot be used.
So if you choose EM0 some of the previous settings in your code are pretty much ignored.
EM0 was specifically created to replicate RC mode where the servo would be effectively spammed by a bunch of position commands and move to each position as quickly as possible. It takes the new position and enters âholding modeâ, so travels to that new position as quickly as possible.
EM1 filtering (ON by default) smoothes the RC motion given this âbus spammingâ approach and uses a moving weighted average of the positions helping considerably with smoothness.
Hi @geraldinebc15
is that an electronic or mechanic reason?
Iâm almost sure you can ask the servo to move 1 degree âin the same directionâ as before. But when it turns over, mechanical slack and potmeter âdead timeâ come into count.
Itâs just an academic question, who needs 1 degree moves in real live?
Certainly, you can ask the servo to move 1 degree in any direction at any time. The problem, in my opinion, is that the code he shared asks if a certain position was reached with a tolerance of 1 degree, that is:
Move to 0 degrees and then asks if it is in a position of less than 1 degree?
In fact, it was a suggestion from experience because for a certain project I needed to do something similar and using a tolerance of 1 degree I dinât get the results I wanted so I chose to put a tolerance of ±2 and I got better results.
Thank you very much for contributing to my forum inquiry. I have some new information:
It turns out that the brief pause is actually due to the myLSS.getPosition() command! I was refreshing my position at every cycle of the loop.
Here is some code that I used to find out that querying position causes delay:
The forward loop is substantially slower; taking around 30 seconds to traverse 360 degrees (jerks forward and pauses like the second hand of a clock), while the entire backward loop completes in around 1 second.
I am going to edit my code to read for position less often. As an aside, does anyone know if there is a way to query the servo position more efficiently?
@Cucumber_Harvester If youâre able to get this far, you can likely create your own code without the need of the library (the serial communication protocol is really easy to understand). That way you control everything, including timing, delays etc.
@scharette (creator of that library) might be able to offer some insight. Querying each servo normally is as simple as changing the ID number when sending a command.
The line in your post is exactly how you would do it.
The function is implemented in the library folder/LSS.cpp like this.
As you can see, it writes only to the address of the used LSS (i.e.: myLSS object) and only tries to read a reply from that single servo, too.
What makes you think it is polling from all 32 servos exactly?
@Cucumber_Harvester
What baud rate are you using with your LSS? If not doing so already, I recommend using the default baud rate, 115200.
It may be better to simply calculate the time it will take to reach the requested position, then send the command to move, wait for the time it will take to do so, and send the other command.
If you set the max speed to 72 deg/sec it should take about 2.5 seconds to reach the next position (0 or 180) so you could wait that time (delay(2500)) and then you can send the query command, and if the condition is satisfied send the next move command, that way you donât continuously request the position.
That is a great idea! I second this!
Iâd go maybe a bit further and say maybe start querying for position a few hundred ms before and maybe every 50-100 ms after that until the condition is satisfied.
That way if there is a faster motion (such as when suddenly moving with gravity and load) or slower (against gravity with load) you can still be efficient.
As a side note if your polling (in loop) has no delay/time constraints, that will prob. cause you issues, too.
Sorry, that was only wild guessing. I expected to see a getPosition(servoID) construct.
Would be handy when the servo movement Iâm currently busy with, depends on another servos position.
e.g. if(getPosition(otherServo) >= xy)âŠ