Open FFBoard
Open source force feedback firmware
Axis.h
Go to the documentation of this file.
1/*
2 * Axis.h
3 *
4 * Created on: 21.01.2021
5 * Author: Yannick / Lidders
6 */
7
8#ifndef SRC_AXIS_H_
9#define SRC_AXIS_H_
10#include <FFBoardMain.h>
11#include <MotorPWM.h>
12#include "usb_hid_ffb_desc.h"
13#include "TMC4671.h"
14#include "PersistentStorage.h"
15#include "ButtonSource.h"
16#include "EncoderLocal.h"
17#include "LocalAnalog.h"
18#include "AnalogSource.h"
19
20#include "HidFFB.h"
21#include "ffb_defs.h"
22#include "TimerHandler.h"
23#include "ClassChooser.h"
24#include "ExtiHandler.h"
25#include "EffectsCalculator.h"
26
27#define INTERNAL_AXIS_DAMPER_SCALER 0.7
28#define INTERNAL_AXIS_FRICTION_SCALER 0.7
29#define INTERNAL_AXIS_INERTIA_SCALER 0.7
30#ifndef AXIS_SPEEDLIMITER_P
31#define AXIS_SPEEDLIMITER_P 0.3
32#endif
33#ifndef AXIS_SPEEDLIMITER_I
34#define AXIS_SPEEDLIMITER_I 0.03
35#endif
36
37
38struct Control_t {
39 bool emergency = false;
40 bool usb_disabled = true;
41 bool update_disabled = true;
43// bool usb_update_flag = false;
44// bool update_flag = false;
45 bool resetEncoder = false;
46};
47
49{
50 uint16_t config = ADR_AXIS1_CONFIG;
51 uint16_t maxSpeed = ADR_AXIS1_MAX_SPEED;
52 uint16_t maxAccel = ADR_AXIS1_MAX_ACCEL;
53
54 uint16_t endstop = ADR_AXIS1_ENDSTOP;
55 uint16_t power = ADR_AXIS1_POWER;
56 uint16_t degrees = ADR_AXIS1_DEGREES;
57 uint16_t effects1 = ADR_AXIS1_EFFECTS1;
58 uint16_t effects2 = ADR_AXIS1_EFFECTS2;
59 uint16_t encoderRatio = ADR_AXIS1_ENC_RATIO;
60
61 uint16_t speedAccelFilter = ADR_AXIS1_SPEEDACCEL_FILTER;
62 uint16_t postprocess1 = ADR_AXIS1_POSTPROCESS1;
63};
64
66{
67 uint8_t drvtype = 0;
68 uint8_t enctype = 0;
69 //bool invert = false;
70};
71struct metric_t {
72 float accel = 0; // in deg/s²
73 float speed = 0; // in deg/s
74 int32_t pos = 0; // scaled position as 16b int -0x7fff to 0x7fff
75 float pos_f = 0; // scaled position as float. -1 to 1 range
76 float posDegrees = 0; // Position in degrees. Not scaled to selected range
77 int32_t torque = 0; // total of effect + endstop torque
78};
79
80
84};
85
87 uint8_t denominator = 0;
88 uint8_t numerator = 0;
89 float gearRatio = 1.0;
90};
91
92
93enum class Axis_commands : uint32_t{
98};
99
100class Axis : public PersistentStorage, public CommandHandler, public ErrorHandler
101{
102public:
103 Axis(char axis, volatile Control_t* control);
104 virtual ~Axis();
105
107 const ClassIdentifier getInfo();
108 const ClassType getClassType() override {return ClassType::Axis;};
109
110 virtual std::string getHelpstring() { return "FFB axis" ;}
111#ifdef TMC4671DRIVER
112 void setupTMC4671();
113#endif
114 // Dynamic classes
115 void setDrvType(uint8_t drvtype);
116 void setEncType(uint8_t enctype);
117 uint8_t getDrvType();
118 uint8_t getEncType();
119
122
123 void usbSuspend(); // Called on usb disconnect and suspend
124 void usbResume(); // Called on usb resume
125
126 void saveFlash() override;
127 void restoreFlash() override;
128
129 void prepareForUpdate(); // called before the effects are calculated
130 void updateDriveTorque(); //int32_t effectTorque);
131 void emergencyStop(bool reset);
132
133 void setPos(uint16_t val);
134 void zeroPos();
135
137
138 std::pair<int32_t,float> scaleEncValue(float angle, uint16_t degrees);
139 float getEncAngle(Encoder *enc);
140
141
142 void setPower(uint16_t power);
143
144
145 void errorCallback(const Error &error, bool cleared) override;
146
147 //ParseStatus command(ParsedCommand_old* cmd,std::string* reply) override;
148 void registerCommands();
149 CommandStatus command(const ParsedCommand& cmd,std::vector<CommandReply>& replies);
150
153
154 int32_t getLastScaledEnc();
155 void resetMetrics(float new_pos);
156 void updateMetrics(float new_pos);
157 int32_t updateIdleSpringForce();
158 void setIdleSpringStrength(uint8_t spring);
159 void setFxStrengthAndFilter(uint8_t val,uint8_t& valToSet, Biquad& filter);
160 void calculateAxisEffects(bool ffb_on);
161 int32_t getTorque(); // current torque scaled as a 32 bit signed value
162 int16_t updateEndstop();
163
164 int32_t calculateExpoTorque(int32_t torque);
165
166 void startForceFadeIn(float start = 0,float fadeTime = 0.5);
167
169
170 void setEffectTorque(int32_t torque);
171 bool updateTorque(int32_t* totalTorque);
172
173
174 void setGearRatio(uint8_t numerator,uint8_t denominator);
175
176 static const std::vector<class_entry<MotorDriver>> axis1_drivers;
177 static const std::vector<class_entry<MotorDriver>> axis2_drivers;
178
179private:
180 // Axis damper is lower than default scale of HID Damper
181 const float AXIS_DAMPER_RATIO = INTERNAL_SCALER_DAMPER * INTERNAL_AXIS_DAMPER_SCALER / 255.0;
182 const float AXIS_INERTIA_RATIO = INTERNAL_SCALER_INERTIA * INTERNAL_AXIS_INERTIA_SCALER / 255.0;
183
186
187 //TIM_HandleTypeDef *timer_update;
189
190 std::unique_ptr<MotorDriver> drv = std::make_unique<MotorDriver>(); // dummy
191 std::shared_ptr<Encoder> enc = nullptr;
192
193 bool outOfBounds = false;
194
195 static AxisConfig decodeConfFromInt(uint16_t val);
196 static uint16_t encodeConfToInt(AxisConfig conf);
197
199
200 float forceFadeTime = 1.0;
201 float forceFadeCurMult = 1.0;
202
203#ifdef TMC4671DRIVER
204 TMC4671Limits tmclimits = TMC4671Limits({.pid_torque_flux_ddt = 32767,
205 .pid_uq_ud = 30000,
206 .pid_torque_flux = 30000,
207 .pid_acc_lim = 2147483647,
208 .pid_vel_lim = 2147483647,
209 .pid_pos_low = -2147483647,
210 .pid_pos_high = 2147483647});
211#endif
212 float encoderOffset = 0; // Offset for absolute encoders
213 uint16_t degreesOfRotation = 900; // How many degrees of range for the full gamepad range
214 uint16_t lastdegreesOfRotation = degreesOfRotation; // Used to store the previous value
215 uint16_t nextDegreesOfRotation = degreesOfRotation; // Buffer when changing range
216
217 // Limiters
218 uint16_t maxSpeedDegS = 0; // Set to non zero to enable. example 1000. 8b * 10?
219 //float maxAccelDegSS = 0;
220 uint32_t maxTorqueRateMS = 0; // 8b * 128?
221 float speedLimiterP = AXIS_SPEEDLIMITER_P;
222 float speedLimiterI = AXIS_SPEEDLIMITER_I;
223
225 //float acclimitreducerI = 0;
226 //const uint8_t accelFactor = 10.0; // Conversion factor between internal and external acc limit
227
228 void setDegrees(uint16_t degrees);
229
230 uint16_t getPower();
231 float getTorqueScaler();
232 bool isInverted();
233 char axis;
234
235
236 // Merge normalized
238 float _lastSpeed = 0;
239 int32_t effectTorque = 0;
240 int32_t axisEffectTorque = 0;
241 uint8_t fx_ratio_i = 204; // Reduce effects to a certain ratio of the total power to have a margin for the endstop. 80% = 204
242 uint16_t power = 5000;
243 float torqueScaler = 0; // power * fx_ratio as a ratio between 0 & 1
245 bool invertAxis = true; // By default most motors and encoders count up CCW while gamepads are counting up CW.
246 uint8_t endstopStrength = 127; // Sets how much extra torque per count above endstop is added. High = stiff endstop. Low = softer
247 const float endstopGain = 25; // Overall max endstop intensity
248
249
250 uint8_t idlespringstrength = 127;
251 int16_t idlespringclip = 0;
253 bool motorWasNotReady = true;
254
255 // TODO tune these and check if it is really stable and beneficial to the FFB. index 4 placeholder
256 const std::array<biquad_constant_t,4> filterSpeedCst = { {{ 40, 55 }, { 70, 55 }, { 120, 55 }, {180, 55}} };
257 const std::array<biquad_constant_t,4> filterAccelCst = { {{ 40, 30 }, { 55, 30 }, { 70, 30 }, {120, 55}} };
261 uint8_t filterProfileId = 1; // Default medium (1) as this is the most common encoder resolution and users can go lower or higher if required.
262 const float filter_f = 1000; // 1khz
263 const int32_t intFxClip = 20000;
264 uint8_t damperIntensity = 30;
265
266 uint8_t frictionIntensity = 0;
267 uint8_t inertiaIntensity = 0;
268
274
275
276 void setFxRatio(uint8_t val);
277 void updateTorqueScaler();
278
279 void setExpo(int val);
280
281
283
284 int expoValInt = 0; // expo v = val*2 => v<0 ? 1/-v : v
285 float expo = 1;
286 float expoScaler = 50; // 0.28 to 3.54
287
288};
289
290#endif /* SRC_AXIS_H_ */
Axis_commands
Definition: Axis.h:93
ClassType
Definition: ClassIDs.h:12
CommandStatus
Definition: Axis.h:101
float forceFadeTime
Definition: Axis.h:200
float effect_margin_scaler
Definition: Axis.h:244
float getTorqueScaler()
Definition: Axis.cpp:686
void errorCallback(const Error &error, bool cleared) override
Definition: Axis.cpp:353
const std::array< biquad_constant_t, 4 > filterAccelCst
Definition: Axis.h:257
float getEncAngle(Encoder *enc)
Definition: Axis.cpp:500
uint8_t idlespringstrength
Definition: Axis.h:250
const biquad_constant_t filterFrictionCst
Definition: Axis.h:259
float speedLimiterI
Definition: Axis.h:222
AxisFlashAddrs flashAddrs
Definition: Axis.h:184
void startForceFadeIn(float start=0, float fadeTime=0.5)
Definition: Axis.cpp:794
int32_t getTorque()
Definition: Axis.cpp:691
axis_metric_t metric
Definition: Axis.h:237
void setEffectTorque(int32_t torque)
Definition: Axis.cpp:712
GearRatio_t gearRatio
Definition: Axis.h:282
bool isInverted()
Definition: Axis.cpp:693
uint16_t nextDegreesOfRotation
Definition: Axis.h:215
Axis(char axis, volatile Control_t *control)
Definition: Axis.cpp:88
uint8_t endstopStrength
Definition: Axis.h:246
float forceFadeCurMult
Definition: Axis.h:201
float torqueScaler
Definition: Axis.h:243
char axis
Definition: Axis.h:233
ClassChooser< MotorDriver > drv_chooser
Definition: Axis.h:151
uint8_t frictionIntensity
Definition: Axis.h:266
void setFxStrengthAndFilter(uint8_t val, uint8_t &valToSet, Biquad &filter)
Definition: Axis.cpp:577
int32_t updateIdleSpringForce()
Definition: Axis.cpp:561
void setDegrees(uint16_t degrees)
Definition: Axis.cpp:803
void calculateAxisEffects(bool ffb_on)
Definition: Axis.cpp:588
bool updateTorque(int32_t *totalTorque)
Definition: Axis.cpp:720
uint8_t damperIntensity
Definition: Axis.h:264
uint8_t filterProfileId
Definition: Axis.h:261
uint16_t getPower()
Definition: Axis.cpp:665
uint8_t getEncType()
Definition: Axis.cpp:274
volatile Control_t * control
Definition: Axis.h:185
std::pair< int32_t, float > scaleEncValue(float angle, uint16_t degrees)
Definition: Axis.cpp:486
void setIdleSpringStrength(uint8_t spring)
Definition: Axis.cpp:568
virtual std::string getHelpstring()
Definition: Axis.h:110
const float filter_f
Definition: Axis.h:262
bool motorWasNotReady
Definition: Axis.h:253
uint16_t lastdegreesOfRotation
Definition: Axis.h:214
float idlespringscale
Definition: Axis.h:252
void usbSuspend()
Definition: Axis.cpp:528
const Error outOfBoundsError
Definition: Axis.h:198
Biquad speedFilter
Definition: Axis.h:269
const ClassType getClassType() override
Definition: Axis.h:108
void setPower(uint16_t power)
Definition: Axis.cpp:371
MotorDriver * getDriver()
Definition: Axis.cpp:290
virtual ~Axis()
Definition: Axis.cpp:123
static const std::vector< class_entry< MotorDriver > > axis1_drivers
Definition: Axis.h:176
AxisConfig conf
Definition: Axis.h:188
static const std::vector< class_entry< MotorDriver > > axis2_drivers
Definition: Axis.h:177
void updateMetrics(float new_pos)
Definition: Axis.cpp:647
static uint16_t encodeConfToInt(AxisConfig conf)
Definition: Axis.cpp:1071
void resetMetrics(float new_pos)
Definition: Axis.cpp:634
int16_t updateEndstop()
Definition: Axis.cpp:700
const int32_t intFxClip
Definition: Axis.h:263
Biquad damperFilter
Definition: Axis.h:271
void registerCommands()
Definition: Axis.cpp:133
Encoder * getEncoder()
Definition: Axis.cpp:294
void setupTMC4671()
Definition: Axis.cpp:429
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
Definition: Axis.cpp:830
void setFxRatio(uint8_t val)
Definition: Axis.cpp:626
ClassChooser< Encoder > enc_chooser
Definition: Axis.h:152
static ClassIdentifier info
Definition: Axis.h:106
const float endstopGain
Definition: Axis.h:247
void setEncType(uint8_t enctype)
Definition: Axis.cpp:451
Biquad frictionFilter
Definition: Axis.h:272
const biquad_constant_t filterDamperCst
Definition: Axis.h:258
uint16_t power
Definition: Axis.h:242
Biquad accelFilter
Definition: Axis.h:270
metric_t * getMetrics()
Definition: Axis.cpp:547
void setPos(uint16_t val)
Definition: Axis.cpp:282
float expo
Definition: Axis.h:285
float speedLimiterP
Definition: Axis.h:221
bool outOfBounds
Definition: Axis.h:193
int32_t calculateExpoTorque(int32_t torque)
Definition: Axis.cpp:672
bool getFfbActive()
std::shared_ptr< Encoder > enc
Definition: Axis.h:191
float expoScaler
Definition: Axis.h:286
int32_t axisEffectTorque
Definition: Axis.h:240
bool invertAxis
Definition: Axis.h:245
int32_t getLastScaledEnc()
Definition: Axis.cpp:554
float encoderOffset
Definition: Axis.h:212
void restoreFlash() override
Definition: Axis.cpp:167
std::unique_ptr< MotorDriver > drv
Definition: Axis.h:190
uint8_t inertiaIntensity
Definition: Axis.h:267
void setGearRatio(uint8_t numerator, uint8_t denominator)
Definition: Axis.cpp:475
uint16_t degreesOfRotation
Definition: Axis.h:213
const biquad_constant_t filterInertiaCst
Definition: Axis.h:260
void setExpo(int val)
Definition: Axis.cpp:815
int32_t effectTorque
Definition: Axis.h:239
int16_t idlespringclip
Definition: Axis.h:251
void updateDriveTorque()
Definition: Axis.cpp:361
void setDrvType(uint8_t drvtype)
Definition: Axis.cpp:391
void saveFlash() override
Definition: Axis.cpp:247
void zeroPos()
float spdlimitreducerI
Definition: Axis.h:224
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
Definition: Axis.cpp:128
void usbResume()
Definition: Axis.cpp:538
void emergencyStop(bool reset)
Definition: Axis.cpp:516
const float AXIS_DAMPER_RATIO
Definition: Axis.h:181
static AxisConfig decodeConfFromInt(uint16_t val)
Definition: Axis.cpp:1062
TMC4671Limits tmclimits
Definition: Axis.h:204
int expoValInt
Definition: Axis.h:284
const std::array< biquad_constant_t, 4 > filterSpeedCst
Definition: Axis.h:256
uint8_t fx_ratio_i
Definition: Axis.h:241
uint32_t maxTorqueRateMS
Definition: Axis.h:220
const float AXIS_INERTIA_RATIO
Definition: Axis.h:182
uint16_t maxSpeedDegS
Definition: Axis.h:218
void updateTorqueScaler()
Definition: Axis.cpp:681
void prepareForUpdate()
Definition: Axis.cpp:301
uint8_t getDrvType()
Definition: Axis.cpp:270
float _lastSpeed
Definition: Axis.h:238
Biquad inertiaFilter
Definition: Axis.h:273
Definition: Filters.h:31
uint8_t drvtype
Definition: Axis.h:67
uint8_t enctype
Definition: Axis.h:68
uint16_t maxAccel
Definition: Axis.h:52
uint16_t config
Definition: Axis.h:50
uint16_t endstop
Definition: Axis.h:54
uint16_t postprocess1
Definition: Axis.h:62
uint16_t maxSpeed
Definition: Axis.h:51
uint16_t degrees
Definition: Axis.h:56
uint16_t encoderRatio
Definition: Axis.h:59
uint16_t speedAccelFilter
Definition: Axis.h:61
uint16_t effects2
Definition: Axis.h:58
uint16_t effects1
Definition: Axis.h:57
uint16_t power
Definition: Axis.h:55
Definition: Axis.h:38
bool update_disabled
Definition: Axis.h:41
bool usb_disabled
Definition: Axis.h:40
bool emergency
Definition: Axis.h:39
bool request_update_disabled
Definition: Axis.h:42
bool resetEncoder
Definition: Axis.h:45
uint8_t denominator
Definition: Axis.h:87
uint8_t numerator
Definition: Axis.h:88
float gearRatio
Definition: Axis.h:89
metric_t current
Definition: Axis.h:82
metric_t previous
Definition: Axis.h:83
uint16_t freq
Definition: Filters.h:16
Definition: Axis.h:71
float posDegrees
Definition: Axis.h:76
int32_t torque
Definition: Axis.h:77
float accel
Definition: Axis.h:72
float speed
Definition: Axis.h:73
int32_t pos
Definition: Axis.h:74
float pos_f
Definition: Axis.h:75