Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve interpolation and filtering of incoming command streams #274

Open
PeterBowman opened this issue Oct 1, 2024 · 1 comment
Open
Assignees

Comments

@PeterBowman
Copy link
Member

PeterBowman commented Oct 1, 2024

Some time ago, I introduced the CommandBuffer class to act as a single-element buffer for high-frequency commands, mostly devised for CSP mode (IPositionDirect):

/**
* @ingroup TechnosoftIpos
* @brief A buffer for periodic commands implementing linear interpolation.
*/
class CommandBuffer
{
public:
void accept(double command);
double interpolate();
double getStoredCommand(double * timestamp = nullptr) const;
void reset(double initialCommand);
private:
double storedCommand {0.0};
double interpolationResult {0.0};
double commandPeriod {0.0};
double commandTimestamp {0.0};
double interpolationTimestamp {0.0};
mutable std::mutex mutex;
};

(implementation)

This feature allowed to decouple the rate of incoming commands (those flowing through the YARP network) from the CSP rate (i.e. commands sent via CAN to the iPOS drives) while also performing linear interpolation (LERP). Prior to that, clients needed to send IPositionDirect commands at exactly the same rate as --syncPeriod; otherwise, a sloppy behavior was to be expected.

I observed that this can be further improved as the behavior is still far from ideal when commands flow irregularly and in lower frequencies. I suggest a dual mechanism to achieve this:

  • Signal filtering via a low-pass filter (IIR): Wikipedia (permalink). It can be actually seen as an exponential moving average (EMA). I recently implemented one here.
  • Spline interpolation via higher-order polynomials, i.e. (beyond linear ones) cubic and perhaps even quintic polynomials. I'm also thinking of minimum jerk trajectory generators, see this YARP implementation for Gazebo: hpp, cpp.
@PeterBowman
Copy link
Member Author

On a side note, the filtering and interpolation could be done by the device that is sending the commands to our joint controllers, instead of those.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant