Skip to content

Commit

Permalink
Merge pull request #16 from ChrGri/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ChrGri authored Jan 8, 2024
2 parents 19252d8 + 5e5db77 commit 2d46a88
Show file tree
Hide file tree
Showing 302 changed files with 138,095 additions and 5,552 deletions.
38 changes: 26 additions & 12 deletions Arduino/Esp32/Main/ABSOscillation.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ABSOscillation {
_timeLastTriggerMillis = millis();
}

float forceOffset(DAP_calculationVariables_st* calcVars_st) {
float forceOffset(DAP_calculationVariables_st* calcVars_st, uint8_t absPattern) {


long timeNowMillis = millis();
Expand All @@ -39,7 +39,25 @@ class ABSOscillation {
{
_absTimeMillis += timeNowMillis - _lastCallTimeMillis;
float absTimeSeconds = _absTimeMillis / 1000.0f;
absForceOffset = calcVars_st->absAmplitude * sin(calcVars_st->absFrequency * absTimeSeconds);

switch (absPattern) {
case 0:
// sine wave pattern
absForceOffset = calcVars_st->absAmplitude * sin(2 * PI * calcVars_st->absFrequency * absTimeSeconds);
break;
case 1:
// sawtooth pattern
if (calcVars_st->absFrequency > 0)
{
absForceOffset = calcVars_st->absAmplitude * fmod(absTimeSeconds, 1.0 / (float)calcVars_st->absFrequency) * (float)calcVars_st->absFrequency;
}
break;
default:
break;
}



}

_lastCallTimeMillis = timeNowMillis;
Expand All @@ -62,33 +80,28 @@ class RPMOscillation {
: _timeLastTriggerMillis(0)
{}
float RPM_value =0;
float RPM_debug =0;
float RPM_debug_MAX_freq =0;
float RPM_debug_MIN_freq =0;
int32_t RPM_position_offset = 0;
public:
void trigger() {
_timeLastTriggerMillis = millis();
}

float forceOffset(DAP_calculationVariables_st* calcVars_st) {
void forceOffset(DAP_calculationVariables_st* calcVars_st) {


long timeNowMillis = millis();
float timeSinceTrigger = (timeNowMillis - _timeLastTriggerMillis);
float RPMForceOffset = 0;
float RPM_max_freq = calcVars_st->RPM_max_freq;
float RPM_min_freq = calcVars_st->RPM_min_freq;
float RPM_max =10;
//float RPM_max =10;
float RPM_amp = calcVars_st->RPM_AMP;
RPM_debug=RPM_amp;
RPM_debug_MAX_freq=RPM_max_freq;
RPM_debug_MIN_freq=RPM_min_freq;
if(RPM_value==0)
{
RPM_min_freq=0;

}


float RPM_freq=constrain(RPM_value*(RPM_max_freq-RPM_min_freq)/100, RPM_min_freq, RPM_max_freq);


Expand All @@ -109,7 +122,8 @@ class RPMOscillation {

_lastCallTimeMillis = timeNowMillis;
RPM_VALUE_LAST=RPMForceOffset;
return RPMForceOffset;
RPM_position_offset = calcVars_st->stepperPosRange*(RPMForceOffset/calcVars_st->Force_Range);
//return RPMForceOffset;


}
Expand Down
5 changes: 4 additions & 1 deletion Arduino/Esp32/Main/DiyActivePedal_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void DAP_config_st::initialiseDefaults() {

payLoadPedalConfig_.absFrequency = 15;
payLoadPedalConfig_.absAmplitude = 0;
payLoadPedalConfig_.absPattern = 0;


payLoadPedalConfig_.lengthPedal_AC = 150;
Expand Down Expand Up @@ -69,6 +70,8 @@ void DAP_config_st::initialiseDefaults() {
payLoadPedalConfig_.loadcell_rating = 150;

payLoadPedalConfig_.travelAsJoystickOutput_u8 = 0;

payLoadPedalConfig_.invertLoadcellReading_u8 = 0;
}


Expand Down Expand Up @@ -118,7 +121,7 @@ void DAP_calculationVariables_st::updateFromConfig(DAP_config_st& config_st) {
startPosRel = ((float)config_st.payLoadPedalConfig_.pedalStartPosition) / 100.0f;
endPosRel = ((float)config_st.payLoadPedalConfig_.pedalEndPosition) / 100.0f;

absFrequency = 2 * PI * ((float)config_st.payLoadPedalConfig_.absFrequency);
absFrequency = ((float)config_st.payLoadPedalConfig_.absFrequency);
absAmplitude = ((float)config_st.payLoadPedalConfig_.absAmplitude) / 20.0f; // in kg

dampingPress = ((float)config_st.payLoadPedalConfig_.dampingPress) / 400.0f;
Expand Down
7 changes: 6 additions & 1 deletion Arduino/Esp32/Main/DiyActivePedal_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdint.h>


#define DAP_VERSION_CONFIG 112
#define DAP_VERSION_CONFIG 114


#define DAP_PAYLOAD_TYPE_CONFIG 100
Expand Down Expand Up @@ -56,6 +56,7 @@ struct payloadPedalConfig {
// configure ABS effect
uint8_t absFrequency; // In Hz
uint8_t absAmplitude; // In kg/20
uint8_t absPattern; // 0: sinewave, 1: sawtooth


// geometric properties of the pedal
Expand Down Expand Up @@ -97,6 +98,10 @@ struct payloadPedalConfig {

// use loadcell or travel as joystick output
uint8_t travelAsJoystickOutput_u8;

// invert loadcell sign
uint8_t invertLoadcellReading_u8;

};

struct payloadFooter {
Expand Down
2 changes: 2 additions & 0 deletions Arduino/Esp32/Main/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
// level shifter is present on this PCB design
#define SENSORLESS_HOMING true

#define Using_analog_output

#endif


Expand Down
47 changes: 20 additions & 27 deletions Arduino/Esp32/Main/Main.ino
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#define ESTIMATE_LOADCELL_VARIANCE
#define ISV_COMMUNICATION
//#define Using_analog_output
//#define PRINT_SERVO_STATES

#define DEBUG_INFO_0_CYCLE_TIMER 1
Expand Down Expand Up @@ -212,10 +211,7 @@ void setup()
// init controller
SetupController();
delay(2000);
#ifdef Using_analog_output
delay(8000);
#endif




// check whether iSV57 communication can be established
Expand All @@ -236,6 +232,9 @@ void setup()
#endif


// initialize configuration and update local variables
dap_config_st.initialiseDefaults();

// Load config from EEPROM, if valid, overwrite initial config
EEPROM.begin(sizeof(DAP_config_st));
dap_config_st.loadConfigFromEprom(dap_config_st);
Expand Down Expand Up @@ -286,14 +285,7 @@ void setup()



// initialize configuration and update local variables
#ifdef PEDAL_IS_BRAKE
dap_config_st.initialiseDefaults();
#endif

#ifdef PEDAL_IS_ACCELERATOR
dap_config_st.initialiseDefaults_Accelerator();
#endif




Expand Down Expand Up @@ -540,19 +532,12 @@ void pedalUpdateTask( void * pvParameters )

// compute pedal oscillation, when ABS is active
float absForceOffset_fl32 = 0.0f;
float RPMForceOffset_fl32 = 0.0f;
float total_effect_force = 0.0f;

#ifdef ABS_OSCILLATION
absForceOffset_fl32 = absOscillation.forceOffset(&dap_calculationVariables_st);
absForceOffset_fl32 = absOscillation.forceOffset(&dap_calculationVariables_st, dap_config_st.payLoadPedalConfig_.absPattern);
RPMOscillation.trigger();
RPMForceOffset_fl32 = RPMOscillation.forceOffset(&dap_calculationVariables_st);
//total_effect_force = absForceOffset_fl32+RPMForceOffset_fl32;
//Serial.println(dap_config_st.payLoadPedalConfig_.RPM_AMP);
//Serial.println(dap_config_st.payLoadPedalConfig_.RPM_max_freq);
//Serial.println(dap_config_st.payLoadPedalConfig_.RPM_min_freq);
//Dap_action_st.
RPMOscillation.forceOffset(&dap_calculationVariables_st);
#endif
//dap_calculationVariables_st.Force_Max+=total_effect_force;

// compute the pedal incline angle
//#define COMPUTE_PEDAL_INCLINE_ANGLE
Expand All @@ -575,6 +560,11 @@ void pedalUpdateTask( void * pvParameters )
// Get the loadcell reading
float loadcellReading = loadcell->getReadingKg();

if (dap_config_st.payLoadPedalConfig_.invertLoadcellReading_u8 == 1)
{
loadcellReading *= -1;
}

// Do the loadcell signal filtering
float filteredReading = kalman->filteredValue(loadcellReading, 0, dap_config_st.payLoadPedalConfig_.kf_modelNoise);
float changeVelocity = kalman->changeVelocity();
Expand Down Expand Up @@ -623,8 +613,8 @@ void pedalUpdateTask( void * pvParameters )
double stepperPosFraction = stepper->getCurrentPositionFraction();
//double stepperPosFraction2 = stepper->getCurrentPositionFractionFromExternalPos( -(int32_t)(isv57.servo_pos_given_p + isv57.servo_pos_error_p - isv57.getZeroPos()) );
//int32_t Position_Next = MoveByInterpolatedStrategy(filteredReading, stepperPosFraction, &forceCurve, &dap_calculationVariables_st, &dap_config_st);
int32_t Position_Next = MoveByPidStrategy(filteredReading, stepperPosFraction, stepper, &forceCurve, &dap_calculationVariables_st, &dap_config_st, absForceOffset_fl32, RPMForceOffset_fl32);
//int32_t Position_Next = MoveByPidStrategy(filteredReading, stepperPosFraction, stepper, &forceCurve, &dap_calculationVariables_st, &dap_config_st, total_effect_force);
int32_t Position_Next = MoveByPidStrategy(filteredReading, stepperPosFraction, stepper, &forceCurve, &dap_calculationVariables_st, &dap_config_st, absForceOffset_fl32);



//#define DEBUG_STEPPER_POS
Expand All @@ -650,8 +640,10 @@ void pedalUpdateTask( void * pvParameters )



// clip target position to configured target interval
Position_Next = (int32_t)constrain(Position_Next, dap_calculationVariables_st.stepperPosMin, dap_calculationVariables_st.stepperPosMax);
//Adding RPM effect
Position_Next +=RPMOscillation.RPM_position_offset;
// clip target position to configured target interval with RPM effect movement in the endstop
Position_Next = (int32_t)constrain(Position_Next, dap_calculationVariables_st.stepperPosMin, dap_calculationVariables_st.stepperPosMax+RPMOscillation.RPM_position_offset);

// if pedal in min position, recalibrate position
#ifdef ISV_COMMUNICATION
Expand Down Expand Up @@ -904,6 +896,7 @@ void serialCommunicationTask( void * pvParameters )
crc = checksumCalculator((uint8_t*)(&(dap_config_st.payLoadHeader_)), sizeof(dap_config_st.payLoadHeader_) + sizeof(dap_config_st.payLoadPedalConfig_));
dap_config_st_local_ptr->payloadFooter_.checkSum = crc;
Serial.write((char*)dap_config_st_local_ptr, sizeof(DAP_config_st));
Serial.print("\r\n");
}


Expand Down
10 changes: 5 additions & 5 deletions Arduino/Esp32/Main/StepperMovementStrategy.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void tunePidValues(DAP_config_st& config_st)
myPID.SetTunings(config_st.payLoadPedalConfig_.PID_p_gain, config_st.payLoadPedalConfig_.PID_i_gain, config_st.payLoadPedalConfig_.PID_d_gain);
}

int32_t MoveByPidStrategy(float loadCellReadingKg, float stepperPosFraction, StepperWithLimits* stepper, ForceCurve_Interpolated* forceCurve, const DAP_calculationVariables_st* calc_st, DAP_config_st* config_st, float absForceOffset_fl32, float RPM_offest) {
int32_t MoveByPidStrategy(float loadCellReadingKg, float stepperPosFraction, StepperWithLimits* stepper, ForceCurve_Interpolated* forceCurve, const DAP_calculationVariables_st* calc_st, DAP_config_st* config_st, float absForceOffset_fl32) {

if (pidWasInitialized == false)
{
Expand Down Expand Up @@ -118,7 +118,7 @@ int32_t MoveByPidStrategy(float loadCellReadingKg, float stepperPosFraction, Ste


loadCellTargetKg -=absForceOffset_fl32;
float step_RPM = RPM_offest/calc_st->Force_Range * (calc_st->stepperPosMax - calc_st->stepperPosMin);


// ToDO
// - Min and Max force need to be identified from forceCurve->forceAtPosition() as they migh differ from calc_st.Force_Min & calc_st.Force_Max
Expand Down Expand Up @@ -148,9 +148,9 @@ int32_t MoveByPidStrategy(float loadCellReadingKg, float stepperPosFraction, Ste

float posStepperNew_fl32 = -1.0 * Output * (float)(calc_st->stepperPosMax - calc_st->stepperPosMin);//stepper->getTravelSteps();
posStepperNew_fl32 += calc_st->stepperPosMin;
//int32_t posStepperNew = floor(posStepperNew_fl32);
int32_t posStepperNew = floor(posStepperNew_fl32+step_RPM);
posStepperNew=constrain(posStepperNew,calc_st->stepperPosMin,calc_st->stepperPosMax+step_RPM );
int32_t posStepperNew = floor(posStepperNew_fl32);

posStepperNew=constrain(posStepperNew,calc_st->stepperPosMin,calc_st->stepperPosMax );

//#define PLOT_PID_VALUES
#ifdef PLOT_PID_VALUES
Expand Down
2 changes: 1 addition & 1 deletion Arduino/Esp32/arduinoCliBuildScript.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# for Arduino-cli help, see https://arduino.github.io/arduino-cli/0.33/commands/arduino-cli_compile/


arduino-cli compile --fqbn esp32:esp32:fm-devkit --output-dir bin Main/.
arduino-cli compile --fqbn esp32:esp32:fm-devkit --output-dir bin Main/. --libraries ../libs/
37 changes: 25 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,10 @@ Here are some examples of mechanical designs awesome DIYers have done:

| Design | Link |
:------------------------- | :-------------------------
|<img src="https://user-images.githubusercontent.com/17485523/231913569-695fcab1-f0bb-4af6-8d90-b1bfaece13bc.png" height="200"> | [Tjfenwick design](https://github.com/tjfenwick/DIY-Sim-Racing-Active-Pedal)|
|<img src="https://user-images.githubusercontent.com/17485523/231913569-695fcab1-f0bb-4af6-8d90-b1bfaece13bc.png" height="200"> | [Tjfenwick's design](https://github.com/tjfenwick/DIY-Sim-Racing-Active-Pedal)|
|<img src="https://user-images.githubusercontent.com/79850208/261399337-b313371c-9262-416d-a131-44fa269f9557.png" height="200"> | [Bjoes design](https://github.com/Bjoes/DIY-Active-pedal-mechanical-design)|
|<img src="https://media.printables.com/media/prints/557527/images/4471984_0fbfebf6-7b91-47dd-9602-44a6c7e8b851/thumbs/inside/1600x1200/png/screenshot-2023-08-19-150158.webp" height="200"> | [GWiz design](https://www.printables.com/de/model/557527-simucube-style-active-pedal/files)|
|<img src="https://media.printables.com/media/prints/557527/images/4471984_0fbfebf6-7b91-47dd-9602-44a6c7e8b851/thumbs/inside/1600x1200/png/screenshot-2023-08-19-150158.webp" height="200"> | [GWiz's design](https://www.printables.com/de/model/557527-simucube-style-active-pedal/files)|
|<img src="https://cdn.thingiverse.com/assets/14/7d/56/cd/03/large_display_9d83a9a8-2c8a-4940-b9ce-b4ae4f9674c6.jpg" height="200"> | [shf90's design](https://www.thingiverse.com/thing:6414587)|



Expand Down Expand Up @@ -119,8 +120,9 @@ Firmware can be built and flashed via Arduino-IDE or Arduino-CLI.

#### Built from source (via Arduino-CLI)
1. Install the [Arduino CLI](https://github.com/arduino/arduino-cli/releases)
2. Execute the [build script](Arduino/Esp32/arduinoCliBuildScript.bat) from a local repo.
3. Flash the binaries via e.g. web installer, see [below](#flash-prebuilt-binaries-via-webflasher).
2. Install the libraries `git submodule update --init --recursive`
3. Execute the [build script](Arduino/Esp32/arduinoCliBuildScript.bat) from a local repo.
4. Flash the binaries via e.g. web installer, see [below](#flash-prebuilt-binaries-via-webflasher).

#### Flash prebuilt binaries via web flasher
The binaries are available [here](https://github.com/ChrGri/DIY-Sim-Racing-FFB-Pedal/releases). They can be flashed via the ESP [webflasher](https://esp.huhn.me/).
Expand All @@ -143,7 +145,7 @@ The SimHub plugin was designed to communicate with the ESP to (a) modify the ped

![image](SimHubPlugin/Images/Plugin-UI.png)

To install the plugin, the plugin [binaries](https://github.com/ChrGri/DIY-Sim-Racing-FFB-Pedal/releases), hidden inside the SimHub_plugin.zip, have to be copied to the SimHub directory, e.g. C:/Program Files (x86)/SimHub
To install the plugin, the plugin [DiyActivePedal.dll](https://github.com/ChrGri/DIY-Sim-Racing-FFB-Pedal/releases) has to be copied to the SimHub directory, e.g. C:/Program Files (x86)/SimHub

# Steps after flashing the firmware
The pedal will not move initially after flashing. One has to open the SimHub plugin, connect to the pedal, and send a config with non-zero PID values.
Expand All @@ -164,6 +166,11 @@ After sending the initial config, power cycling of the pedal is necessary. The p
1. Make sure, that you follow the above instructions. The default PID values are set to 0 thus the pedal will not move. You have to send non-zero PID values and restart the pedal to observe pedal travel.
2. Open the serial monitor in Arduino IDE, set the baud rate to 921600, and restart the pedal. You should see some debug info. Make a screenshot and kindly ask the Discord server for help.

## Bluetooth doesn't show gamepad data
Install DirectX 9

## The serial monitor shows a message "Couldn't load config from EPROM due to version mismatch"
Install a SimHub plugin matching the ESP firmware you installed and send a config to the pedal.

# Misc
## Pedal kinematics calculation
Expand All @@ -178,17 +185,23 @@ To get a better understanding of the motion and forces, a [python](Validation/Pe
ESP code:
- [ ] Add automatic system identification of pedal response
- [ ] Add model-predictive-control to the ESP code for the improved pedal response
- [ ] Add field to select joystick output to be conputed from force or travel

- [ ] Add field to invert motor and losdcell direction
- [ ] send joystick data to simhub plugin and provide data as vJoy gamecontroller
- [ ] check sebastiand issue eith sticking gas pedal
- [ ] allow effects to move stepper beyond configured max/min position, but not the measured homing positions.

SimHub plugin:
- [ ] Send SimHub data via wifi to ESP
- [ ] GUI design improvements for the SimHub plugin
- [ ] JSON deserialization make compatible with older revisions
- [ ] JSON deserialization add nicer formating
- [ ] add button to reset the ESP https://stackoverflow.com/questions/51084038/c-sharp-dtrenable-and-rtsenable-in-the-serialport
- [x] GUI design improvements for the SimHub plugin
- [x] JSON deserialization make compatible with older revisions
- [ ] include the types header file and use it

- [ ] Make use of effects from the ShakeIt plugin
- [ ] add OTA update for esp firmware
- [ ] automatic serial monitor update
- [ ] serial plotter
- [ ] add different abs effect patterns, e.g. sawtooth

Misc:
- [ ] Create a video describing the build progress and the features
- [ ] Add Doxygen + Graphviz to the project to automatically generate documentation, architectural design overview, etc.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified SimHubPlugin/.vs/User.PluginSdkDemo/v17/.suo
Binary file not shown.
Loading

0 comments on commit 2d46a88

Please sign in to comment.