Skip to content

Commit c7687da

Browse files
authored
Merge pull request #1 from esp-cpp/feature/cli
Feature/cli
2 parents ac39867 + 18497d6 commit c7687da

File tree

5 files changed

+152
-65
lines changed

5 files changed

+152
-65
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ set(EXTRA_COMPONENT_DIRS
1212

1313
set(
1414
COMPONENTS
15-
"main esptool_py filters task monitor mt6701 bldc_motor bldc_driver bldc_haptics"
15+
"main esptool_py cli filters task monitor mt6701 bldc_motor bldc_driver bldc_haptics"
1616
CACHE STRING
1717
"List of components to include"
1818
)

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,15 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
3636

3737
## Output
3838

39-
This code can be re-run (by modifying the code to change the selected
40-
`DetentConfig` from one of the predefined configurations or by making your own)
41-
to produce various behaviors. Additionally, at the end of each demo, it will
42-
play a haptic buzz / click using the motor.
39+
The haptics (detent configuration, click/buzz) can be configured dynamically at
40+
run-time using the provided CLI, see screenshot below:
41+
42+
![CleanShot 2023-06-23 at 08 45 26](https://github.com/esp-cpp/bldc_test_stand/assets/213467/912aae32-a434-4969-8309-af42a4f5f4c7)
43+
44+
As you can see, the cli also allows you to start and stop the haptic engine
45+
(default is off when the program starts) and allows you to query the position of
46+
the motor based on the current detent config. The default detent config is the
47+
unbounded_no_detents configuration.
4348

4449
For more information, see the documentation or the original PR:
4550
https://github.com/esp-cpp/espp/pull/60

components/espp

Submodule espp updated 127 files

main/main.cpp

Lines changed: 135 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "bldc_haptics.hpp"
88
#include "bldc_motor.hpp"
99
#include "butterworth_filter.hpp"
10+
#include "cli.hpp"
1011
#include "lowpass_filter.hpp"
1112
#include "mt6701.hpp"
1213
#include "task.hpp"
@@ -21,6 +22,8 @@ static constexpr int I2C_FREQ_HZ = (400 * 1000);
2122
static constexpr int I2C_TIMEOUT_MS = (10);
2223

2324
extern "C" void app_main(void) {
25+
espp::Cli::configure_stdin_stdout();
26+
2427
espp::Logger logger({.tag = "BLDC Test Stand", .level = espp::Logger::Verbosity::DEBUG});
2528

2629
logger.info("Bootup");
@@ -134,70 +137,143 @@ extern "C" void app_main(void) {
134137
.output_min = -20.0, // angle pid works on velocity (rad/s)
135138
.output_max = 20.0, // angle pid works on velocity (rad/s)
136139
},
137-
.log_level = espp::Logger::Verbosity::INFO});
138-
139-
auto print_detent_config = [&logger](const auto &detent_config) {
140-
if (detent_config == espp::detail::UNBOUNDED_NO_DETENTS) {
141-
logger.info("Setting detent config to UNBOUNDED_NO_DETENTS");
142-
}
143-
if (detent_config == espp::detail::BOUNDED_NO_DETENTS) {
144-
logger.info("Setting detent config to BOUNDED_NO_DETENTS");
145-
}
146-
if (detent_config == espp::detail::MULTI_REV_NO_DETENTS) {
147-
logger.info("Setting detent config to MULTI_REV_NO_DETENTS");
148-
}
149-
if (detent_config == espp::detail::ON_OFF_STRONG_DETENTS) {
150-
logger.info("Setting detent config to ON_OFF_STRONG_DETENTS");
151-
}
152-
if (detent_config == espp::detail::COARSE_VALUES_STRONG_DETENTS) {
153-
logger.info("Setting detent config to COARSE_VALUES_STRONG_DETENTS");
154-
}
155-
if (detent_config == espp::detail::FINE_VALUES_NO_DETENTS) {
156-
logger.info("Setting detent config to FINE_VALUES_NO_DETENTS");
157-
}
158-
if (detent_config == espp::detail::FINE_VALUES_WITH_DETENTS) {
159-
logger.info("Setting detent config to FINE_VALUES_WITH_DETENTS");
160-
}
161-
if (detent_config == espp::detail::MAGNETIC_DETENTS) {
162-
logger.info("Setting detent config to MAGNETIC_DETENTS");
163-
}
164-
if (detent_config == espp::detail::RETURN_TO_CENTER_WITH_DETENTS) {
165-
logger.info("Setting detent config to RETURN_TO_CENTER_WITH_DETENTS");
166-
}
167-
};
140+
.log_level = espp::Logger::Verbosity::WARN});
168141

