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};
63
65{
66 uint8_t drvtype = 0;
67 uint8_t enctype = 0;
68 //bool invert = false;
69};
70struct metric_t {
71 float accel = 0; // in deg/s²
72 float speed = 0; // in deg/s
73 int32_t pos = 0; // scaled position as 16b int -0x7fff to 0x7fff
74 float pos_f = 0; // scaled position as float. -1 to 1 range
75 float posDegrees = 0; // Position in degrees. Not scaled to selected range
76 int32_t torque = 0; // total of effect + endstop torque
77};
78
79
83};
84
86 uint8_t denominator = 0;
87 uint8_t numerator = 0;
88 float gearRatio = 1.0;
89};
90
91
92enum class Axis_commands : uint32_t{
96};
97
98class Axis : public PersistentStorage, public CommandHandler, public ErrorHandler
99{
100public:
101 Axis(char axis, volatile Control_t* control);
102 virtual ~Axis();
103
105 const ClassIdentifier getInfo();
106 const ClassType getClassType() override {return ClassType::Axis;};
107
108 virtual std::string getHelpstring() { return "FFB axis" ;}
109#ifdef TMC4671DRIVER
110 void setupTMC4671();
111#endif
112 // Dynamic classes
113 void setDrvType(uint8_t drvtype);
114 void setEncType(uint8_t enctype);
115 uint8_t getDrvType();
116 uint8_t getEncType();
117
120
121 void usbSuspend(); // Called on usb disconnect and suspend
122 void usbResume(); // Called on usb resume
123
124 void saveFlash() override;
125 void restoreFlash() override;
126
127 void prepareForUpdate(); // called before the effects are calculated
128 void updateDriveTorque(); //int32_t effectTorque);
129 void emergencyStop(bool reset);
130
131 void setPos(uint16_t val);
132 void zeroPos();
133
135
136 std::pair<int32_t,float> scaleEncValue(float angle, uint16_t degrees);
137 float getEncAngle(Encoder *enc);
138
139
140 void setPower(uint16_t power);
141
142
143 void errorCallback(const Error &error, bool cleared) override;
144
145 //ParseStatus command(ParsedCommand_old* cmd,std::string* reply) override;
146 void registerCommands();
147 CommandStatus command(const ParsedCommand& cmd,std::vector<CommandReply>& replies);
148
151
152 int32_t getLastScaledEnc();
153 void resetMetrics(float new_pos);
154 void updateMetrics(float new_pos);
155 int32_t updateIdleSpringForce();
156 void setIdleSpringStrength(uint8_t spring);
157 void setFxStrengthAndFilter(uint8_t val,uint8_t& valToSet, Biquad& filter);
158 void calculateAxisEffects(bool ffb_on);
159 int32_t getTorque(); // current torque scaled as a 32 bit signed value
160 int16_t updateEndstop();
161
162 void startForceFadeIn(float start = 0,float fadeTime = 0.5);
163
165
166 void setEffectTorque(int32_t torque);
167 bool updateTorque(int32_t* totalTorque);
168
169 void setGearRatio(uint8_t numerator,uint8_t denominator);
170
171 static const std::vector<class_entry<MotorDriver>> axis1_drivers;
172 static const std::vector<class_entry<MotorDriver>> axis2_drivers;
173
174private:
175 // Axis damper is lower than default scale of HID Damper
176 const float AXIS_DAMPER_RATIO = INTERNAL_SCALER_DAMPER * INTERNAL_AXIS_DAMPER_SCALER / 255.0;
177 const float AXIS_INERTIA_RATIO = INTERNAL_SCALER_INERTIA * INTERNAL_AXIS_INERTIA_SCALER / 255.0;
178
181
182 //TIM_HandleTypeDef *timer_update;
184
185 std::unique_ptr<MotorDriver> drv = std::make_unique<MotorDriver>(); // dummy
186 std::shared_ptr<Encoder> enc = nullptr;
187
188 bool outOfBounds = false;
189
190 static AxisConfig decodeConfFromInt(uint16_t val);
191 static uint16_t encodeConfToInt(AxisConfig conf);
192
194
195 float forceFadeTime = 1.0;
196 float forceFadeCurMult = 1.0;
197
198#ifdef TMC4671DRIVER
199 TMC4671Limits tmclimits = TMC4671Limits({.pid_torque_flux_ddt = 32767,
200 .pid_uq_ud = 30000,
201 .pid_torque_flux = 30000,
202 .pid_acc_lim = 2147483647,
203 .pid_vel_lim = 2147483647,
204 .pid_pos_low = -2147483647,
205 .pid_pos_high = 2147483647});
206#endif
207 float encoderOffset = 0; // Offset for absolute encoders
208 uint16_t degreesOfRotation = 900; // How many degrees of range for the full gamepad range
209 uint16_t lastdegreesOfRotation = degreesOfRotation; // Used to store the previous value
210 uint16_t nextDegreesOfRotation = degreesOfRotation; // Buffer when changing range
211
212 // Limiters
213 uint16_t maxSpeedDegS = 0; // Set to non zero to enable. example 1000. 8b * 10?
214 //float maxAccelDegSS = 0;
215 uint32_t maxTorqueRateMS = 0; // 8b * 128?
216 float speedLimiterP = AXIS_SPEEDLIMITER_P;
217 float speedLimiterI = AXIS_SPEEDLIMITER_I;
218
220 //float acclimitreducerI = 0;
221 //const uint8_t accelFactor = 10.0; // Conversion factor between internal and external acc limit
222
223 void setDegrees(uint16_t degrees);
224
225 uint16_t getPower();
226 float getTorqueScaler();
227 bool isInverted();
228 char axis;
229
230
231 // Merge normalized
233 float _lastSpeed = 0;
234 int32_t effectTorque = 0;
235 int32_t axisEffectTorque = 0;
236 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
237 uint16_t power = 5000;
238 float torqueScaler = 0; // power * fx_ratio as a ratio between 0 & 1
240 bool invertAxis = true; // By default most motors and encoders count up CCW while gamepads are counting up CW.
241 uint8_t endstopStrength = 127; // Sets how much extra torque per count above endstop is added. High = stiff endstop. Low = softer
242 const float endstopGain = 25; // Overall max endstop intensity
243
244
245 uint8_t idlespringstrength = 127;
246 int16_t idlespringclip = 0;
248 bool motorWasNotReady = true;
249
250 // TODO tune these and check if it is really stable and beneficial to the FFB. index 4 placeholder
251 const std::array<biquad_constant_t,4> filterSpeedCst = { {{ 40, 55 }, { 70, 55 }, { 120, 55 }, {180, 55}} };
252 const std::array<biquad_constant_t,4> filterAccelCst = { {{ 40, 30 }, { 55, 30 }, { 70, 30 }, {120, 55}} };
256 uint8_t filterProfileId = 1; // Default medium (1) as this is the most common encoder resolution and users can go lower or higher if required.
257 const float filter_f = 1000; // 1khz
258 const int32_t intFxClip = 20000;
259 uint8_t damperIntensity = 30;
260
261 uint8_t frictionIntensity = 0;
262 uint8_t inertiaIntensity = 0;
263
269
270
271 void setFxRatio(uint8_t val);
272 void updateTorqueScaler();
273
274
276
277};
278
279#endif /* SRC_AXIS_H_ */
Axis_commands
Definition: Axis.h:92
ClassType
Definition: ClassIDs.h:12
CommandStatus
Definition: Axis.h:99
float forceFadeTime
Definition: Axis.h:195
float effect_margin_scaler
Definition: Axis.h:239
float getTorqueScaler()
Definition: Axis.cpp:663
void errorCallback(const Error &error, bool cleared) override
Definition: Axis.cpp:342
const std::array< biquad_constant_t, 4 > filterAccelCst
Definition: Axis.h:252
float getEncAngle(Encoder *enc)
Definition: Axis.cpp:489
uint8_t idlespringstrength
Definition: Axis.h:245
const biquad_constant_t filterFrictionCst
Definition: Axis.h:254
float speedLimiterI
Definition: Axis.h:217
AxisFlashAddrs flashAddrs
Definition: Axis.h:179
void startForceFadeIn(float start=0, float fadeTime=0.5)
Definition: Axis.cpp:767
int32_t getTorque()
Definition: Axis.cpp:668
axis_metric_t metric
Definition: Axis.h:232
void setEffectTorque(int32_t torque)
Definition: Axis.cpp:689
GearRatio_t gearRatio
Definition: Axis.h:275
bool isInverted()
Definition: Axis.cpp:670
uint16_t nextDegreesOfRotation
Definition: Axis.h:210
Axis(char axis, volatile Control_t *control)
Definition: Axis.cpp:88
uint8_t endstopStrength
Definition: Axis.h:241
float forceFadeCurMult
Definition: Axis.h:196
float torqueScaler
Definition: Axis.h:238
char axis
Definition: Axis.h:228
ClassChooser< MotorDriver > drv_chooser
Definition: Axis.h:149
uint8_t frictionIntensity
Definition: Axis.h:261
void setFxStrengthAndFilter(uint8_t val, uint8_t &valToSet, Biquad &filter)
Definition: Axis.cpp:566
int32_t updateIdleSpringForce()
Definition: Axis.cpp:550
void setDegrees(uint16_t degrees)
Definition: Axis.cpp:776
void calculateAxisEffects(bool ffb_on)
Definition: Axis.cpp:577
bool updateTorque(int32_t *totalTorque)
Definition: Axis.cpp:697
uint8_t damperIntensity
Definition: Axis.h:259
uint8_t filterProfileId
Definition: Axis.h:256
uint16_t getPower()
Definition: Axis.cpp:654
uint8_t getEncType()
Definition: Axis.cpp:263
volatile Control_t * control
Definition: Axis.h:180
std::pair< int32_t, float > scaleEncValue(float angle, uint16_t degrees)
Definition: Axis.cpp:475
void setIdleSpringStrength(uint8_t spring)
Definition: Axis.cpp:557
virtual std::string getHelpstring()
Definition: Axis.h:108
const float filter_f
Definition: Axis.h:257
bool motorWasNotReady
Definition: Axis.h:248
uint16_t lastdegreesOfRotation
Definition: Axis.h:209
float idlespringscale
Definition: Axis.h:247
void usbSuspend()
Definition: Axis.cpp:517
const Error outOfBoundsError
Definition: Axis.h:193
Biquad speedFilter
Definition: Axis.h:264
const ClassType getClassType() override
Definition: Axis.h:106
void setPower(uint16_t power)
Definition: Axis.cpp:360
MotorDriver * getDriver()
Definition: Axis.cpp:279
virtual ~Axis()
Definition: Axis.cpp:123
static const std::vector< class_entry< MotorDriver > > axis1_drivers
Definition: Axis.h:171
AxisConfig conf
Definition: Axis.h:183
static const std::vector< class_entry< MotorDriver > > axis2_drivers
Definition: Axis.h:172
void updateMetrics(float new_pos)
Definition: Axis.cpp:636
static uint16_t encodeConfToInt(AxisConfig conf)
Definition: Axis.cpp:1021
void resetMetrics(float new_pos)
Definition: Axis.cpp:623
int16_t updateEndstop()
Definition: Axis.cpp:677
const int32_t intFxClip
Definition: Axis.h:258
Biquad damperFilter
Definition: Axis.h:266
void registerCommands()
Definition: Axis.cpp:133
Encoder * getEncoder()
Definition: Axis.cpp:283
void setupTMC4671()
Definition: Axis.cpp:418
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
Definition: Axis.cpp:788
void setFxRatio(uint8_t val)
Definition: Axis.cpp:615
ClassChooser< Encoder > enc_chooser
Definition: Axis.h:150
static ClassIdentifier info
Definition: Axis.h:104
const float endstopGain
Definition: Axis.h:242
void setEncType(uint8_t enctype)
Definition: Axis.cpp:440
Biquad frictionFilter
Definition: Axis.h:267
const biquad_constant_t filterDamperCst
Definition: Axis.h:253
uint16_t power
Definition: Axis.h:237
Biquad accelFilter
Definition: Axis.h:265
metric_t * getMetrics()
Definition: Axis.cpp:536
void setPos(uint16_t val)
Definition: Axis.cpp:271
float speedLimiterP
Definition: Axis.h:216
bool outOfBounds
Definition: Axis.h:188
bool getFfbActive()
std::shared_ptr< Encoder > enc
Definition: Axis.h:186
int32_t axisEffectTorque
Definition: Axis.h:235
bool invertAxis
Definition: Axis.h:240
int32_t getLastScaledEnc()
Definition: Axis.cpp:543
float encoderOffset
Definition: Axis.h:207
void restoreFlash() override
Definition: Axis.cpp:165
std::unique_ptr< MotorDriver > drv
Definition: Axis.h:185
uint8_t inertiaIntensity
Definition: Axis.h:262
void setGearRatio(uint8_t numerator, uint8_t denominator)
Definition: Axis.cpp:464
uint16_t degreesOfRotation
Definition: Axis.h:208
const biquad_constant_t filterInertiaCst
Definition: Axis.h:255
int32_t effectTorque
Definition: Axis.h:234
int16_t idlespringclip
Definition: Axis.h:246
void updateDriveTorque()
Definition: Axis.cpp:350
void setDrvType(uint8_t drvtype)
Definition: Axis.cpp:380
void saveFlash() override
Definition: Axis.cpp:240
void zeroPos()
float spdlimitreducerI
Definition: Axis.h:219
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
Definition: Axis.cpp:128
void usbResume()
Definition: Axis.cpp:527
void emergencyStop(bool reset)
Definition: Axis.cpp:505
const float AXIS_DAMPER_RATIO
Definition: Axis.h:176
static AxisConfig decodeConfFromInt(uint16_t val)
Definition: Axis.cpp:1012
TMC4671Limits tmclimits
Definition: Axis.h:199
const std::array< biquad_constant_t, 4 > filterSpeedCst
Definition: Axis.h:251
uint8_t fx_ratio_i
Definition: Axis.h:236
uint32_t maxTorqueRateMS
Definition: Axis.h:215
const float AXIS_INERTIA_RATIO
Definition: Axis.h:177
uint16_t maxSpeedDegS
Definition: Axis.h:213
void updateTorqueScaler()
Definition: Axis.cpp:658
void prepareForUpdate()
Definition: Axis.cpp:290
uint8_t getDrvType()
Definition: Axis.cpp:259
float _lastSpeed
Definition: Axis.h:233
Biquad inertiaFilter
Definition: Axis.h:268
Definition: Filters.h:31
uint8_t drvtype
Definition: Axis.h:66
uint8_t enctype
Definition: Axis.h:67
uint16_t maxAccel
Definition: Axis.h:52
uint16_t config
Definition: Axis.h:50
uint16_t endstop
Definition: Axis.h:54
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:86
uint8_t numerator
Definition: Axis.h:87
float gearRatio
Definition: Axis.h:88
metric_t current
Definition: Axis.h:81
metric_t previous
Definition: Axis.h:82
uint16_t freq
Definition: Filters.h:16
Definition: Axis.h:70
float posDegrees
Definition: Axis.h:75
int32_t torque
Definition: Axis.h:76
float accel
Definition: Axis.h:71
float speed
Definition: Axis.h:72
int32_t pos
Definition: Axis.h:73
float pos_f
Definition: Axis.h:74