Skip to content

Commit 28153c2

Browse files
committed
fix: fix the denormalisation issue in calculateFFBTorque. Optimize the struct from 64 to 32b to reduce load.
1 parent ba58b35 commit 28153c2

2 files changed

Lines changed: 36 additions & 37 deletions

File tree

Firmware/FFBoard/Inc/Axis.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class Axis : public PersistentStorage, public CommandHandler, public ErrorHandle
350350
* @brief Calculates the FFB torque exponential torque, from the input torque and apply expo and scaler
351351
* @return The calculated exponential torque.
352352
*/
353-
int64_t calculateFFBTorque();
353+
int32_t calculateFFBTorque();
354354

355355
/**
356356
* @brief Starts a force fade-in.
@@ -365,7 +365,7 @@ class Axis : public PersistentStorage, public CommandHandler, public ErrorHandle
365365
* @brief Sets the FFB effect torque.
366366
* @param torque The new FFB effect torque from the EffectsCalculator.
367367
*/
368-
void setFfbEffectTorque(int64_t torque);
368+
void setFfbEffectTorque(int32_t torque);
369369

370370
/**
371371
* @brief Updates the total torque.
@@ -432,12 +432,12 @@ class Axis : public PersistentStorage, public CommandHandler, public ErrorHandle
432432
* @param torque A reference to the torque value to be modified.
433433
* @return torque update to apply to reduced de speed.
434434
*/
435-
int64_t applySpeedLimiterTorque(int64_t& torque);
435+
int32_t applySpeedLimiterTorque(int32_t& torque);
436436
/**
437437
* @brief Applies the torque slew rate limiter to the torque.
438438
* @param torque A reference to the torque value to be modified.
439439
*/
440-
void applyTorqueSlewRateLimiter(int64_t& torque);
440+
void applyTorqueSlewRateLimiter(int32_t& torque);
441441
/**
442442
* @brief Decodes the axis configuration from a 16-bit integer stored in flash.
443443
* @param val The 16-bit encoded configuration value.
@@ -496,7 +496,7 @@ class Axis : public PersistentStorage, public CommandHandler, public ErrorHandle
496496
float previousFrameSpeed = 0; //!< Instantaneous speed from the last cycle, used for acceleration calculation.
497497

498498
// Torque components
499-
int64_t ffbEffectTorque = 0; //!< Torque from HID FFB effects.
499+
int32_t ffbEffectTorque = 0; //!< Torque from HID FFB effects.
500500
int32_t mechanicalEffectTorque = 0; //!< Torque from mechanical effects (damper, friction, inertia).
501501

502502
// Power and scaling

Firmware/FFBoard/Src/Axis.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -780,36 +780,34 @@ uint16_t Axis::getPower(){
780780
/**
781781
* Calculates an exponential torque correction curve and scale for FFBEffect
782782
*/
783-
int64_t Axis::calculateFFBTorque(){
783+
int32_t Axis::calculateFFBTorque(){
784784

785-
// Apply equalizer
786-
float filtered_torque = this->ffbEffectTorque;
785+
// 1. Initial conversion and normalization
786+
// Convert to float and move to [-1.0, 1.0] range immediately.
787+
float torque = (float)this->ffbEffectTorque * (1.0f / 32767.0f);
787788

789+
// 2. Game Clipping detection
790+
// Performed on normalized value for consistency.
791+
if(fabsf(torque) >= 1.0f){
792+
pulseClipLed(); // Visual alert: game signal is clipping
793+
}
794+
795+
// 3. Apply equalizer
796+
// Standardized DSP processing on [-1.0, 1.0] range.
788797
if(equalizerEnabled){
789798
for (uint8_t i = 0; i < num_eq_bands; ++i) {
790-
filtered_torque = eqFilters[i].process(filtered_torque);
799+
torque = eqFilters[i].process(torque);
791800
}
792801
}
793802

794-
// Game effects. Down and up-scaling may introduce float artifacts. Do this before scaling down.
795-
float torque = (float)filtered_torque / (float)0x7fff;
796-
797-
// 1. Game Clipping detection
798-
// If the game sends more than the theoretical maximum (+/- 32767), the signal is clipped at the source.
799-
if(abs(torque) >= 0x7fff){
800-
pulseClipLed(); // Visual alert: game signal is clipping
801-
}
802-
803-
// 2. Apply Expo (Linearization or sensation curve)
804-
if(expo != 1){
803+
// 4. Apply Expo (Linearization or sensation curve)
804+
if(expo != 1.0f){
805805
torque = calculateExpoTorque(torque);
806806
}
807807

808-
// 3. Game specific gain (effectRatioScaler)
809-
// Scale the FFB from game only (allows lowering game effects without lowering endstops)
810-
torque = (int64_t)((float)torque * effectRatioScaler);
811-
812-
return torque;
808+
// 5. Final scaling and single conversion back to integer
809+
// Apply both the FFB range and the effect ratio in one final step.
810+
return (int32_t)(torque * 32767.0f * effectRatioScaler);
813811
}
814812

815813
int32_t Axis::getTorque() { return metric.current.torque; } // Fix: move from previous to current
@@ -834,7 +832,7 @@ int32_t Axis::calculateEndstopTorque(){
834832
return clip<int32_t,int32_t>(endstopTorque,-0x7fff,0x7fff);
835833
}
836834

837-
void Axis::setFfbEffectTorque(int64_t torque) {
835+
void Axis::setFfbEffectTorque(int32_t torque) {
838836
this->ffbEffectTorque = torque;
839837
}
840838

@@ -846,7 +844,7 @@ bool Axis::updateTorque(int32_t* totalTorque) {
846844

847845
// STEP 1: Process FFB torque from the game (via helper function)
848846
// (Reconstructed by CMSIS Spline, Expo applied, and scaled by FFB ratio)
849-
int64_t torque = calculateFFBTorque();
847+
int32_t torque = calculateFFBTorque();
850848

851849
// STEP 2: Mix in local mechanical effects
852850
// (Damper, Friction, Inertia generated locally at high frequency)
@@ -859,7 +857,7 @@ bool Axis::updateTorque(int32_t* totalTorque) {
859857

860858
// STEP 4: Master Volume Scaling
861859
// Map the virtual signal (+/- 32767) to the physical power limit ("power")
862-
torque = (int64_t)((float)torque * torqueScaler);
860+
torque = (int32_t)((float)torque * torqueScaler);
863861

864862
// STEP 5: Safety limits (Fade-in, Out of bounds)
865863
// Applied BEFORE dynamic limiters so that abrupt cuts are smoothed by the Slew Rate.
@@ -870,7 +868,7 @@ bool Axis::updateTorque(int32_t* totalTorque) {
870868
// Apply a fade-in effect for a smooth force ramp-up on startup or recovery.
871869
// Increases forceFadeMultiplier progressively based on forceFadeDuration and sample rate.
872870
if(forceFadeMultiplier < 1.0f){
873-
torque = (int64_t)((float)torque * forceFadeMultiplier);
871+
torque = (int32_t)((float)torque * forceFadeMultiplier);
874872
forceFadeMultiplier += forceFadeDuration / this->filter_f;
875873
}
876874

@@ -904,7 +902,7 @@ bool Axis::updateTorque(int32_t* totalTorque) {
904902
}
905903

906904

907-
void Axis::applyTorqueSlewRateLimiter(int64_t& torque)
905+
void Axis::applyTorqueSlewRateLimiter(int32_t& torque)
908906
{
909907
// Limits the rate of change of the torque (slew rate), to smooths out sudden changes in torque.
910908
// Essential for a natural feel and to prevent "clanking" noises.
@@ -913,14 +911,14 @@ void Axis::applyTorqueSlewRateLimiter(int64_t& torque)
913911
}
914912

915913
// This prevents sudden torque jumps, resulting in a smoother feel.
916-
const int64_t previousTorque = metric.previous.torque;
917-
const int64_t maxTorqueChange = maxTorqueRateMS;
914+
const int32_t previousTorque = metric.previous.torque;
915+
const int32_t maxTorqueChange = maxTorqueRateMS;
918916

919917
// The torque is clipped to be within the range of [previous torque - limit, previous torque + limit].
920-
torque = clip<int64_t>(torque, previousTorque - maxTorqueChange, previousTorque + maxTorqueChange);
918+
torque = clip<int32_t>(torque, previousTorque - maxTorqueChange, previousTorque + maxTorqueChange);
921919
}
922920

923-
int64_t Axis::applySpeedLimiterTorque(int64_t& torque){
921+
int32_t Axis::applySpeedLimiterTorque(int32_t& torque){
924922
// Speed Limiter: A PI controller to reduce torque when speed exceeds maxSpeedDegS.
925923
// The limiter only acts when torque is applied in the direction of movement.
926924

@@ -929,7 +927,8 @@ int64_t Axis::applySpeedLimiterTorque(int64_t& torque){
929927
return 0;
930928
}
931929

932-
int64_t resultTorque = 0;
930+
int32_t resultTorque = 0;
931+
933932
float effectiveSpeed = metric.current.speed * (torque > 0 ? 1.0f : -1.0f);
934933

935934
if (effectiveSpeed > maxSpeedDegS)
@@ -951,9 +950,9 @@ int64_t Axis::applySpeedLimiterTorque(int64_t& torque){
951950
// We must only reduce the magnitude of the torque, not invert it.
952951
reductionAmount = clip(reductionAmount, 0.0f, fabsf((float)torque));
953952
if(torque > 0) {
954-
resultTorque = reductionAmount;
953+
resultTorque = (int32_t)reductionAmount;
955954
} else {
956-
resultTorque = -reductionAmount;
955+
resultTorque = (int32_t)-reductionAmount;
957956
}
958957
} else {
959958
#ifdef USE_DSP_FUNCTIONS

0 commit comments

Comments
 (0)