Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: LSM9DS1 RangeFinder FastPWM
Dependents: PM2_Example_PES_board PM2_Example_PES_board PM2_Example_PES_board PM2_Example_PES_board ... more
Diff: PositionController.cpp
- Revision:
- 29:335fb9b01ca7
- Parent:
- 19:518ed284d98b
- Child:
- 30:05abc1d2a2b9
--- a/PositionController.cpp Thu May 05 11:10:12 2022 +0000
+++ b/PositionController.cpp Fri May 13 20:53:33 2022 +0000
@@ -12,7 +12,7 @@
setSpeedCntrlGain(0.1f);
this->max_voltage = max_voltage;
this->max_speed = kn*max_voltage;
- setPositionCntrlGain(1300.0f);
+ setPositionCntrlGain(22.0f);
// initialise pwm
pwm.period(0.00005); // pwm period of 50 us
@@ -28,64 +28,11 @@
this->initialRotation = initialRotation;
actualRotation = initialRotation;
desiredRotation = initialRotation;
-
- // set up thread
- thread.start(callback(this, &PositionController::run));
- ticker.attach(callback(this, &PositionController::sendThreadFlag), std::chrono::microseconds{static_cast<long int>(1.0e6f * TS)});
-}
-
-PositionController::PositionController(float counts_per_turn, float kn, float kp, float max_voltage, FastPWM& pwm, EncoderCounter& encoderCounter) : pwm(pwm), encoderCounter(encoderCounter), thread(osPriorityHigh, 4096)
-{
- this->counts_per_turn = counts_per_turn;
- setFeedForwardGain(kn);
- setSpeedCntrlGain(kp);
- this->max_voltage = max_voltage;
- this->max_speed = kn*max_voltage;
- setPositionCntrlGain(1300.0f);
-
- // initialise pwm
- pwm.period(0.00005); // pwm period of 50 us
- pwm.write(0.5); // duty-cycle of 50%
-
- // initialise
- previousValueCounter = encoderCounter.read();
- speedFilter.setPeriod(TS);
- speedFilter.setFrequency(LOWPASS_FILTER_FREQUENCY);
- desiredSpeed = 0.0f;
- actualSpeed = 0.0f;
- float initialRotation = (float)encoderCounter.read()/counts_per_turn;
- this->initialRotation = initialRotation;
- actualRotation = initialRotation;
- desiredRotation = initialRotation;
-
- // set up thread
- thread.start(callback(this, &PositionController::run));
- ticker.attach(callback(this, &PositionController::sendThreadFlag), std::chrono::microseconds{static_cast<long int>(1.0e6f * TS)});
-}
-
-PositionController::PositionController(float counts_per_turn, float kn, float kp, float p, float max_voltage, FastPWM& pwm, EncoderCounter& encoderCounter) : pwm(pwm), encoderCounter(encoderCounter), thread(osPriorityHigh, 4096)
-{
- this->counts_per_turn = counts_per_turn;
- setFeedForwardGain(kn);
- setSpeedCntrlGain(kp);
- this->max_voltage = max_voltage;
- this->max_speed = kn*max_voltage;
- setPositionCntrlGain(p);
-
- // initialise pwm
- pwm.period(0.00005); // pwm period of 50 us
- pwm.write(0.5); // duty-cycle of 50%
-
- // initialise
- previousValueCounter = encoderCounter.read();
- speedFilter.setPeriod(TS);
- speedFilter.setFrequency(LOWPASS_FILTER_FREQUENCY);
- desiredSpeed = 0.0f;
- actualSpeed = 0.0f;
- float initialRotation = (float)encoderCounter.read()/counts_per_turn;
- this->initialRotation = initialRotation;
- actualRotation = initialRotation;
- desiredRotation = initialRotation;
+
+ motion.setProfileVelocity(max_voltage * kn);
+ float maxAcceleration = 22.0f * max_voltage * kn * 0.4f; // pmic, 13.05.2022, only 40%, based on simple measurement, max_voltage * kn is gearratio
+ motion.setProfileAcceleration(maxAcceleration);
+ motion.setProfileDeceleration(maxAcceleration);
// set up thread
thread.start(callback(this, &PositionController::run));
@@ -124,19 +71,6 @@
}
/**
- * Sets desired rotation (1 corresponds to 360 deg) and max. rotational speed in RPS (rotations per second).
- */
-void PositionController::setDesiredRotation(float desiredRotation, float maxSpeedRPS)
-{
- float maxSpeedRPM = fabs(maxSpeedRPS * 60.0f);
- if(maxSpeedRPM > kn * max_voltage) {
- maxSpeedRPM = kn * max_voltage;
- }
- this->max_speed = maxSpeedRPM;
- this->desiredRotation = initialRotation + desiredRotation;
-}
-
-/**
* Reads the number of rotations (1 corresponds to 360 deg).
* @return actual rotations.
*/
@@ -169,6 +103,46 @@
this->p = p;
}
+/**
+ * Sets the maximum Velocity in RPS.
+ */
+void PositionController::setMaxVelocityRPS(float maxVelocityRPS)
+{
+ if (maxVelocityRPS*60.0f <= max_speed)
+ motion.setProfileVelocity(maxVelocityRPS*60.0f);
+ else
+ motion.setProfileVelocity(max_speed);
+}
+
+/**
+ * Sets the maximum Velocity in RPM.
+ */
+void PositionController::setMaxVelocityRPM(float maxVelocityRPM)
+{
+ if (maxVelocityRPM <= max_speed)
+ motion.setProfileVelocity(maxVelocityRPM);
+ else
+ motion.setProfileVelocity(max_speed);
+}
+
+/**
+ * Sets the maximum Acceleration in RPS/sec.
+ */
+void PositionController::setMaxAccelerationRPS(float maxAccelerationRPS)
+{
+ motion.setProfileAcceleration(maxAccelerationRPS*60.0f);
+ motion.setProfileDeceleration(maxAccelerationRPS*60.0f);
+}
+
+/**
+ * Sets the maximum Acceleration in RPM/sec.
+ */
+void PositionController::setMaxAccelerationRPM(float maxAccelerationRPM)
+{
+ motion.setProfileAcceleration(maxAccelerationRPM);
+ motion.setProfileDeceleration(maxAccelerationRPM);
+}
+
void PositionController::run()
{
while(true) {
@@ -182,10 +156,16 @@
actualSpeed = speedFilter.filter((float)countsInPastPeriod/counts_per_turn/TS*60.0f);
actualRotation = actualRotation + actualSpeed/60.0f*TS;
+ motion.incrementToPosition(60.0f * desiredRotation, TS);
+ float desiredRotationMotion = motion.getPosition();
+ float desiredVelocityMotion = motion.getVelocity();
+
// calculate motor phase voltages
- desiredSpeed = p*(desiredRotation - actualRotation);
+ desiredSpeed = p *(desiredRotationMotion - 60.0f * actualRotation) + 0.0f * desiredVelocityMotion;
+
if (desiredSpeed < -max_speed) desiredSpeed = -max_speed;
else if (desiredSpeed > max_speed) desiredSpeed = max_speed;
+
float voltage = kp*(desiredSpeed - actualSpeed) + desiredSpeed/kn;
// calculate, limit and set duty cycles
float dutyCycle = 0.5f + 0.5f*voltage/max_voltage;
