diff --git a/.project b/.project new file mode 100644 index 00000000..3fd72c24 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + OpenFFBoard + + + + + + + + diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 00000000..bd126997 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/msys64/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/cmake-kits.json b/.vscode/cmake-kits.json new file mode 100644 index 00000000..a2353c93 --- /dev/null +++ b/.vscode/cmake-kits.json @@ -0,0 +1,11 @@ +[ + { + "name": "GCC for ARM Embedded", + "compilers": { + "C": "C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/arm-none-eabi-gcc.exe", + "CXX": "C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/arm-none-eabi-g++.exe" + }, + "isTrusted": true, + "keep": true + } +] \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..6a67e84f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/Users/gorkem/OpenFFBoard/Firmware/FFBoard/Src", + "program": "c:/Users/gorkem/OpenFFBoard/Firmware/FFBoard/Src/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b4bbaabb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,68 @@ +{ + "cmake.additionalKits": [ + "${workspaceFolder}/.vscode/cmake-kits.json" + ], + "cmake.configureOnOpen": true, + "files.associations": { + "*.h": "c", + "*.c": "c", + "*.cpp": "cpp" + }, + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/Firmware/FFBoard/Inc/EffectsCalculator.h b/Firmware/FFBoard/Inc/EffectsCalculator.h index e065c033..7b03b734 100644 --- a/Firmware/FFBoard/Inc/EffectsCalculator.h +++ b/Firmware/FFBoard/Inc/EffectsCalculator.h @@ -60,6 +60,7 @@ enum class EffectsCalculator_commands : uint32_t { damper_f, damper_q, friction_f, friction_q, inertia_f, inertia_q, filterProfileId, frictionPctSpeedToRampup, monitorEffect, effectsDetails, effectsForces, + safetyLimit, safetyDamping, }; class EffectsCalculator: public PersistentStorage, @@ -115,7 +116,9 @@ class EffectsCalculator: public PersistentStorage, uint8_t global_gain = 0xff; effect_gain_t gain; effect_scaler_t scaler; - uint8_t frictionPctSpeedToRampup = 25; // define the max value of the range (0..5% of maxspeed) where torque is rampup on friction + uint8_t frictionPctSpeedToRampup = 25; + uint16_t safetySpeedLimit = 20000; // default limit 2 + uint8_t safetyDamping = 5; // default damping // FFB status bool effects_active = false; // If FFB is on diff --git a/Firmware/FFBoard/Src/EffectsCalculator.cpp b/Firmware/FFBoard/Src/EffectsCalculator.cpp index 688afb25..8c44ad18 100644 --- a/Firmware/FFBoard/Src/EffectsCalculator.cpp +++ b/Firmware/FFBoard/Src/EffectsCalculator.cpp @@ -49,6 +49,8 @@ EffectsCalculator::EffectsCalculator() : CommandHandler("fx", CLSID_EFFECTSCALC) registerCommand("filterProfile_id", EffectsCalculator_commands::filterProfileId, "Conditional effects filter profile: 0 default; 1 custom", CMDFLAG_GET | CMDFLAG_SET); registerCommand("frictionPctSpeedToRampup", EffectsCalculator_commands::frictionPctSpeedToRampup, "% of max speed for gradual increase", CMDFLAG_GET | CMDFLAG_SET); + registerCommand("safetyLimit", EffectsCalculator_commands::safetyLimit, "Safety Cutoff Speed (0=Off)", CMDFLAG_GET | CMDFLAG_SET); + registerCommand("safetyDamping", EffectsCalculator_commands::safetyDamping, "Safety Damping Factor", CMDFLAG_GET | CMDFLAG_SET); //this->Start(); // Enable if we want to periodically monitor } @@ -150,8 +152,35 @@ void EffectsCalculator::calculateEffects(std::vector> &axe // Apply summed force to axes for(uint8_t i=0 ; i < axisCount ; i++) { - int32_t force = clip(forces[i], -0x7fff, 0x7fff); // Clip - axes[i]->setEffectTorque(force); + int32_t finalForce = forces[i]; + + // --- meadhours CONFIGURABLE HAND SAFETY PATCH START --- + + // if limit value 0, off + if (this->safetySpeedLimit > 0) { + + float currentVel = 0.0f; + metric_t *metrics = axes[i]->getMetrics(); + + if (metrics != nullptr) { + currentVel = metrics->speed; + } + + // speed control + if (abs(currentVel) > this->safetySpeedLimit) { + + // killswitch + finalForce = 0; + + // active damping + float dampingFactor = (float)this->safetyDamping / 10.0f; + float dampingForce = -1.0f * currentVel * dampingFactor; + finalForce = (int32_t)dampingForce; + } + } + + int32_t clippedForce = clip(finalForce, -0x7fff, 0x7fff); + axes[i]->setEffectTorque(clippedForce); } effects_statslast = effects_stats; @@ -934,6 +963,22 @@ CommandStatus EffectsCalculator::command(const ParsedCommand& cmd,std::vectorsafetySpeedLimit); + } else if (cmd.type == CMDtype::set) { + this->safetySpeedLimit = cmd.val; + } + break; + + case EffectsCalculator_commands::safetyDamping: + if (cmd.type == CMDtype::get) { + replies.emplace_back(this->safetyDamping); + } else if (cmd.type == CMDtype::set) { + this->safetyDamping = clip(cmd.val, 0, 100); + } + break; + default: return CommandStatus::NOT_FOUND; }