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.
Diff: main.cpp
- Revision:
- 30:1e8295770bc1
- Parent:
- 29:d6f1ccf42a31
- Child:
- 31:12faf1ba9bc7
--- a/main.cpp Fri Mar 18 09:44:52 2022 +0100
+++ b/main.cpp Tue Mar 22 10:45:49 2022 +0100
@@ -32,41 +32,41 @@
float pwm_period_s = 0.00005f; // define pwm period time in seconds and create FastPWM objects to command dc motors
FastPWM pwm_M1(PB_13); // motor M1 is used open loop
-FastPWM pwm_M2(PA_9); // motor M2 is speed controlled
-FastPWM pwm_M3(PA_10); // motor M3 is position controlled (angle controlled)
+FastPWM pwm_M2(PA_9); // motor M2 is closed-loop speed controlled (angle velocity)
+FastPWM pwm_M3(PA_10); // motor M3 is closed-loop position controlled (angle controlled)
-EncoderCounter encoder_M1(PA_6, PC_7); // create encoder read objects
+EncoderCounter encoder_M1(PA_6, PC_7); // create encoder objects to read in the encoder counter values
EncoderCounter encoder_M2(PB_6, PB_7);
EncoderCounter encoder_M3(PA_0, PA_1);
-// create SpeedController and PositionController controller objects, default parametrization is for 78.125:1 gear box
+// create SpeedController and PositionController objects, default parametrization is for 78.125:1 gear box
float max_voltage = 12.0f; // define maximum voltage of battery packs, adjust this to 6.0f V if you only use one batterypack
float counts_per_turn = 20.0f * 78.125f; // define counts per turn at gearbox end: counts/turn * gearratio
float kn = 180.0f / 12.0f; // define motor constant in rpm per V
-// float k_gear = 25.0f / 78.125f; // define additional ratio in case you are using a dc motor with a different gear box, e.g. 25:1
-// float kp = 0.1f; // define custom kp, this is the default speed controller gain for gear box 78.125:1
+float k_gear = 100.0f / 78.125f; // define additional ratio in case you are using a dc motor with a different gear box, e.g. 100:1
+float kp = 0.1f; // define custom kp, this is the default speed controller gain for gear box 78.125:1
-SpeedController speedController_M2(counts_per_turn, kn, max_voltage, pwm_M2, encoder_M2); // default 78.125:1 gear box with default contoller parameters
-// SpeedController speedController_M2(counts_per_turn * k_gear, kn / k_gear, max_voltage, pwm_M2, encoder_M2); // parameters adjusted to 25:1 gear
+// SpeedController speedController_M2(counts_per_turn, kn, max_voltage, pwm_M2, encoder_M2); // default 78.125:1 gear box with default contoller parameters
+SpeedController speedController_M2(counts_per_turn * k_gear, kn / k_gear, max_voltage, pwm_M2, encoder_M2); // parameters adjusted to 100:1 gear
float max_speed_rps = 0.5f; // define maximum speed that the position controller is changig the speed, has to be smaller or equal to kn * max_voltage
-PositionController positionController_M3(counts_per_turn, kn, max_voltage, pwm_M3, encoder_M3); // default 78.125:1 gear with default contoller parameters
-// PositionController positionController_M3(counts_per_turn * k_gear, kn / k_gear, kp * k_gear, max_voltage, pwm_M3, encoder_M3); // parameters adjusted to 25:1 gear, we need a different speed controller gain here
+// PositionController positionController_M3(counts_per_turn, kn, max_voltage, pwm_M3, encoder_M3); // default 78.125:1 gear with default contoller parameters
+PositionController positionController_M3(counts_per_turn * k_gear, kn / k_gear, kp * k_gear, max_voltage, pwm_M3, encoder_M3); // parameters adjusted to 100:1 gear, we need a different speed controller gain here
// Futaba Servo S3001 20mm 3kg Analog
Servo servo_S1(PB_2); // create servo objects
Servo servo_S2(PC_8);
-int servo_pos_S1_mus = 0; // servo S1 position, the desired position gets commanded as a time
-int servo_pos_S2_mus = 0; // servo S2 position
+float servo_S1_angle = 0; // servo S1 normalized angle
+float servo_S2_angle = 0; // servo S2 normalized angle
int servo_period_mus = 20000; // define servo period time in mus
int servo_counter = 0; // define servo counter, this is an additional variable to make the servos move
-int loops_per_second = static_cast<int>(ceilf(1.0f/(0.001f*(float)main_task_period_ms))); // define loops per second
+int loops_per_seconds = static_cast<int>(ceilf(1.0f/(0.001f*(float)main_task_period_ms))); // define loops per second
// Groove Ultrasonic Ranger V2.0
float us_distance_cm = 0.0f; // define variable to store measurement
-RangeFinder us_range_finder(PB_12, 5782.0f, 0.02f, 17500);
-// RangeFinder us_range_finder(PB_12, 5782.0f, 0.02f, 7000); // create range finder object (ultra sonic distance sensor), 1/main_task_period_ms = 20 Hz parametrization
+RangeFinder us_range_finder(PB_12, 5782.0f, 0.02f, 17500); // create range finder object (ultra sonic distance sensor), 20 Hz parametrization
+// RangeFinder us_range_finder(PB_12, 5782.0f, 0.02f, 7000); // create range finder object (ultra sonic distance sensor), 50 Hz parametrization
// LSM9DS1 IMU, carefull: not all PES boards have an imu (chip shortage)
// LSM9DS1 imu(PC_9, PA_8); // create LSM9DS1 comunication object, if you want to be able to use the imu you need to #include "LSM9DS1_i2c.h"
@@ -88,11 +88,11 @@
// motor M1 is used open-loop, we need to initialize the pwm and set pwm output to zero at the beginning, range: 0...1 -> u_min...u_max: 0.5 -> 0 V
pwm_M1.period(pwm_period_s);
- pwm_M1.write(0.5);
+ pwm_M1.write(0.5f);
// enable servos, you can also disable them at any point in your program if you don't want your servos to become warm
- servo_S1.Enable(servo_pos_S1_mus, servo_period_mus);
- servo_S2.Enable(servo_pos_S2_mus, servo_period_mus);
+ servo_S1.Enable(servo_S1_angle, servo_period_mus);
+ servo_S2.Enable(servo_S2_angle, servo_period_mus);
while (true) { // this loop will run forever
@@ -105,23 +105,26 @@
// command dc motors if mechanical button is pressed
if (mechanical_button.read()) {
- pwm_M1.write(0.75); // write output voltage to motor M1
+ pwm_M1.write(0.75f); // write output voltage to motor M1
speedController_M2.setDesiredSpeedRPS(0.5f); // set a desired speed for speed controlled dc motors M2
positionController_M3.setDesiredRotation(1.5f, max_speed_rps); // set a desired rotation for position controlled dc motors M3
} else {
- pwm_M1.write(0.5);
+ pwm_M1.write(0.5f);
speedController_M2.setDesiredSpeedRPS(0.0f);
positionController_M3.setDesiredRotation(0.0f, max_speed_rps);
}
+ // check if servos are enabled
+ if (!servo_S1.isEnabled()) servo_S1.Enable(servo_S1_angle, servo_period_mus);
+ if (!servo_S2.isEnabled()) servo_S2.Enable(servo_S2_angle, servo_period_mus);
// command servo position, this needs to be calibrated
- servo_S1.SetPosition(servo_pos_S1_mus);
- servo_S2.SetPosition(servo_pos_S2_mus);
- if (servo_pos_S1_mus <= servo_period_mus & servo_counter%loops_per_second == 0 & servo_counter != 0) {
- servo_pos_S1_mus += 100;
+ servo_S1.SetPosition(servo_S1_angle);
+ if (servo_S1_angle <= 1.0f & servo_counter%loops_per_seconds == 0 & servo_counter != 0) {
+ servo_S1_angle += 0.01f;
}
- if (servo_pos_S2_mus <= servo_period_mus & servo_counter%loops_per_second == 0 & servo_counter != 0) {
- servo_pos_S2_mus += 100;
+ servo_S2.SetPosition(servo_S2_angle);
+ if (servo_S2_angle <= 1.0f & servo_counter%loops_per_seconds == 0 & servo_counter != 0) {
+ servo_S2_angle += 0.01f;
}
servo_counter++;
@@ -135,14 +138,16 @@
ir_distance_mV = 0.0f;
- pwm_M1.write(0.5);
+ pwm_M1.write(0.5f);
speedController_M2.setDesiredSpeedRPS(0.0f);
positionController_M3.setDesiredRotation(0.0f, max_speed_rps);
- servo_pos_S1_mus = 0;
- servo_pos_S2_mus = 0;
- servo_S1.SetPosition(servo_pos_S1_mus);
- servo_S2.SetPosition(servo_pos_S2_mus);
+ servo_S1_angle = 0;
+ servo_S2_angle = 0;
+ // servo_S1.SetPosition(servo_S1_angle);
+ // servo_S2.SetPosition(servo_S2_angle);
+ if (servo_S1.isEnabled()) servo_S1.Disable();
+ if (servo_S2.isEnabled()) servo_S2.Disable();
us_distance_cm = 0.0f;
@@ -152,13 +157,13 @@
user_led = !user_led;
// do only output via serial what's really necessary (this makes your code slow)
- printf("IR sensor (mV): %3.3f, Encoder M1: %3d, Speed M2 (rps) %3.3f, Position M3 (rot): %3.3f, Servo S1 position (ms): %3d, Servo S2 position (ms): %3d, US sensor (cm): %3.3f\r\n",
+ printf("IR sensor (mV): %3.3f, Encoder M1: %3d, Speed M2 (rps) %3.3f, Position M3 (rot): %3.3f, Servo S1 angle (normalized): %3.3f, Servo S2 angle (normalized): %3.3f, US sensor (cm): %3.3f\r\n",
ir_distance_mV,
encoder_M1.read(),
speedController_M2.getSpeedRPS(),
positionController_M3.getRotation(),
- servo_pos_S1_mus,
- servo_pos_S2_mus,
+ servo_S1_angle,
+ servo_S2_angle,
us_distance_cm);
// read out the imu, the actual frames of the sensor reading needs to be figured out