Skip to content

Commit d05acbe

Browse files
add enable and disable to actuators (#139)
* add enable and disable to actuators * reset motor errors on odrive when enabled * fix table alignment with prettier * remove comments in canopen_motor * change enabled to true * remove enabled from d1 setup * add notes about the `active` property * review documentation * remove inconsistently placed comments * some cleanup * first act, then mark module as disabled * simplify output.cpp a bit * call the right methods; swap if statement for consistency * fix end-of-file * add guard around `output.pulse` * code review --------- Co-authored-by: Falko Schindler <falko@zauberzeug.com>
1 parent 0f72bc7 commit d05acbe

33 files changed

+712
-65
lines changed

docs/module_reference.md

Lines changed: 119 additions & 42 deletions
Large diffs are not rendered by default.

main/modules/canopen_motor.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const std::map<std::string, Variable_ptr> CanOpenMotor::get_defaults() {
6969
{PROP_PV_IS_MOVING, std::make_shared<BooleanVariable>(false)},
7070
{PROP_CTRL_ENA_OP, std::make_shared<BooleanVariable>(false)},
7171
{PROP_CTRL_HALT, std::make_shared<BooleanVariable>(true)},
72+
{"enabled", std::make_shared<BooleanVariable>(true)},
7273
};
7374
}
7475

@@ -523,6 +524,9 @@ double CanOpenMotor::get_position() {
523524
}
524525

525526
void CanOpenMotor::position(const double position, const double speed, const double acceleration) {
527+
if (!this->enabled) {
528+
return;
529+
}
526530
this->enter_position_mode(static_cast<int32_t>(speed));
527531
this->send_target_position(static_cast<int32_t>(position) + this->properties[PROP_OFFSET]->integer_value);
528532
send_control_word(build_ctrl_word(true));
@@ -533,7 +537,39 @@ double CanOpenMotor::get_speed() {
533537
}
534538

535539
void CanOpenMotor::speed(const double speed, const double acceleration) {
540+
if (!this->enabled) {
541+
return;
542+
}
536543
this->enter_velocity_mode(speed);
537544
this->properties[PROP_CTRL_HALT]->boolean_value = false;
538545
send_control_word(build_ctrl_word(false));
539546
}
547+
548+
void CanOpenMotor::step() {
549+
if (!this->properties[PROP_INITIALIZED]->boolean_value) {
550+
return;
551+
}
552+
553+
if (this->properties["enabled"]->boolean_value != this->enabled) {
554+
if (this->properties["enabled"]->boolean_value) {
555+
this->enable();
556+
} else {
557+
this->disable();
558+
}
559+
}
560+
}
561+
562+
void CanOpenMotor::enable() {
563+
this->enabled = true;
564+
this->properties["enabled"]->boolean_value = true;
565+
this->properties[PROP_CTRL_ENA_OP]->boolean_value = true;
566+
send_control_word(build_ctrl_word(false));
567+
}
568+
569+
void CanOpenMotor::disable() {
570+
this->stop();
571+
this->properties[PROP_CTRL_ENA_OP]->boolean_value = false;
572+
send_control_word(build_ctrl_word(false));
573+
this->enabled = false;
574+
this->properties["enabled"]->boolean_value = false;
575+
}

main/modules/canopen_motor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ using CanOpenMotor_ptr = std::shared_ptr<CanOpenMotor>;
1313
class CanOpenMotor : public Module, public std::enable_shared_from_this<CanOpenMotor>, virtual public Motor {
1414
Can_ptr can;
1515
const uint8_t node_id;
16+
bool enabled = true;
1617

1718
enum InitState init_state = WaitingForPreoperational;
1819

@@ -66,4 +67,7 @@ class CanOpenMotor : public Module, public std::enable_shared_from_this<CanOpenM
6667
void position(const double position, const double speed, const double acceleration) override;
6768
double get_speed() override;
6869
void speed(const double speed, const double acceleration) override;
70+
void enable() override;
71+
void disable() override;
72+
void step() override;
6973
};

main/modules/d1_motor.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const std::map<std::string, Variable_ptr> D1Motor::get_defaults() {
1818
{"velocity", std::make_shared<IntegerVariable>()},
1919
{"status_word", std::make_shared<IntegerVariable>(-1)},
2020
{"status_flags", std::make_shared<IntegerVariable>()},
21+
{"enabled", std::make_shared<BooleanVariable>(true)},
2122
};
2223
}
2324

