Skip to content

Commit

Permalink
Some renaming and machine probing fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
rombrew committed Jun 11, 2024
1 parent 3ae158c commit 980ce02
Show file tree
Hide file tree
Showing 101 changed files with 99,078 additions and 385 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- Robust ORTEGA observer with gain scheduling against speed.
- Accurate KALMAN observer having convergence at HF injection.
- Flux weakening and MTPA control (**EXPERIMENTAL**).
- Three and two phase machine support.
- Three and two phases machine connection.
- Hardware abstraction layer (HAL) over STM32F4 and STM32F7.
- Various controller hardware are supported (including VESC clones).
- Regular Command Line Interface (CLI) with autocompletion and history.
- Graphical front-end software based on
- Command Line Interface (CLI) with autocompletion and history.
- Graphical User Interface (PGUI) based on
[Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) and
[SDL2](https://www.libsdl.org/).
- Non time-critical tasks are managed by
Expand All @@ -36,7 +36,8 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- Least Squares estimate library
[LSE](https://github.com/rombrew/lse).

- Phase current sampling schemes includes two or three sensors configuration

- Phase current sampling scheme includes two or three sensors configuration
with inline or low-side placement.
- Self-adjustment of all onboard measurements (current and voltage) along
symmetrical channels.
Expand Down Expand Up @@ -86,14 +87,14 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- DC link current consumption and regeneration.
- DC link overvoltage and undervoltage.
- Maximal speed (forward and reverse) and acceleration.
- Absolute location maximal and minimal limit.
- Absolute location limits in servo operation.

- Input control interfaces:
- Analog input knob with brake signal.
- RC servo pulse width modulation.
- CAN bus flexible configurable data transfers.
- STEP/DIR (or CW/CCW) interface (**EXPERIMENTAL**).
- Manual control through CLI or graphical front-end.
- Manual control through CLI or PGUI.
- Custom embedded application can implement any control strategy.

- Advanced CAN networking:
Expand All @@ -111,20 +112,20 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
- Battery energy (Wh) and charge (Ah) consumed.
- Fuel gauge percentage.

## Hardware specification (`REV5A`, `REV5B`)
## Hardware specification (`REV5`)

- Dimension: 82mm x 55mm x 35mm.
- Weight: 40g (PCB) or about 400g (with wires and heatsink).
- Wires: 10 AWG.
- Connector: XT90-S and bullet 5.5mm.
- Battery voltage from 5v to 50v.
- Battery voltage from 5v to 52v.
- Phase current up to 120A (with IPT007N06N, 60v, 0.75 mOhm).
- Light capacitor bank (4 x 4.7uF + 2 x 330uF).
- PWM frequency from 20 to 60 kHz.
- STM32F405RG microcontroller (Cortex-M4F at 168 MHz).

- Onboard sensors:
- Two current shunts (0.5 mOhm) with amplifiers (AD8418) give a
- Two current shunts 0.5 mOhm with amplifiers AD8418 give a
measuring range of 165A.
- Battery voltage from 0 to 60v.
- Three terminal voltages from 0 to 60v.
Expand Down Expand Up @@ -153,8 +154,8 @@ There are a few videos about PMC on [youtube](https://www.youtube.com/@romblv).
## TODO

- Make a detailed documentation.
- Improve GUI front-end software.
- Improve PGUI software.
- Add pulse output signal.
- Make a drawing of the heatsink case for `REV5A`.
- Make a drawing of the heatsink case for `REV5`.
- Design the new hardware for 120v battery voltage.

16 changes: 9 additions & 7 deletions bench/bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ tlm_plot_grab()
fmt_GP(pm.base_TIM, 0);
fmt_GP(pm.hold_TIM, 0);

sym_GP(atan2(pm.forced_F[1], pm.forced_F[0]) * kDEG, "pm.forced_F", "°");
sym_GP(atan2(pm.forced_F[1], pm.forced_F[0]) * kDEG, "pm.forced_F", "deg");
fmk_GP(pm.forced_wS, kRPM, "rpm");

fmt_GP(pm.forced_track_D, "A");
Expand All @@ -174,7 +174,7 @@ tlm_plot_grab()
fmt_GP(pm.flux_X[0], "Wb");
fmt_GP(pm.flux_X[1], "Wb");
fmt_GP(pm.flux_lambda, "Wb");
sym_GP(atan2(pm.flux_F[1], pm.flux_F[0]) * kDEG, "pm.flux_F", "°");
sym_GP(atan2(pm.flux_F[1], pm.flux_F[0]) * kDEG, "pm.flux_F", "deg");
fmk_GP(pm.flux_wS, kRPM, "rpm");

fmt_GP(pm.kalman_bias_Q, "V");
Expand All @@ -185,12 +185,12 @@ tlm_plot_grab()
fmt_GP(pm.hfi_wave[0], 0);
fmt_GP(pm.hfi_wave[1], 0);

sym_GP(atan2(pm.hall_F[1], pm.hall_F[0]) * kDEG, "pm.hall_F", "°");
sym_GP(atan2(pm.hall_F[1], pm.hall_F[0]) * kDEG, "pm.hall_F", "deg");
fmk_GP(pm.hall_wS, kRPM, "rpm");

fmt_GP(pm.eabi_ADJUST, 0);

sym_GP(atan2(pm.eabi_F[1], pm.eabi_F[0]) * kDEG, "pm.eabi_F", "°");
sym_GP(atan2(pm.eabi_F[1], pm.eabi_F[0]) * kDEG, "pm.eabi_F", "deg");
fmk_GP(pm.eabi_wS, kRPM, "rpm");

fmt_GP(pm.watt_DC_MAX, 0);
Expand Down Expand Up @@ -408,14 +408,16 @@ void bench_script()
ts_script_base();
blm_restart(&m);

pm.config_LU_ESTIMATE = PM_FLUX_KALMAN;

pm.fsm_req = PM_STATE_LU_STARTUP;
ts_wait_IDLE();

pm.s_setpoint_speed = 4000.f;
sim_runtime(1.0);

m.Udc = 30.;
m.Rdc = 50.;
//m.Udc = 30.;
//m.Rdc = 50.;

pm.watt_wP_reverse = 1000.f;
pm.watt_uDC_maximal = 48.f;
Expand All @@ -427,7 +429,7 @@ void bench_script()
//pm.s_track = 0.f;
sim_runtime(0.3);

m.Rdc = 1.;
//m.Rdc = 1.;
sim_runtime(0.5);

tlm_PWM_grab();
Expand Down
8 changes: 4 additions & 4 deletions bench/blm.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ void blm_enable(blm_t *m)
m->Ld = 11.E-6;
m->Lq = 16.E-6;

/* Flux linkage constant (Weber).
* */
m->lambda = blm_Kv_lambda(m, 270.);

/* Number of the rotor pole pairs.
* */
m->Zp = 14;

/* Flux linkage constant (Weber).
* */
m->lambda = blm_Kv_lambda(m, 270.);

/* Ambient temperature (Celsius).
* */
m->Ta = 25.;
Expand Down
32 changes: 19 additions & 13 deletions bench/tsfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,15 @@ void ts_probe_spinup()
if (ts_wait_IDLE() != PM_OK)
break;

if (pm.flux_LINKAGE != PM_ENABLED) {
if ( pm.flux_LINKAGE != PM_ENABLED
&& pm.config_EXCITATION == PM_EXCITATION_CONST) {

pm.s_setpoint_speed = pm.probe_speed_hold;

if (ts_wait_spinup() != PM_OK)
break;

printf("zone_lpf_wS = %.2f (rad/s)\n", pm.zone_lpf_wS);
sim_runtime(400 / (double) TS_TICK_RATE);

pm.fsm_req = PM_STATE_PROBE_CONST_FLUX_LINKAGE;

Expand All @@ -219,24 +220,22 @@ void ts_probe_spinup()
pm_auto(&pm, PM_AUTO_PROBE_SPEED_HOLD);
pm_auto(&pm, PM_AUTO_FORCED_MAXIMAL);

printf("probe_speed_hold = %.2f (rad/s)\n", pm.probe_speed_hold);
printf("forced_maximal = %.2f (rad/s)\n", pm.forced_maximal);

printf("zone_noise = %.2f (rad/s) %.3f (V)\n",
pm.zone_noise,
pm.zone_noise * pm.const_lambda);
pm.zone_noise * pm.const_lambda / pm.k_EMAX);

printf("zone_threshold = %.2f (rad/s) %.3f (V)\n",
pm.zone_threshold,
pm.zone_threshold * pm.const_lambda);

printf("probe_speed_hold = %.2f (rad/s)\n", pm.probe_speed_hold);
printf("forced_maximal = %.2f (rad/s)\n", pm.forced_maximal);
pm.zone_threshold * pm.const_lambda / pm.k_EMAX);

pm.s_setpoint_speed = pm.probe_speed_hold;

if (ts_wait_spinup() != PM_OK)
break;

printf("zone_lpf_wS = %.2f (rad/s)\n", pm.zone_lpf_wS);

if (pm.flux_ZONE != PM_ZONE_HIGH) {

pm.fsm_errno = PM_ERROR_NO_FLUX_CAUGHT;
Expand All @@ -245,6 +244,8 @@ void ts_probe_spinup()

if (pm.config_EXCITATION == PM_EXCITATION_CONST) {

sim_runtime(400 / (double) TS_TICK_RATE);

pm.fsm_req = PM_STATE_PROBE_CONST_FLUX_LINKAGE;

if (ts_wait_IDLE() != PM_OK)
Expand All @@ -257,20 +258,27 @@ void ts_probe_spinup()
TS_assert_relative(pm.const_lambda, m.lambda);
}

sim_runtime(400 / (double) TS_TICK_RATE);

pm.fsm_req = PM_STATE_PROBE_NOISE_THRESHOLD;

if (ts_wait_IDLE() != PM_OK)
break;

pm_auto(&pm, PM_AUTO_ZONE_THRESHOLD);
pm_auto(&pm, PM_AUTO_PROBE_SPEED_HOLD);
pm_auto(&pm, PM_AUTO_FORCED_MAXIMAL);

printf("probe_speed_hold = %.2f (rad/s)\n", pm.probe_speed_hold);
printf("forced_maximal = %.2f (rad/s)\n", pm.forced_maximal);

printf("zone_noise = %.2f (rad/s) %.3f (V)\n",
pm.zone_noise,
pm.zone_noise * pm.const_lambda);
pm.zone_noise * pm.const_lambda / pm.k_EMAX);

printf("zone_threshold = %.2f (rad/s) %.3f (V)\n",
pm.zone_threshold,
pm.zone_threshold * pm.const_lambda);
pm.zone_threshold * pm.const_lambda / pm.k_EMAX);

pm.fsm_req = PM_STATE_PROBE_CONST_INERTIA;

Expand All @@ -297,11 +305,9 @@ void ts_probe_spinup()
if (ts_wait_IDLE() != PM_OK)
break;

pm_auto(&pm, PM_AUTO_FORCED_MAXIMAL);
pm_auto(&pm, PM_AUTO_FORCED_ACCEL);
pm_auto(&pm, PM_AUTO_LOOP_SPEED);

printf("forced_maximal = %.2f (rad/s)\n", pm.forced_maximal);
printf("forced_accel = %.1f (rad/s2)\n", pm.forced_accel);
printf("lu_gain_mq_LP = %.2E\n", pm.lu_gain_mq_LP);
printf("s_gain_P = %.2E\n", pm.s_gain_P);
Expand Down
21 changes: 9 additions & 12 deletions doc/CommandLineInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ CLI with autocompletion function and command history.

These are the basic special keys that are used in the CLI:

- `Return` - Run the current line.
- `Return` - Run the command from current line.
- `Backspace` or `Delete` - Erase last typed character.
- `Tab` or (@) - Automplete function.
- `Shift` + `Tab` - Automplete function reverse.
- `Ctrl` + `C` or `Ctrl` + `D` - Drop the content of the line or abort the command.
- `Ctrl` + `P` or `Up` or `*` - History function scroll up.
- `Ctrl` + `N` or `Down` or `!` - History function scroll down.

## Register file concept
## Register file

A register is a scalar variable known by its name and having associated
attributes. All registers together are called the register file. This is a
Expand All @@ -26,8 +26,8 @@ command.
- Without arguments it will list all registers and their current values.
- You can specify a pattern by which registers will be filtered. A pattern can
be any part of the register name.
- If only one register matches the specified pattern the second parameter
specifies its new value.
- If only one register matches the specified pattern the second parameter can
specify its new value.
- You can specify a register number instead of its name to refer the exactly
one register.

Expand Down Expand Up @@ -64,7 +64,7 @@ registers that are required to configure data transfer between different
subsystems.

Keep in mind each register can have its own write and read event handler that
can do any complex non-obvious actions during access to it.
can do any non-obvious actions during access to it.

## Linkage concept

Expand All @@ -88,7 +88,7 @@ Command to grab telemetry into RAM and flush textual dump.
(pmc) tlm_grab <rate>
(pmc) tlm_flush_sync

Run an endless loop grabbing until PMC stops with error.
Run in endless loop of grabbing until PMC stops with error.

(pmc) tlm_watch <rate>

Expand All @@ -98,21 +98,18 @@ Use a real-time telemetry printout.

Using CAN data pipes you are able to link register across CAN network. You can
easily control many machines from single input. Build a traction control by
exchange the speed signals across PMC instances.
exchange the speed signals across PMC nodes.

## Textual transcription

Some of integer registers printed out accompanied by textual transcription that
describes register current value. Typically this is a configuration register
responsible for selecting one of several possible options. Note that you must
assign a new value to the register to find out its transcription.
responsible for selecting one of several possible options. The textual
transcription corresponds to the enumeration in the source code of PMC.

(pmc) reg pm.config_IFB
1 [151] pm.config_IFB = 2 (PM_IFB_ABC_INLINE)

The textual transcription corresponds to the enumeration constants in the
source code of PMC.

## Examples

Show all raw feedback values that PMC uses in control loops.
Expand Down
Loading

0 comments on commit 980ce02

Please sign in to comment.