169142
using BldcHaptics = espp::BldcHaptics<BldcMotor>;
170143

171144
auto haptic_motor = BldcHaptics({.motor = motor,
172145
.kp_factor = 2,
173146
.kd_factor_min = 0.01,
174147
.kd_factor_max = 0.04,
175-
.log_level = espp::Logger::Verbosity::INFO});
176-
177-
// auto detent_config = espp::detail::UNBOUNDED_NO_DETENTS;
178-
// auto detent_config = espp::detail::BOUNDED_NO_DETENTS;
179-
// auto detent_config = espp::detail::MULTI_REV_NO_DETENTS;
180-
// auto detent_config = espp::detail::ON_OFF_STRONG_DETENTS;
181-
auto detent_config = espp::detail::COARSE_VALUES_STRONG_DETENTS;
182-
// auto detent_config = espp::detail::FINE_VALUES_NO_DETENTS;
183-
// auto detent_config = espp::detail::FINE_VALUES_WITH_DETENTS;
184-
// auto detent_config = espp::detail::MAGNETIC_DETENTS;
185-
// auto detent_config = espp::detail::RETURN_TO_CENTER_WITH_DETENTS;
186-
187-
logger.info("{}", detent_config);
188-
189-
haptic_motor.update_detent_config(detent_config);
190-
// this will start the haptic motor thread which will run in the background.
191-
// If we want to change the detent config we can call update_detent_config()
192-
// and it will update the detent config in the background thread.
193-
haptic_motor.start();
194-
print_detent_config(detent_config);
195-
196-
while (true) {
197-
std::this_thread::sleep_for(500ms);
198-
if (driver->is_faulted()) {
199-
logger.error("Driver is faulted, cannot continue haptics");
200-
break;
201-
}
202-
}
148+
.log_level = espp::Logger::Verbosity::WARN});
149+
150+
// set the default detent config to be unbounded no detents so that if
151+
haptic_motor.update_detent_config(espp::detail::UNBOUNDED_NO_DETENTS);
152+
153+
auto root_menu = std::make_unique<cli::Menu>("haptics", "Haptic configuration menu");
154+
root_menu->Insert(
155+
"start",
156+
[&](std::ostream &out) {
157+
out << "Starting motor!\n";
158+
haptic_motor.start();
159+
},
160+
"Start the motor");
161+
root_menu->Insert(
162+
"stop",
163+
[&](std::ostream &out) {
164+
out << "Stopping motor!\n";
165+
haptic_motor.stop();
166+
},
167+
"Stop the motor");
168+
root_menu->Insert(
169+
"position",
170+
[&](std::ostream &out) {
171+
out << "Current position: " << haptic_motor.get_position() << "\n";
172+
},
173+
"Print the current position of the haptic motor");
174+
root_menu->Insert(
175+
"unbounded_no_detents",
176+
[&](std::ostream &out) {
177+
out << "Setting to unbounded no detents!\n";
178+
haptic_motor.update_detent_config(espp::detail::UNBOUNDED_NO_DETENTS);
179+
},
180+
"Set the haptic config to unbounded no detents");
181+
root_menu->Insert(
182+
"bounded_no_detents",
183+
[&](std::ostream &out) {
184+
out << "Setting to bounded no detents!\n";
185+
haptic_motor.update_detent_config(espp::detail::BOUNDED_NO_DETENTS);
186+
},
187+
"Set the haptic config to bounded no detents");
188+
root_menu->Insert(
189+
"multi_rev_no_detents",
190+
[&](std::ostream &out) {
191+
out << "Setting to multi rev no detents!\n";
192+
haptic_motor.update_detent_config(espp::detail::MULTI_REV_NO_DETENTS);
193+
},
194+
"Set the haptic config to multi rev no detents");
195+
root_menu->Insert(
196+
"on_off_strong_detents",
197+
[&](std::ostream &out) {
198+
out << "Setting to on off strong detents!\n";
199+
haptic_motor.update_detent_config(espp::detail::ON_OFF_STRONG_DETENTS);
200+
},
201+
"Set the haptic config to on off strong detents");
202+
root_menu->Insert(
203+
"coarse_values_strong_detents",
204+
[&](std::ostream &out) {
205+
out << "Setting to coarse values strong detents!\n";
206+
haptic_motor.update_detent_config(espp::detail::COARSE_VALUES_STRONG_DETENTS);
207+
},
208+
"Set the haptic config to coarse values strong detents");
209+
root_menu->Insert(
210+
"fine_values_no_detents",
211+
[&](std::ostream &out) {
212+
out << "Setting to fine values no detents!\n";
213+
haptic_motor.update_detent_config(espp::detail::FINE_VALUES_NO_DETENTS);
214+
},
215+
"Set the haptic config to fine values no detents");
216+
root_menu->Insert(
217+
"fine_values_with_detents",
218+
[&](std::ostream &out) {
219+
out << "Setting to fine values with detents!\n";
220+
haptic_motor.update_detent_config(espp::detail::FINE_VALUES_WITH_DETENTS);
221+
},
222+
"Set the haptic config to fine values with detents");
223+
root_menu->Insert(
224+
"magnetic_detents",
225+
[&](std::ostream &out) {
226+
out << "Setting to magnetic detents!\n";
227+
haptic_motor.update_detent_config(espp::detail::MAGNETIC_DETENTS);
228+
},
229+
"Set the haptic config to magnetic detents");
230+
root_menu->Insert(
231+
"return_to_center_with_detents",
232+
[&](std::ostream &out) {
233+
out << "Setting to return to center with detents!\n";
234+
haptic_motor.update_detent_config(espp::detail::RETURN_TO_CENTER_WITH_DETENTS);
235+
},
236+
"Set the haptic config to return to center with detents");
237+
root_menu->Insert(
238+
"click",
239+
[&](std::ostream &out, float strength) {
240+
strength = std::clamp(strength, 0.0f, 10.0f);
241+
espp::detail::HapticConfig config{
242+
.strength = strength,
243+
.frequency = 0.0f, // TODO: unused
244+
.duration = 1ms, // TODO: unused
245+
};
246+
haptic_motor.play_haptic(config);
247+
},
248+
"Play a haptic click / buzz with the given strength (suggested range 1.0 - 5.0)");
249+
root_menu->Insert(
250+
"color",
251+
[](std::ostream &out) {
252+
out << "Colors ON\n";
253+
cli::SetColor();
254+
},
255+
"Enable colors in the cli");
256+
root_menu->Insert(
257+
"nocolor",
258+
[](std::ostream &out) {
259+
out << "Colors OFF\n";
260+
cli::SetNoColor();
261+
},
262+
"Disable colors in the cli");
263+
264+
cli::Cli cli(std::move(root_menu));
265+
// turn the colors on by default :)
266+
cli::SetColor();
267+
// add an exit action to stop the motor when the cli exits
268+
cli.ExitAction([&](auto &out) {
269+
out << "Exiting menu and disabling haptics!\n";
270+
haptic_motor.stop();
271+
out << "Goodbye and thanks for all the fish.\n";
272+
});
273+
274+
espp::Cli input(cli);
275+
input.SetInputHistorySize(10);
276+
input.Start();
277+
278+
// if we've gotten here the cli has finished its session
203279
}

sdkconfig.defaults

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
CONFIG_IDF_TARGET="esp32s3"
22

3+
# enable the console to be default output on the usb-serial-jtag port instead of uart
4+
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
5+
36
CONFIG_COMPILER_OPTIMIZATION_PERF=y
47
# CONFIG_COMPILER_OPTIMIZATION_SIZE=y
58

@@ -23,3 +26,6 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
2326
#
2427
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
2528
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
29+
30+
# the cli library requires exceptions right now...
31+
CONFIG_COMPILER_CXX_EXCEPTIONS=y

0 commit comments

Comments
 (0)