@@ -120,6 +121,12 @@ void D1Motor::call(const std::string method_name, const std::vector<ConstExpress
120121
} else if (method_name == "nmt_write") {
121122
Module::expect(arguments, 1, integer);
122123
this->nmt_write(arguments[0]->evaluate_integer());
124+
} else if (method_name == "enable") {
125+
Module::expect(arguments, 0);
126+
this->enable();
127+
} else if (method_name == "disable") {
128+
Module::expect(arguments, 0);
129+
this->disable();
123130
} else {
124131
throw std::runtime_error("Method " + method_name + " not found");
125132
}
@@ -130,6 +137,13 @@ void D1Motor::step() {
130137
this->sdo_read(0x2014, 0);
131138
this->sdo_read(0x6064, 0);
132139
this->sdo_read(0x606C, 0);
140+
if (this->properties.at("enabled")->boolean_value != this->enabled) {
141+
if (this->properties.at("enabled")->boolean_value) {
142+
this->enable();
143+
} else {
144+
this->disable();
145+
}
146+
}
133147
Module::step();
134148
}
135149

@@ -160,6 +174,8 @@ void D1Motor::setup() {
160174
}
161175

162176
void D1Motor::home() {
177+
if (!this->enabled)
178+
return;
163179
this->sdo_write(0x6060, 0, 8, 6);
164180
// set specific homing parameters
165181
this->sdo_write(0x6099, 1, 32, this->properties["switch_search_speed"]->integer_value);
@@ -170,6 +186,8 @@ void D1Motor::home() {
170186
}
171187

172188
void D1Motor::profile_position(const int32_t position) {
189+
if (!this->enabled)
190+
return;
173191
// set mode to profile position mode
174192
this->sdo_write(0x6060, 0, 8, 1);
175193
// commit target position
@@ -185,6 +203,8 @@ void D1Motor::profile_position(const int32_t position) {
185203
}
186204

187205
void D1Motor::profile_velocity(const int32_t velocity) {
206+
if (!this->enabled)
207+
return;
188208
// set mode to profile velocity mode
189209
this->sdo_write(0x6060, 0, 8, 3);
190210
// commit target velocity
@@ -199,3 +219,14 @@ void D1Motor::profile_velocity(const int32_t velocity) {
199219
void D1Motor::stop() {
200220
this->sdo_write(0x6040, 0, 16, 7);
201221
}
222+
223+
void D1Motor::enable() {
224+
this->enabled = true;
225+
this->properties.at("enabled")->boolean_value = true;
226+
}
227+
228+
void D1Motor::disable() {
229+
this->stop();
230+
this->enabled = false;
231+
this->properties.at("enabled")->boolean_value = false;
232+
}

main/modules/d1_motor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class D1Motor : public Module, public std::enable_shared_from_this<D1Motor> {
1414
const uint8_t node_id;
1515
int waiting_nmt_writes = 0;
1616
int waiting_sdo_writes = 0;
17+
bool enabled = true;
1718

1819
void sdo_read(const uint16_t index, const uint8_t sub);
1920
void nmt_write(const uint8_t cs);
@@ -32,4 +33,6 @@ class D1Motor : public Module, public std::enable_shared_from_this<D1Motor> {
3233
void profile_position(const int32_t position);
3334
void profile_velocity(const int32_t velocity);
3435
void stop();
36+
void enable();
37+
void disable();
3538
};

main/modules/dunker_motor.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const std::map<std::string, Variable_ptr> DunkerMotor::get_defaults() {
1313
{"voltage_power", std::make_shared<NumberVariable>()},
1414
{"m_per_turn", std::make_shared<NumberVariable>(1.0)},
1515
{"reversed", std::make_shared<BooleanVariable>()},
16+
{"enabled", std::make_shared<BooleanVariable>(true)},
1617
};
1718
}
1819

@@ -110,10 +111,10 @@ void DunkerMotor::call(const std::string method_name, const std::vector<ConstExp
110111
this->sdo_write(index, sub, bits, value);
111112
} else if (method_name == "enable") {
112113
Module::expect(arguments, 0);
113-
this->sdo_write(0x4004, 1, 8, 1);
114+
this->enable();
114115
} else if (method_name == "disable") {
115116
Module::expect(arguments, 0);
116-
this->sdo_write(0x4004, 1, 8, 0);
117+
this->disable();
117118
} else if (method_name == "speed") {
118119
Module::expect(arguments, 1, numbery);
119120
this->speed(arguments[0]->evaluate_number());
@@ -149,6 +150,8 @@ void DunkerMotor::handle_can_msg(const uint32_t id, const int count, const uint8
149150
}
150151

151152
void DunkerMotor::speed(const double speed) {
153+
if (!this->enabled)
154+
return;
152155
const int32_t motor_speed = speed /
153156
this->properties.at("m_per_turn")->number_value /
154157
(this->properties.at("reversed")->boolean_value ? -1 : 1) *
@@ -159,3 +162,26 @@ void DunkerMotor::speed(const double speed) {
159162
double DunkerMotor::get_speed() {
160163
return this->properties.at("speed")->number_value;
161164
}
165+
166+
void DunkerMotor::enable() {
167+
this->enabled = true;
168+
this->properties.at("enabled")->boolean_value = true;
169+
this->sdo_write(0x4004, 1, 8, 1);
170+
}
171+
172+
void DunkerMotor::disable() {
173+
this->sdo_write(0x4004, 1, 8, 0);
174+
this->enabled = false;
175+
this->properties.at("enabled")->boolean_value = false;
176+
}
177+
178+
void DunkerMotor::step() {
179+
if (this->properties.at("enabled")->boolean_value != this->enabled) {
180+
if (this->properties.at("enabled")->boolean_value) {
181+
this->enable();
182+
} else {
183+
this->disable();
184+
}
185+
}
186+
Module::step();
187+
}

main/modules/dunker_motor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class DunkerMotor : public Module, public std::enable_shared_from_this<DunkerMot
1414
const uint8_t node_id;
1515
int waiting_nmt_writes = 0;
1616
int waiting_sdo_writes = 0;
17+
bool enabled = true;
1718

1819
void sdo_read(const uint16_t index, const uint8_t sub);
1920
void nmt_write(const uint8_t cs);
@@ -28,4 +29,7 @@ class DunkerMotor : public Module, public std::enable_shared_from_this<DunkerMot
2829
static const std::map<std::string, Variable_ptr> get_defaults();
2930
void speed(const double speed);
3031
double get_speed();
32+
void enable();
33+
void disable();
34+
void step() override;
3135
};

main/modules/dunker_wheels.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const std::map<std::string, Variable_ptr> DunkerWheels::get_defaults() {
88
{"width", std::make_shared<NumberVariable>(1.0)},
99
{"linear_speed", std::make_shared<NumberVariable>()},
1010
{"angular_speed", std::make_shared<NumberVariable>()},
11+
{"enabled", std::make_shared<BooleanVariable>(true)},
1112
};
1213
}
1314

@@ -23,18 +24,48 @@ void DunkerWheels::step() {
2324
this->properties.at("linear_speed")->number_value = (left_speed + right_speed) / 2;
2425
this->properties.at("angular_speed")->number_value = (right_speed - left_speed) / this->properties.at("width")->number_value;
2526

27+
if (this->properties.at("enabled")->boolean_value != this->enabled) {
28+
if (this->properties.at("enabled")->boolean_value) {
29+
this->enable();
30+
} else {
31+
this->disable();
32+
}
33+
}
34+
2635
Module::step();
2736
}
2837

2938
void DunkerWheels::call(const std::string method_name, const std::vector<ConstExpression_ptr> arguments) {
3039
if (method_name == "speed") {
3140
Module::expect(arguments, 2, numbery, numbery);
41+
if (!this->enabled)
42+
return;
3243
double linear = arguments[0]->evaluate_number();
3344
double angular = arguments[1]->evaluate_number();
3445
double width = this->properties.at("width")->number_value;
3546
this->left_motor->speed(linear - angular * width / 2.0);
3647
this->right_motor->speed(linear + angular * width / 2.0);
48+
} else if (method_name == "enable") {
49+
Module::expect(arguments, 0);
50+
this->enable();
51+
} else if (method_name == "disable") {
52+
Module::expect(arguments, 0);
53+
this->disable();
3754
} else {
3855
Module::call(method_name, arguments);
3956
}
4057
}
58+
59+
void DunkerWheels::enable() {
60+
this->enabled = true;
61+
this->properties.at("enabled")->boolean_value = true;
62+
this->left_motor->enable();
63+
this->right_motor->enable();
64+
}
65+
66+
void DunkerWheels::disable() {
67+
this->left_motor->disable();
68+
this->right_motor->disable();
69+
this->enabled = false;
70+
this->properties.at("enabled")->boolean_value = false;
71+
}

main/modules/dunker_wheels.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ class DunkerWheels : public Module {
77
private:
88
const DunkerMotor_ptr left_motor;
99
const DunkerMotor_ptr right_motor;
10+
bool enabled = true;
1011

1112
public:
1213
DunkerWheels(const std::string name, const DunkerMotor_ptr left_motor, const DunkerMotor_ptr right_motor);
1314
void step() override;
1415
void call(const std::string method_name, const std::vector<ConstExpression_ptr> arguments) override;
1516
static const std::map<std::string, Variable_ptr> get_defaults();
17+
void enable();
18+
void disable();
1619
};

main/modules/linear_motor.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const std::map<std::string, Variable_ptr> LinearMotor::get_defaults() {
77
return {
88
{"in", std::make_shared<BooleanVariable>()},
99
{"out", std::make_shared<BooleanVariable>()},
10+
{"enabled", std::make_shared<BooleanVariable>(true)},
1011
};
1112
}
1213

@@ -17,27 +18,58 @@ LinearMotor::LinearMotor(const std::string name) : Module(output, name) {
1718
void LinearMotor::step() {
1819
this->properties.at("in")->boolean_value = this->get_in();
1920
this->properties.at("out")->boolean_value = this->get_out();
21+
22+
if (this->properties.at("enabled")->boolean_value != this->enabled) {
23+
if (this->properties.at("enabled")->boolean_value) {
24+
this->enable();
25+
} else {
26+
this->disable();
27+
}
28+
}
29+
2030
Module::step();
2131
}
2232

2333
void LinearMotor::call(const std::string method_name, const std::vector<ConstExpression_ptr> arguments) {
2434
if (method_name == "in") {
2535
Module::expect(arguments, 0);
36+
if (!this->enabled)
37+
return;
2638
this->set_in(1);
2739
this->set_out(0);
2840
} else if (method_name == "out") {
2941
Module::expect(arguments, 0);
42+
if (!this->enabled)
43+
return;
3044
this->set_in(0);
3145
this->set_out(1);
3246
} else if (method_name == "stop") {
3347
Module::expect(arguments, 0);
3448
this->set_in(0);
3549
this->set_out(0);
50+
} else if (method_name == "enable") {
51+
Module::expect(arguments, 0);
52+
this->enable();
53+
} else if (method_name == "disable") {
54+
Module::expect(arguments, 0);
55+
this->disable();
3656
} else {
3757
Module::call(method_name, arguments);
3858
}
3959
}
4060

61+
void LinearMotor::enable() {
62+
this->enabled = true;
63+
this->properties.at("enabled")->boolean_value = true;
64+
}
65+
66+
void LinearMotor::disable() {
67+
this->set_in(0);
68+
this->set_out(0);
69+
this->enabled = false;
70+
this->properties.at("enabled")->boolean_value = false;
71+
}
72+
4173
GpioLinearMotor::GpioLinearMotor(const std::string name,
4274
const gpio_num_t move_in,
4375
const gpio_num_t move_out,

0 commit comments

Comments
 (0)