Skip to content

Commit d4e1015

Browse files
committed
Implement 3-Stage Smoothing for Remote Tilt (Hardcoded)
Feature: Add 3-Stage Smoothing for Remote Tilt; > Parameters are hard-coded to serve remotes well
1 parent ea40338 commit d4e1015

7 files changed

Lines changed: 130 additions & 29 deletions

File tree

src/conf/datatypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ typedef struct {
199199
int8_t bms_ht_threshold;
200200
} CfgBMS;
201201

202+
typedef struct {
203+
float alpha;
204+
float in_alpha_away;
205+
float in_alpha_back;
206+
} CfgTargetFilter;
207+
202208
typedef struct {
203209
bool is_default;
204210
} CfgMeta;

src/data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ typedef struct {
104104
float noseangling_interpolated;
105105
time_t alert_timer;
106106
time_t nag_timer;
107+
float dt;
107108
float idle_voltage;
108109
time_t fault_angle_pitch_timer, fault_angle_roll_timer, fault_switch_timer,
109110
fault_switch_half_timer;

src/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ static void configure(Data *d) {
186186

187187
lcm_configure(&d->lcm, &d->float_conf.leds);
188188

189+
d->dt = 1.0f / d->float_conf.hertz;
190+
189191
// Loop time in microseconds
190192
d->loop_time_us = 1e6 / d->float_conf.hertz;
191193

@@ -874,7 +876,7 @@ static void refloat_thd(void *arg) {
874876
);
875877
d->setpoint = d->setpoint_target_interpolated;
876878

877-
remote_update(&d->remote, &d->state, &d->float_conf);
879+
remote_update(&d->remote, &d->state, &d->float_conf, d->dt);
878880
d->setpoint += d->remote.setpoint;
879881

880882
if (!d->state.darkride) {

src/remote.c

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,25 @@ void remote_init(Remote *remote) {
2828
void remote_reset(Remote *remote) {
2929
remote->setpoint = 0;
3030
remote->ramped_step_size = 0;
31+
32+
smooth_target_reset(&remote->smooth_target, 0.0f);
3133
}
3234

3335
void remote_configure(Remote *remote, const RefloatConfig *config) {
3436
remote->step_size = config->inputtilt_speed / config->hertz;
37+
38+
// Hardcoded target filter for remote
39+
static const CfgTargetFilter remote_target_filter = {
40+
.alpha = 0.020, .in_alpha_away = 0.050, .in_alpha_back = 0.015
41+
};
42+
43+
smooth_target_configure(
44+
&remote->smooth_target,
45+
&remote_target_filter,
46+
config->inputtilt_speed,
47+
config->inputtilt_speed,
48+
config->hertz
49+
);
3550
}
3651

3752
void remote_input(Remote *remote, const RefloatConfig *config) {
@@ -72,37 +87,13 @@ void remote_input(Remote *remote, const RefloatConfig *config) {
7287
remote->input = value;
7388
}
7489

75-
void remote_update(Remote *remote, const State *state, const RefloatConfig *config) {
90+
void remote_update(Remote *remote, const State *state, const RefloatConfig *config, float dt) {
7691
float target = remote->input * config->inputtilt_angle_limit;
7792

7893
if (state->darkride) {
7994
target = -target;
8095
}
8196

82-
float target_diff = target - remote->setpoint;
83-
84-
// Smoothen changes in tilt angle by ramping the step size
85-
const float smoothing_factor = 0.02;
86-
87-
// Within X degrees of Target Angle, start ramping down step size
88-
if (fabsf(target_diff) < 2.0f) {
89-
// Target step size is reduced the closer to center you are (needed for smoothly
90-
// transitioning away from center)
91-
remote->ramped_step_size = smoothing_factor * remote->step_size * target_diff / 2 +
92-
(1 - smoothing_factor) * remote->ramped_step_size;
93-
// Linearly ramped down step size is provided as minimum to prevent overshoot
94-
float centering_step_size =
95-
fminf(fabsf(remote->ramped_step_size), fabsf(target_diff / 2) * remote->step_size) *
96-
sign(target_diff);
97-
if (fabsf(target_diff) < fabsf(centering_step_size)) {
98-
remote->setpoint = target;
99-
} else {
100-
remote->setpoint += centering_step_size;
101-
}
102-
} else {
103-
// Ramp up step size until the configured tilt speed is reached
104-
remote->ramped_step_size = smoothing_factor * remote->step_size * sign(target_diff) +
105-
(1 - smoothing_factor) * remote->ramped_step_size;
106-
remote->setpoint += remote->ramped_step_size;
107-
}
97+
smooth_target_update(&remote->smooth_target, target);
98+
remote->setpoint = remote->smooth_target.value;
10899
}

src/remote.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
#pragma once
1919

2020
#include "conf/datatypes.h"
21+
#include "smooth_target.h"
2122
#include "state.h"
2223

2324
typedef struct {
2425
float step_size;
2526

2627
float input;
2728
float ramped_step_size;
29+
SmoothTarget smooth_target;
2830

2931
float setpoint;
3032
} Remote;
@@ -37,4 +39,4 @@ void remote_configure(Remote *remote, const RefloatConfig *config);
3739

3840
void remote_input(Remote *remote, const RefloatConfig *config);
3941

40-
void remote_update(Remote *remote, const State *state, const RefloatConfig *config);
42+
void remote_update(Remote *remote, const State *state, const RefloatConfig *config, float dt);

src/smooth_target.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2024 Lukas Hrazky
2+
//
3+
// This file is part of the Refloat VESC package.
4+
//
5+
// Refloat VESC package is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by the
7+
// Free Software Foundation, either version 3 of the License, or (at your
8+
// option) any later version.
9+
//
10+
// Refloat VESC package is distributed in the hope that it will be useful, but
11+
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12+
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+
// more details.
14+
//
15+
// You should have received a copy of the GNU General Public License along with
16+
// this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
#include "smooth_target.h"
19+
20+
#include "utils.h"
21+
22+
#include <math.h>
23+
24+
void smooth_target_configure(
25+
SmoothTarget *st, const CfgTargetFilter *cfg, float on_speed, float off_speed, float hertz
26+
) {
27+
st->cfg = *cfg;
28+
st->on_speed = on_speed / hertz;
29+
st->off_speed = off_speed / hertz;
30+
}
31+
32+
void smooth_target_reset(SmoothTarget *st, float value) {
33+
st->v1 = 0;
34+
st->step = 0;
35+
st->value = value;
36+
}
37+
38+
void smooth_target_update(SmoothTarget *st, float target) {
39+
st->v1 += st->cfg.alpha * (target - st->v1);
40+
41+
float delta = st->cfg.alpha * (st->v1 - st->value);
42+
43+
if (fabsf(delta) > fabsf(st->step) || sign(delta) != sign(st->step)) {
44+
if (sign(st->value) == sign(delta)) {
45+
st->step += st->cfg.in_alpha_away * (delta - st->step);
46+
} else {
47+
st->step += st->cfg.in_alpha_back * (delta - st->step);
48+
}
49+
} else {
50+
st->step = delta;
51+
}
52+
53+
float speed_limit;
54+
if (sign(st->step) == sign(st->value)) {
55+
speed_limit = st->on_speed;
56+
} else {
57+
speed_limit = st->off_speed;
58+
}
59+
60+
st->value += sign(st->step) * min(fabsf(st->step), speed_limit);
61+
}

src/smooth_target.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2024 Lukas Hrazky
2+
//
3+
// This file is part of the Refloat VESC package.
4+
//
5+
// Refloat VESC package is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by the
7+
// Free Software Foundation, either version 3 of the License, or (at your
8+
// option) any later version.
9+
//
10+
// Refloat VESC package is distributed in the hope that it will be useful, but
11+
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12+
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13+
// more details.
14+
//
15+
// You should have received a copy of the GNU General Public License along with
16+
// this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
#pragma once
19+
20+
#include "conf/datatypes.h"
21+
22+
typedef struct {
23+
CfgTargetFilter cfg;
24+
float on_speed;
25+
float off_speed;
26+
27+
float v1;
28+
float step;
29+
float value;
30+
} SmoothTarget;
31+
32+
void smooth_target_configure(
33+
SmoothTarget *st, const CfgTargetFilter *cfg, float on_speed, float off_speed, float hertz
34+
);
35+
36+
void smooth_target_reset(SmoothTarget *st, float value);
37+
38+
void smooth_target_update(SmoothTarget *st, float target);

0 commit comments

Comments
 (0)