Skip to content

Commit 894c0ed

Browse files
committed
- add last tick sync mechanic for driver control tasks to fix an issue with vTaskSuspend/vTaskResume
- add pump stopped mechanic to validate pump rpm - reset pumpState when we turn off the pump
1 parent 431faf7 commit 894c0ed

File tree

11 files changed

+123
-46
lines changed

11 files changed

+123
-46
lines changed

stm32-modules/include/vacuum-module/firmware/pressure_policy.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <atomic>
34
#include <cstdint>
45

56
#include "i2c_comms.hpp"
@@ -10,8 +11,10 @@ using namespace i2c::hardware;
1011

1112
class PressurePolicy {
1213
public:
13-
PressurePolicy(TaskHandle hw_handle, I2C *i2c1, I2C *i2c2, I2C *i2c3)
14+
PressurePolicy(TaskHandle hw_handle, std::atomic<bool> *t_sync, I2C *i2c1,
15+
I2C *i2c2, I2C *i2c3)
1416
: hardware_handle(hw_handle),
17+
t_resync_needed(t_sync),
1518
i2c_comms1{i2c1},
1619
i2c_comms2{i2c2},
1720
i2c_comms3{i2c3} {}
@@ -37,6 +40,7 @@ class PressurePolicy {
3740

3841
private:
3942
TaskHandle hardware_handle;
43+
std::atomic<bool> *t_resync_needed;
4044

4145
I2C *i2c_comms1;
4246
I2C *i2c_comms2;

stm32-modules/include/vacuum-module/firmware/pump_policy.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <atomic>
34
#include <cstdint>
45

56
#include "firmware/pump_hardware.h"
@@ -9,7 +10,8 @@ namespace pump_policy {
910

1011
class PumpPolicy {
1112
public:
12-
PumpPolicy(TaskHandle hw_handle) : hardware_handle(hw_handle) {}
13+
PumpPolicy(TaskHandle hw_handle, std::atomic<bool>* t_sync)
14+
: hardware_handle(hw_handle), t_resync_needed(t_sync) {}
1315

1416
auto start_pump_motor() -> bool;
1517
auto stop_pump_motor() -> bool;
@@ -23,5 +25,6 @@ class PumpPolicy {
2325

2426
private:
2527
TaskHandle hardware_handle;
28+
std::atomic<bool>* t_resync_needed;
2629
};
2730
} // namespace pump_policy

stm32-modules/include/vacuum-module/vacuum-module/gcodes.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,9 @@ struct GetPumpState {
475475
-> InputIt {
476476
int res = 0;
477477
res = snprintf(&*buf, (limit - buf),
478-
"M123 T:%.1f R:%.1f A:%d D:%d E:%d M:%d OK\n", target_rpm,
479-
current_rpm, target_pwm, current_pwm, pump_running,
480-
manual_control);
478+
"M123 T:%.1f R:%.1f A:%d D:%d E:%d M:%d OK\n",
479+
target_rpm, current_rpm, target_pwm, current_pwm,
480+
pump_running, manual_control);
481481
if (res <= 0) {
482482
return buf;
483483
}

stm32-modules/include/vacuum-module/vacuum-module/messages.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ struct GetPumpStateResponseMessage {
157157
double current_rpm;
158158
uint8_t target_pwm;
159159
uint8_t current_pwm;
160-
bool manual_control;
161160
bool pump_running;
161+
bool manual_control;
162162
};
163163

164164
using HostCommsMessage =

stm32-modules/include/vacuum-module/vacuum-module/pressure_task.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const PressureControl pressure_control = {
8686
.pid = PID{.kp = 1,
8787
.ki = 0.5,
8888
.kd = 0,
89-
.sampletime = CONTROL_PERIOD_MS * 1000,
89+
.sampletime = CONTROL_PERIOD_MS,
9090
.windup_limit_high = 18000,
9191
.windup_limit_low = 0},
9292
};

stm32-modules/include/vacuum-module/vacuum-module/pump_task.hpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ namespace pump_task {
1919

2020
// The frequency the pump control loop runs at.
2121
// static constexpr const uint32_t CONTROL_PERIOD_HZ = 100;
22-
static constexpr const uint32_t CONTROL_PERIOD_HZ = 1;
22+
static constexpr const uint32_t CONTROL_PERIOD_HZ = 20;
2323
static constexpr const uint32_t CONTROL_PERIOD_MS =
2424
(1 / CONTROL_PERIOD_HZ) * 1000;
2525
static constexpr const double MS_TO_SECONDS = 0.001F;
2626
static constexpr const uint8_t MAX_PWM = 100;
27+
static constexpr const double MIN_RPM = 0;
2728
static constexpr const double MAX_RPM = 3000;
2829

2930
struct PumpControl {
30-
// NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
3131
double target_rpm = 0.0F;
3232
double current_rpm = 0.0F;
3333
uint8_t current_pwm = 0;
@@ -44,10 +44,10 @@ struct PumpControl {
4444
const PumpControl pump_control = {
4545
.target_rpm = 0.0f,
4646
.target_pwm = 0,
47-
.pid = PID{.kp = 1,
48-
.ki = 0.5,
49-
.kd = 0,
50-
.sampletime = CONTROL_PERIOD_MS * 1000,
47+
.pid = PID{.kp = 2,
48+
.ki = 0.8,
49+
.kd = 0.1,
50+
.sampletime = CONTROL_PERIOD_MS,
5151
.windup_limit_high = 18000,
5252
.windup_limit_low = 0},
5353
};
@@ -132,20 +132,29 @@ class PumpTask {
132132
static_cast<void>(m);
133133
static_cast<void>(policy);
134134

135+
if (!_pump_control.enable_pump) {
136+
return;
137+
}
138+
135139
// Get delta time
136140
auto timestamp = policy.get_time_ms();
137141
auto delta_s = (timestamp - pump_control.last_tick) * MS_TO_SECONDS;
138142
_pump_control.last_tick = timestamp;
139143

140144
// TODO: Do we want rampgen here for smooth interpolation?
141145
// Compute the new duty cycle
142-
auto current_rpm = policy.get_pump_rpm();
143-
auto difference = _pump_control.target_rpm - current_rpm;
146+
auto rpm = policy.get_pump_rpm();
147+
// reject non-sense rpm
148+
if (rpm < MIN_RPM || rpm >= MAX_RPM) {
149+
return;
150+
}
151+
152+
auto difference = _pump_control.target_rpm - rpm;
144153
auto duty = _pump_control.pid.compute(difference, delta_s);
145154
duty = std::clamp<uint8_t>(duty, 0, MAX_PWM);
155+
// set the motor duty cycle if different
146156
_pump_control.current_pwm = duty;
147-
148-
// set the motor duty cycle
157+
_pump_control.current_rpm = rpm;
149158
policy.set_pump_duty_cycle(duty);
150159
}
151160

@@ -163,15 +172,14 @@ class PumpTask {
163172

164173
if (!m.run_pump) {
165174
policy.enable_pump_control(false);
175+
policy.enable_pump_tach(false);
166176
policy.stop_pump_motor();
167177
// TODO: maybe check the rpm here and verify that the pump is off
168178
// Might want a way to ramp down when we turn off the pump.
169179
_pump_control.pump_running = false;
170-
return;
171-
}
172-
173-
// start pump if not running
174-
if (m.run_pump && !_pump_control.pump_running) {
180+
_pump_control.current_rpm = 0;
181+
_pump_control.current_pwm = 0;
182+
} else if (!_pump_control.pump_running) {
175183
policy.enable_pump_tach(true);
176184
policy.enable_pump_control(true);
177185
policy.start_pump_motor();
@@ -192,8 +200,8 @@ class PumpTask {
192200
.current_rpm = _pump_control.current_rpm,
193201
.target_pwm = _pump_control.target_pwm,
194202
.current_pwm = _pump_control.current_pwm,
195-
.manual_control = _pump_control.manual_control,
196203
.pump_running = _pump_control.pump_running,
204+
.manual_control = _pump_control.manual_control,
197205
};
198206
static_cast<void>(
199207
_task_registry->send_to_address(msg, Queues::HostCommsAddress));

stm32-modules/vacuum-module/firmware/pressure_task/freertos_pressure_task.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ static constexpr uint32_t _hardware_stack_size = 128;
2323
static std::array<StackType_t, _hardware_stack_size> _hardware_stack;
2424
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2525
static StaticTask_t _hardware_data;
26+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
27+
std::atomic<bool> t_resync_needed = true;
2628

2729
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2830
static tasks::FirmwareTasks::PressureQueue
@@ -36,6 +38,12 @@ static auto _top_task = pressure_task::PressureTask(_queue, nullptr, nullptr);
3638
static void run_hardware_task(void* param) {
3739
TickType_t last_wake_time = xTaskGetTickCount();
3840
while (true) {
41+
// Need to resync last time count after suspension
42+
if (t_resync_needed.load()) {
43+
last_wake_time = xTaskGetTickCount();
44+
t_resync_needed.store(false);
45+
}
46+
3947
vTaskDelayUntil(
4048
&last_wake_time,
4149
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
@@ -57,7 +65,8 @@ auto run(tasks::FirmwareTasks::QueueAggregator* aggregator,
5765
run_hardware_task, "PressureHardware", _hardware_stack.size(), nullptr,
5866
1, _hardware_stack.data(), &_hardware_data);
5967

60-
auto policy = PressurePolicy(hw_handle, i2c1_comms, i2c2_comms, i2c3_comms);
68+
auto policy = PressurePolicy(hw_handle, &t_resync_needed, i2c1_comms,
69+
i2c2_comms, i2c3_comms);
6170
policy.enable_continous_pressure(false);
6271
while (true) {
6372
_top_task.run_once(policy);

stm32-modules/vacuum-module/firmware/pressure_task/pressure_policy.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "firmware/pressure_policy.hpp"
22

3-
#include <cstdint>
4-
53
#include "FreeRTOS.h"
64
#include "firmware/pressure_sensor_hardware.h"
75
#include "projdefs.h"
@@ -31,6 +29,7 @@ auto PressurePolicy::sensor_reset(PressureSensorID sensor_id) -> void {
3129
auto PressurePolicy::enable_continous_pressure(bool enable) -> void {
3230
auto handle = static_cast<TaskHandle_t>(hardware_handle);
3331
if (enable) {
32+
t_resync_needed->store(true);
3433
vTaskResume(handle);
3534
} else {
3635
vTaskSuspend(handle);

stm32-modules/vacuum-module/firmware/pump_task/freertos_pump_task.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ static constexpr uint32_t _hardware_stack_size = 128;
2020
static std::array<StackType_t, _hardware_stack_size> _hardware_stack;
2121
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2222
static StaticTask_t _hardware_data;
23+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
24+
std::atomic<bool> t_resync_needed = true;
2325

2426
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2527
static tasks::FirmwareTasks::PumpQueue
@@ -32,6 +34,12 @@ static auto _top_task = pump_task::PumpTask(_queue, nullptr, nullptr);
3234
static void run_hardware_task(void* param) {
3335
TickType_t last_wake_time = xTaskGetTickCount();
3436
while (true) {
37+
// Need to resync last time count after suspension
38+
if (t_resync_needed.load()) {
39+
last_wake_time = xTaskGetTickCount();
40+
t_resync_needed.store(false);
41+
}
42+
3543
vTaskDelayUntil(
3644
&last_wake_time,
3745
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
@@ -51,7 +59,7 @@ auto run(tasks::FirmwareTasks::QueueAggregator* aggregator) -> void {
5159
run_hardware_task, "PumpHardware", _hardware_stack.size(), nullptr, 1,
5260
_hardware_stack.data(), &_hardware_data);
5361

54-
auto policy = PumpPolicy(hw_handle);
62+
auto policy = PumpPolicy(hw_handle, &t_resync_needed);
5563
policy.enable_pump_control(false);
5664
while (true) {
5765
_top_task.run_once(policy);

0 commit comments

Comments
 (0)