Open FFBoard
Open source force feedback firmware
Loading...
Searching...
No Matches
EffectsCalculator.h
Go to the documentation of this file.
1/*
2 * EffectsCalculator.h
3 *
4 * Created on: 27.01.2021
5 * Author: Yannick / Jon Lidgard / Vincent Manoukian
6 */
7
8#ifndef EFFECTSCALCULATOR_H_
9#define EFFECTSCALCULATOR_H_
10
11//#include "ClassChooser.h"
12#include "ffb_defs.h"
13#include "PersistentStorage.h"
14#include "CommandHandler.h"
15#include <vector>
16#include "FastAvg.h"
18#define EFFECT_THREAD_MEM 128
19#define EFFECT_THREAD_PRIO 20 // low priority for stat
20
21#define INTERNAL_SCALER_DAMPER 40
22#define INTERNAL_SCALER_FRICTION 45
23#define INTERNAL_SCALER_INERTIA 4
24
25#define CUSTOM_PROFILE_ID 1
26
27class Axis;
28struct metric_t;
29
30// default effect gains
32 uint8_t friction = 254;
33 uint8_t spring = 64;
34 uint8_t damper = 64;
35 uint8_t inertia = 127;
36};
37
39 float friction = 1.0; //0.4 * 40;
40 float spring = 16.0;
41 float damper = 4.0; //2 * 40 * 2
42 float inertia = 2.0;//0.5 * 40;
43};
44
51
53 std::array<int16_t,MAX_AXIS> current={0};
54 std::array<int16_t,MAX_AXIS> max={0};
55 uint16_t nb=0;
56};
57
64
66 public CommandHandler,
68public:
70 virtual ~EffectsCalculator();
71
72 static ClassIdentifier info;
74 const ClassType getClassType() override {return ClassType::Internal;};
75
76 void saveFlash();
77 void restoreFlash();
78
79 bool isActive();
80 void setActive(bool active);
81 void calculateEffects(std::vector<std::unique_ptr<Axis>> &axes);
82 virtual void setFilters(FFB_Effect* effect);
83 void setGain(uint8_t gain);
84 uint8_t getGain();
85 void logEffectType(uint8_t type,bool remove = false);
86 //void setDirectionEnableMask(uint8_t mask);
87 void calcStatsEffectType(uint8_t type, int32_t force,uint8_t axis);
88 void logEffectState(uint8_t type,uint8_t state);
89 void resetLoggedActiveEffects(bool reinit);
90
91 int32_t find_free_effect(uint8_t type);
92 void free_effect(uint16_t idx);
93
94 CommandStatus command(const ParsedCommand& cmd,std::vector<CommandReply>& replies);
95 virtual std::string getHelpstring() { return "Controls internal FFB effects"; }
96
97 static const uint32_t max_effects = MAX_EFFECTS;
98 std::array<FFB_Effect,max_effects> effects; // Main effects storage
99
100 // Thread impl
101 void Run();
102
103 void updateSamplerate(float newSamplerate); // Must be called if update rate is changed to update filters and effects
104
105
106protected:
107
108private:
109 //uint8_t directionEnableMask = 0;
110 // Filters
111 effect_biquad_t filter[2]; // 0 is the default profile and the custom for CFFilter, CUSTOM_PROFILE_ID is the custom slot
112 uint8_t filterProfileId = 0;
113 uint32_t calcfrequency = 1000; // HID frequency 1khz
114 const float qfloatScaler = 0.01;
115
116 // Rescale factor for conditional effect to boost or decrease the intensity
117 uint8_t global_gain = 0xff;
120 uint8_t frictionPctSpeedToRampup = 25; // define the max value of the range (0..5% of maxspeed) where torque is rampup on friction
121
122 // FFB status
123 bool effects_active = false; // If FFB is on
124 uint32_t effects_used = 0;
125 std::array<effect_stat_t,12> effects_stats; // [0..12 effect types]
126 std::array<effect_stat_t,12> effects_statslast; // [0..12 effect types]
127 bool isMonitorEffect = false;
128
129 int32_t calcComponentForce(FFB_Effect *effect, int32_t forceVector, std::vector<std::unique_ptr<Axis>> &axes, uint8_t axis);
131 float speedRampupPct();
132 int32_t calcConditionEffectForce(FFB_Effect *effect, float metric, uint8_t gain, uint8_t idx, float scale, float angle_ratio);
133 int32_t getEnvelopeMagnitude(FFB_Effect *effect);
134 std::string listEffectsUsed(bool details = false,uint8_t axis = 0);
135 //std::string listForceEffects();
136 void checkFilterCoeff(biquad_constant_t *filter, uint32_t freq,uint8_t q);
137 void updateFilterSettingsForEffects(uint8_t type_effect);
138};
139
144public:
145 virtual void set_FFB(bool state) = 0; // Enables or disables FFB
146 virtual void stop_FFB(){set_FFB(false);};
147 virtual void start_FFB(){set_FFB(true);};
148 virtual void reset_ffb() = 0;
149 virtual uint32_t getConstantForceRate(); // Returns an estimate of the constant force effect update rate in hz
150 virtual uint32_t getRate(); // Returns an estimate of the overall effect update speed in hz
151 virtual bool getFfbActive() = 0;
152 virtual void set_gain(uint8_t gain) = 0;
153 virtual void cfUpdateEvent();
154 virtual void fxUpdateEvent();
155 virtual void updateSamplerate(float newSamplerate) = 0; // Should be called when update loop rate is changed
156
157private:
160
161 uint32_t lastFxUpdate = 0;
162 uint32_t lastCfUpdate = 0;
163};
164
165#endif /* EFFECTSCALCULATOR_H_ */
@ filterProfileId
Definition Axis.h:96
ClassType
Definition ClassIDs.h:12
CommandStatus
EffectsCalculator_commands
Definition Axis.h:101
CommandHandler(const char *clsname, uint16_t clsid, uint8_t instance=0)
void logEffectState(uint8_t type, uint8_t state)
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
std::string listEffectsUsed(bool details=false, uint8_t axis=0)
void updateFilterSettingsForEffects(uint8_t type_effect)
int32_t calcComponentForce(FFB_Effect *effect, int32_t forceVector, std::vector< std::unique_ptr< Axis > > &axes, uint8_t axis)
int32_t find_free_effect(uint8_t type)
void updateSamplerate(float newSamplerate)
virtual std::string getHelpstring()
void setActive(bool active)
int32_t getEnvelopeMagnitude(FFB_Effect *effect)
void checkFilterCoeff(biquad_constant_t *filter, uint32_t freq, uint8_t q)
void calculateEffects(std::vector< std::unique_ptr< Axis > > &axes)
int32_t calcConditionEffectForce(FFB_Effect *effect, float metric, uint8_t gain, uint8_t idx, float scale, float angle_ratio)
const ClassType getClassType() override
void setGain(uint8_t gain)
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
std::array< effect_stat_t, 12 > effects_stats
static const uint32_t max_effects
void calcStatsEffectType(uint8_t type, int32_t force, uint8_t axis)
effect_biquad_t filter[2]
std::array< effect_stat_t, 12 > effects_statslast
static ClassIdentifier info
int32_t calcNonConditionEffectForce(FFB_Effect *effect)
std::array< FFB_Effect, max_effects > effects
virtual void setFilters(FFB_Effect *effect)
void logEffectType(uint8_t type, bool remove=false)
void resetLoggedActiveEffects(bool reinit)
effect_scaler_t scaler
void free_effect(uint16_t idx)
virtual uint32_t getConstantForceRate()
virtual void fxUpdateEvent()
virtual void stop_FFB()
virtual void cfUpdateEvent()
virtual void set_FFB(bool state)=0
FastMovingAverage< float > fxPeriodAvg
virtual void reset_ffb()=0
FastMovingAverage< float > cfUpdatePeriodAvg
virtual void updateSamplerate(float newSamplerate)=0
virtual uint32_t getRate()
virtual bool getFfbActive()=0
virtual void set_gain(uint8_t gain)=0
virtual void start_FFB()
biquad_constant_t constant
biquad_constant_t damper
biquad_constant_t friction
biquad_constant_t inertia
std::array< int16_t, MAX_AXIS > max
std::array< int16_t, MAX_AXIS > current