Also, the LSS have an advanced mode that combines the best of the smart world (serial comms) with PWM-type control!
If you set the motion controller to mode 0 (i.e.: EM0), you now have a way to control the servo that is quite different.
In some cases with high variance in torque this can give both more control on motion but also reduce stuff like jerkiness at end points and motions where torque changes dramatically (such as changing between working against vs working with gravity).
In this mode, by default, the LSS will replay a command internally when it receives it. So if your LSS is at position 0 (QD=0) and you send D900, it will internally replay D900 (kinda like when you send a PWM indicating a +90° on a RC servomotor) until it reaches that position. By default, the LSS in this mode has an exponential weighted moving average (you can read more here & here) added to the input which produces, effectively, an S-curve style motion on the cheap, allowing you to have smooth starts and stop while also moving fast in between. You may have to tweak your AS and AH value to change how stiff the motions are based on what you are doing (you should be doing this anyway for complex motions! )
Alternatively, you can turn off this “motion engine” and/or tweak the depth of the the EWMA. If I remember correctly, the motion engine playback at a rate of 1:4 with the control loop, so that would make it play at exactly 20 ms (used to be ±1-2 ms of jitter but I think the staggered scheduling of the tasks removed that completely now), just like a typical RC servomotors.
If you change the dept of the EWMA you can increase or reduce the “smoothing” effect. I recommend only using odd values for best results. If you set it to 0 you can turn it off, too. Be prepared for rough motion though if you do that! I think the default value is 5.
As for the motion engine itself, when it is turned off the LSS will not go to the sent position on the first command. Instead, you’ll have to send a new position regularly until the LSS makes it to that position. How fast you send those positions (and their relative delta) will determine how fast the servo will reach your final position. This allows for a huge amount of flexibility in motion.
In all of the EM=0 cases if you send positions faster than the running rate of the application of motion (i.e.: once per 20 ms), only the latest value will apply the next time the LSS is ready to apply a new position command to its internal control system. See the example below:
In this example the LSS at
t = 0 ms is limp/without motion. Each vertical bars (blue & orange) represent a position update. One is done at 10 ms, 30 ms, 50 ms, 55 ms, 70 ms and 90 ms. All of the blue updates will take effect when they are sent. The orange one at 55 ms will not take effect at 55 ms since the control is not ready for a new position yet. It will only get applied 20 ms after the last cycle. If a new position is sent before then (such as the one at 70 ms), that value will be used instead.
This has been discussed before many times, especially with @cmackenzie. I think the main show stopped on this front is that the TX and RX lines are set to their respective roles (on each LSS TX is a buffered output and RX is a buffered input). After those discussions, I think the conclusion was that there was no simple way for the LSS to read the status of the TX line. Therefore, this makes it really difficult to coordinate two or more LSS to coordinate responding on the bus. Timing can be used, but then you’ll need good safety margins since all LSS will have variance in clock timing & etc. The larger safeguards in timing will make this about as efficient or less than reading each individually at high speed ( with 0 risk of collision if done properly, see @cmackenzie 's work on that it is very impressive! ).
That being said, it is still not completely impossible but most likely not trivial at all… If only there was one extra pin to read TX output (on the buffer side). Unfortunately, reading the line status when not outputting (on the common bus) is not possible due to the buffer that prevents line contention. A tough problem with the current electronics, so to speak.
I’m sure it would have many uses. Then again, the current software solutions aren’t much different and do a decent enough job that a full humanoid can be controlled in real time (with very tight control loops)!
I think I’d point the finger at @cbenson on that one probably… though I’m not 100% sure!
Totally the goal! It also makes the button menu quick to use and very user friendly once you get use to the concepts of how it works.
They really, really do!
To be honest… I kinda forgot… haha. Also, while this is not possible with the current firmware, please note that that RGB LED in the LSS is capable of at least 8 (or was it 16?) bit resolution on each of the color components individually (hardware wise/not µC CPU bound), anyway). This means that with a proper set of commands/API and some updates to the firmware, an LSS could, in theory, display at least a few thousand different colours on that LED and even transition between them smoothly enough! For now, I guess, it has 8 colours!
Sounds like a good way to get started without having a giant mess right off the bat!
I think whatever we choose (or change to, bound to happen as the code base grows!) is looked at carefully and refactored often as needed we’ll be fine. We don’t want to get stuck in repo “design paralysis” and never commit any code for months!
For now some bare bone basics to prevent major conflicts n the shared repo should be enough!
Those are pretty sensible ideas overall!
Maybe the root folder should have a contributor’s guide and we can write some basics stuff (like the structure we want to use) for now and slowly add things together as we figure out how we want to contribute. I’d say lets keep it simple and grow as needed! We don’t have millions of contributors yet so no need to be too strict for now! Kinda “let it grow organically” while keeping a (refactoring) eye on it!