Generic velocity control for servos
This commit is contained in:
parent
d22fc8e244
commit
ae62974562
@ -1,3 +1,77 @@
|
||||
#include "ServoMotor.h"
|
||||
|
||||
ServoMotor::ServoMotor() {}
|
||||
#include "VectorAlgebra/FloatSingle.h"
|
||||
|
||||
ServoMotor::ServoMotor() { this->controlMode = ControlMode::Position; }
|
||||
|
||||
void ServoMotor::SetTargetAngle(float targetAngle) {
|
||||
targetAngle = Float::Clamp(targetAngle, minAngle, maxAngle);
|
||||
|
||||
if (maxVelocity == 0.0F) {
|
||||
SetAngle(targetAngle);
|
||||
} else if (targetAngle != this->targetAngle) {
|
||||
// if the new target is the same, the limited angle is not overwritten
|
||||
this->limitedTargetAngle = this->targetAngle;
|
||||
}
|
||||
|
||||
this->controlMode = ControlMode::Position;
|
||||
this->targetAngle = targetAngle;
|
||||
}
|
||||
|
||||
float ServoMotor::GetTargetAngle() { return this->targetAngle; }
|
||||
|
||||
void ServoMotor::SetMaximumVelocity(float maxVelocity) {
|
||||
this->maxVelocity = maxVelocity;
|
||||
}
|
||||
|
||||
void ServoMotor::SetTargetVelocity(float velocity) {
|
||||
targetVelocity =
|
||||
Float::Clamp(targetVelocity, -this->maxVelocity, maxVelocity);
|
||||
|
||||
this->controlMode = ControlMode::Velocity;
|
||||
this->targetVelocity = targetVelocity;
|
||||
this->hasTargetAngle = false; // can't we use the controlMode for this?
|
||||
}
|
||||
|
||||
float ServoMotor::GetTargetVelocity() { return this->targetVelocity; }
|
||||
|
||||
void ServoMotor::Update(float currentTimeMs) {
|
||||
if (this->lastUpdateTimeMs == 0 || currentTimeMs < this->lastUpdateTimeMs) {
|
||||
this->lastUpdateTimeMs = currentTimeMs;
|
||||
return;
|
||||
}
|
||||
|
||||
float deltaTime = (currentTimeMs - this->lastUpdateTimeMs) / 1000.0F;
|
||||
|
||||
if (controlMode == ControlMode::Position) {
|
||||
if (maxVelocity == 0.0F || hasTargetAngle == false) {
|
||||
this->lastUpdateTimeMs = currentTimeMs;
|
||||
return;
|
||||
|
||||
} else {
|
||||
float angleStep = maxVelocity * deltaTime;
|
||||
float deltaAngle = this->targetAngle - this->limitedTargetAngle;
|
||||
if (deltaAngle < 0)
|
||||
deltaAngle = -deltaAngle;
|
||||
|
||||
if (deltaAngle < angleStep) {
|
||||
this->limitedTargetAngle = this->targetAngle;
|
||||
SetAngle(targetAngle);
|
||||
} else {
|
||||
limitedTargetAngle += angleStep;
|
||||
}
|
||||
SetAngle(limitedTargetAngle);
|
||||
|
||||
this->lastUpdateTimeMs = currentTimeMs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float newAngle = this->targetAngle + targetVelocity * deltaTime;
|
||||
newAngle = Float::Clamp(newAngle, minAngle, maxAngle);
|
||||
|
||||
ServoMotor::SetTargetAngle(newAngle);
|
||||
SetAngle(newAngle);
|
||||
|
||||
this->lastUpdateTimeMs = currentTimeMs;
|
||||
}
|
29
ServoMotor.h
29
ServoMotor.h
@ -9,7 +9,34 @@ class ServoMotor : public Thing {
|
||||
public:
|
||||
ServoMotor();
|
||||
|
||||
virtual void SetTargetAngle(float angle) = 0;
|
||||
float minAngle = -90.0F;
|
||||
float maxAngle = 90.0F;
|
||||
|
||||
enum ControlMode { Position, Velocity };
|
||||
ControlMode controlMode = ControlMode::Position;
|
||||
|
||||
virtual void SetTargetAngle(float angle);
|
||||
virtual float GetTargetAngle();
|
||||
|
||||
virtual void SetMaximumVelocity(float maxVelocity);
|
||||
|
||||
virtual void SetTargetVelocity(float velocity);
|
||||
virtual float GetTargetVelocity();
|
||||
|
||||
virtual void Update(float currentTimeMs);
|
||||
|
||||
protected:
|
||||
bool hasTargetAngle = false;
|
||||
float targetAngle = 0.0F;
|
||||
|
||||
float maxVelocity = 0.0F;
|
||||
|
||||
float targetVelocity = 0.0F;
|
||||
float limitedTargetAngle = 0.0F;
|
||||
|
||||
float lastUpdateTimeMs = 0.0F;
|
||||
|
||||
virtual void SetAngle(float angle) = 0;
|
||||
};
|
||||
|
||||
} // namespace RoboidContol
|
||||
|
Loading…
x
Reference in New Issue
Block a user