From 2dce470a401b4d60265e4cc7d648ddda536322bf Mon Sep 17 00:00:00 2001 From: ChrGri Date: Fri, 29 Dec 2023 16:48:36 +0100 Subject: [PATCH] Overwrite payload type when pedal config is send --- .DS_Store | Bin 14340 -> 14340 bytes .github/.DS_Store | Bin 6148 -> 6148 bytes Arduino/.DS_Store | Bin 14340 -> 12292 bytes Arduino/Esp32/Dev/StepperWithLimits.cpp | 340 +++++++++ Arduino/Esp32/Main/.DS_Store | Bin 8196 -> 10244 bytes Arduino/libs/.DS_Store | Bin 8196 -> 10244 bytes Arduino/libs/Copy/.DS_Store | Bin 0 -> 6148 bytes Arduino/libs/Copy/NimBLE-Arduino/.DS_Store | Bin 8196 -> 8196 bytes SimHubPlugin/.DS_Store | Bin 8196 -> 10244 bytes SimHubPlugin/SettingsControlDemo.xaml.cs | 843 +++++++++++---------- SimHubPlugin/obj/.DS_Store | Bin 6148 -> 6148 bytes SimHubPlugin/obj/Release/.DS_Store | Bin 0 -> 10244 bytes StepperParameterization/.DS_Store | Bin 6148 -> 6148 bytes Validation/.DS_Store | Bin 10244 -> 10244 bytes Wiring/.DS_Store | Bin 6148 -> 8196 bytes Wiring/PowerPcb/.DS_Store | Bin 0 -> 6148 bytes 16 files changed, 764 insertions(+), 419 deletions(-) create mode 100644 Arduino/Esp32/Dev/StepperWithLimits.cpp create mode 100644 Arduino/libs/Copy/.DS_Store create mode 100644 SimHubPlugin/obj/Release/.DS_Store create mode 100644 Wiring/PowerPcb/.DS_Store diff --git a/.DS_Store b/.DS_Store index 57caf52006bc138ac35ffc6c109d9afda068f525..0c060e8a5134a0a2cd8239327f88e291d547e58d 100644 GIT binary patch delta 1015 zcmZoEXepTBFY3p@z`)GFAi%(o%izIK%8qWXqVi+|6BbrRpd`!WMj;uFl;Y%^ zr2PDxja$O`85K4+3b8Q>_ z>Ijuc!79ODkbz`Olf&c&A=%CCB6}H8&1ZVRIr*W85q9$-5?IU!N}!t0?66r-tOLz# zM)8G{8^tBi&8{d62e}j0Oyw8^!$?`H{nAiqEvk7o~+aUzC``8i5u# zNua<11{51ZI722w5fJAwr03?N*o9RMinUV}7&gbsX)`kFZst*tLb07&u=UAiNkv<> z092b9R;-%`wwZ-Nk0BjsZwaccnDWRra$gW&nCzwA$mFnb@>z8`HlPo>7uHPvsIGuu zicHql;A2eKY^9OGSdW}gSSk&70yVHRI08MK0!(lqPv@gKFBcjx7^;wih5?5vWT&!R zoxs2_d7@^6huutYK)W!cG86;tOlQbLwX-4bO)WGsP}CsX2vRdSQcHm`U~`q00pr98 z(v$fFq?x&Uk|*m3$N)Xx@bGo*WIq8pbqEt`o+mJCB?4^(+KlWr2JQu$CkwPPvKyIO f=qMN&Po5>}F!9RE&Flu>ST;XYDP^KXq&WcqgXRrc delta 391 zcmZoEXepTBFKWiXz`)GFAi%(o$dJyE%21qAoSZZ9qVi+|6Bb!Upd7t>Glc$UFZ(b~} z&baxN#5~r`ALOJNCq8Iql-kUrAjP=ZNzs69@;UWVHK5H54D1YgK=)@dlrUs4lrkjc z=DWBg<>V&;WjK8PmL>`LPR`U&V1qLIHIx_`HgD3%V4S>4D<9~%$~YzBtseiwU9 zw$+w{F%z{Ffa;pG4H!2cl|IY_bwT}Rc7ty$lh-MxZmv`P!U%GMC2?*z>WJY|0MvPK A#sB~S diff --git a/.github/.DS_Store b/.github/.DS_Store index f03f63fc87fef9576c702701477237cfe444ddff..6c3be0ad71aaf4ae074d7e8cd0410d6324541e7c 100644 GIT binary patch delta 64 zcmZoMXffEJ$;_m&c5*$lm{4xMi%U{Yei8!%0|yXyFRYnd%PcWDo0*3V&Q)V_U;ruJ Jyqnom1OPzP5oQ1Y delta 64 zcmZoMXffEJ$;`ySFu9&tOeisN&7L HnLR}SKj6g{iAZBH7Whh2gke3b=Wt^;~Ahq#`J3ph$#0i@9Af*`$B@DR? zIXUTu!O8i#1wcg%3@TpjKoTyOoA2V1l#`zX6a%`bAt1u*s3WR;3SRkw3?#EHHUPB( zotMLqxLHI%ijg1LVxY`sc|m8k5Hu^Dp;m&m0UeymP?4LDVks6CDAs~Z4iUF!jQiRn z24u4U?ayRLVkkzlD12KL)NgQk6l*Z#ku71gR+#)zBA}j&!IvSQAq8lBDKHK~fUYfO zC_xEe2KQQ^Be1GNbCB|{RIr0^s6}xcRIMs@gOOdzz%XIsMK)GOuFX6O^^7dcardrn z?pKs%V*|P>_j&i^4eBx>5GL4iq{M`53Uk5(pdt`p0wp^T@CB2sV3I+D8%Vn%C*O@1 j-!o6lKbVqROY>l`qIJ3{K9^EdUt`1d|1&0ybVd#m30JnMa|X zk%fUVEPr#qqBI-Z4-u(}fv%G`sLQB9m|%NY8C)5P844JT8H`X&Vk%&mI6-Q%j$}Js z9DIyTk`>|s18yMgiX7k@FTQ7<%&!y3!vu*A3y{LiIXZUCNPe;)&QCy{NIotLF3JM{ D4IOf^ diff --git a/Arduino/Esp32/Dev/StepperWithLimits.cpp b/Arduino/Esp32/Dev/StepperWithLimits.cpp new file mode 100644 index 00000000..98c0fe2a --- /dev/null +++ b/Arduino/Esp32/Dev/StepperWithLimits.cpp @@ -0,0 +1,340 @@ +#include "StepperWithLimits.h" +#include "RTDebugOutput.h" +#include "Main.h" +#include "matrix.h" + + + +#define STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT 20 +#define MIN_POS_MAX_ENDSTOP STEPS_PER_MOTOR_REVOLUTION * 3 // servo has to drive minimum N steps before it allows the detection of the max endstop + +static const uint8_t LIMIT_TRIGGER_VALUE = LOW; // does endstop trigger high or low +static const int32_t ENDSTOP_MOVEMENT = STEPS_PER_MOTOR_REVOLUTION / 100; // how much to move between trigger checks +static const int32_t ENDSTOP_MOVEMENT_SENSORLESS = ENDSTOP_MOVEMENT * 5; + + +FastAccelStepperEngine& stepperEngine() { + static FastAccelStepperEngine myEngine = FastAccelStepperEngine(); // this is a factory and manager for all stepper instances + + static bool firstTime = true; + if (firstTime) { + myEngine.init(); + firstTime = false; + } + + return myEngine; +} + + + +StepperWithLimits::StepperWithLimits(uint8_t pinStep, uint8_t pinDirection, uint8_t pinMin, uint8_t pinMax) + : _pinMin(pinMin), _pinMax(pinMax) + , _limitMin(0), _limitMax(0) + , _posMin(0), _posMax(0) +{ + + + pinMode(pinMin, INPUT); + pinMode(pinMax, INPUT); + + + _stepper = stepperEngine().stepperConnectToPin(pinStep); + + + + // Stepper Parameters + if (_stepper) { + _stepper->setDirectionPin(pinDirection, MOTOR_INVERT_MOTOR_DIR); + _stepper->setAutoEnable(true); + _stepper->setSpeedInHz(MAXIMUM_STEPPER_SPEED); // steps/s + _stepper->setAcceleration(MAXIMUM_STEPPER_ACCELERATION); // steps/s² + +//#if defined(SUPPORT_ESP32_PULSE_COUNTER) +// _stepper->attachToPulseCounter(1, 0, 0); +//#endif + } +} + + +void StepperWithLimits::findMinMaxSensorless(isv57communication * isv57) +{ + + if (! hasValidStepper()) return; + + // obtain servo states + isv57->readServoStates(); + bool endPosDetected = abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + + + int32_t setPosition = _stepper->getCurrentPosition(); + while(!endPosDetected){ + delay(10); + isv57->readServoStates(); + endPosDetected = abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + + setPosition = setPosition - ENDSTOP_MOVEMENT_SENSORLESS; + _stepper->moveTo(setPosition, true); + + //Serial.print("Min_DetValue: "); + //Serial.println(isv57->servo_current_percent); + } + + // move away from min position to reduce servos current reading + _stepper->forceStop(); + setPosition = setPosition + 5 * ENDSTOP_MOVEMENT_SENSORLESS; + _stepper->moveTo(setPosition, true); + _stepper->forceStopAndNewPosition(0); + _stepper->moveTo(0); + _limitMin = 0; + + // wait N ms to let the endPosDetected become 0 again + //delay(300); + + // read servo states again + //isv57->readServoStates(); + endPosDetected = 0;//abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + + setPosition = _stepper->getCurrentPosition(); + while (!endPosDetected) { + delay(10); + isv57->readServoStates(); + + // only trigger when difference is significant + if (setPosition > MIN_POS_MAX_ENDSTOP) + { + endPosDetected = abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + } + + + setPosition = setPosition + ENDSTOP_MOVEMENT_SENSORLESS; + _stepper->moveTo(setPosition, true); + + //Serial.print("Max_DetValue: "); + //Serial.println(isv57->servo_current_percent); + } + + //_stepper->forceStop(); + //setPosition = setPosition - 5 * ENDSTOP_MOVEMENT; + + _limitMax = _stepper->getCurrentPosition(); + + // reduce speed and accelerartion + _stepper->setSpeedInHz(MAXIMUM_STEPPER_SPEED / 4); + _stepper->setAcceleration(MAXIMUM_STEPPER_ACCELERATION / 4); + + // move to min + _stepper->moveTo(_posMin, true); + + // increase speed and accelerartion + _stepper->setAcceleration(MAXIMUM_STEPPER_ACCELERATION); + _stepper->setSpeedInHz(MAXIMUM_STEPPER_SPEED); + + + + +#if defined(SUPPORT_ESP32_PULSE_COUNTER) + _stepper->clearPulseCounter(); +#endif + + +} + + +void StepperWithLimits::findMinMaxEndstops() { + if (! hasValidStepper()) return; + + int32_t setPosition = _stepper->getCurrentPosition(); + while(! (LIMIT_TRIGGER_VALUE == digitalRead(_pinMin))){ + setPosition = setPosition - ENDSTOP_MOVEMENT; + _stepper->moveTo(setPosition, true); + } + + + _stepper->forceStopAndNewPosition(0); + _stepper->moveTo(0); + _limitMin = 0; + + setPosition = _stepper->getCurrentPosition(); + while(! (LIMIT_TRIGGER_VALUE == digitalRead(_pinMax))){ + setPosition = setPosition + ENDSTOP_MOVEMENT; + _stepper->moveTo(setPosition, true); + } + + _limitMax = _stepper->getCurrentPosition(); + + _stepper->moveTo(_posMin, true); +#if defined(SUPPORT_ESP32_PULSE_COUNTER) + _stepper->clearPulseCounter(); +#endif +} + +void StepperWithLimits::updatePedalMinMaxPos(uint8_t pedalStartPosPct, uint8_t pedalEndPosPct) { + int32_t limitRange = _limitMax - _limitMin; + _posMin = _limitMin + ((limitRange * pedalStartPosPct) / 100); + _posMax = _limitMin + ((limitRange * pedalEndPosPct) / 100); +} + +void StepperWithLimits::refindMinLimit() { + int32_t setPosition = _stepper->getCurrentPosition(); + while(! (LIMIT_TRIGGER_VALUE == digitalRead(_pinMin))){ + setPosition = setPosition - ENDSTOP_MOVEMENT; + _stepper->moveTo(setPosition, true); + } + _stepper->forceStopAndNewPosition(_limitMin); +} + +void StepperWithLimits::refindMinLimitSensorless(isv57communication * isv57) { + + // obtain servo states + isv57->readServoStates(); + bool endPosDetected = abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + + + int32_t setPosition = _stepper->getCurrentPosition(); + while(!endPosDetected){ + delay(10); + isv57->readServoStates(); + endPosDetected = abs( isv57->servo_current_percent) > STEPPER_WITH_LIMITS_SENSORLESS_CURRENT_THRESHOLD_IN_PERCENT; + + setPosition = setPosition - ENDSTOP_MOVEMENT_SENSORLESS; + _stepper->moveTo(setPosition, true); + + //Serial.print("Min_DetValue: "); + //Serial.println(isv57->servo_current_percent); + } + + // move away from min position to reduce servos current reading + _stepper->forceStop(); + setPosition = setPosition + 5 * ENDSTOP_MOVEMENT_SENSORLESS; + _stepper->moveTo(setPosition, true); + _stepper->forceStopAndNewPosition(_limitMin); +} + +void StepperWithLimits::checkLimitsAndResetIfNecessary() { + // in case the stepper loses its position and therefore an endstop is triggered reset position + if (LIMIT_TRIGGER_VALUE == digitalRead(_pinMin)) { + _stepper->forceStopAndNewPosition(_limitMin); + _stepper->moveTo(_posMin, true); + } + if (LIMIT_TRIGGER_VALUE == digitalRead(_pinMax)) { + _stepper->forceStopAndNewPosition(_limitMin); + _stepper->moveTo(_posMax, true); + } +} + +int8_t StepperWithLimits::moveTo(int32_t position, bool blocking) { + return _stepper->moveTo(position, blocking); +} + +int32_t StepperWithLimits::getCurrentPositionSteps() const { + return _stepper->getCurrentPosition() - _posMin; +} + + +double StepperWithLimits::getCurrentPositionFraction() const { + return double(getCurrentPositionSteps()) / getTravelSteps(); +} + +int32_t StepperWithLimits::getTargetPositionSteps() const { + return _stepper->getPositionAfterCommandsCompleted(); +} + + +void StepperWithLimits::printStates() +{ + int32_t currentStepperPos = _stepper->getCurrentPosition(); + int32_t currentStepperVel = _stepper->getCurrentSpeedInUs(); + int32_t currentStepperVel2 = _stepper->getCurrentSpeedInMilliHz(); + + + //Serial.println(currentStepperVel); + + int32_t currentStepperAccel = _stepper->getCurrentAcceleration(); + + static RTDebugOutput rtDebugFilter({ "Pos", "Vel", "Vel2", "Accel"}); + rtDebugFilter.offerData({ currentStepperPos, currentStepperVel, currentStepperVel2, currentStepperAccel}); +} + + +void StepperWithLimits::setSpeed(uint32_t speedInStepsPerSecond) +{ + _stepper->setSpeedInHz(speedInStepsPerSecond); // steps/s +} + +bool StepperWithLimits::isAtMinPos() +{ + + bool isNotRunning = !_stepper->isRunning(); + bool isAtMinPos = getCurrentPositionSteps() == 0; + + return isAtMinPos && isNotRunning; +} +bool StepperWithLimits::correctPos(int32_t posOffset) +{ + // + int32_t stepOffset =(int32_t)constrain(posOffset, -10, 10); + + // correct pos + _stepper->setCurrentPosition(_stepper->getCurrentPosition() + stepOffset); + return 1; +} + + + + + + + +float RLS_lambda = 0.999; /* Forgetting factor */ +Matrix RLS_theta(4,1); /* The variables we want to indentify */ +Matrix RLS_in(4,1); /* Input data */ +Matrix RLS_out(1,1); /* Output data */ +Matrix RLS_gain(4,1); /* RLS gain */ +Matrix RLS_P(4,4); /* Inverse of correction estimation */ +float oldPos_fl32 = 0; +float oldInput_fl32 = 0; +bool rls_has_been_initialized_b = false; +void StepperWithLimits::identifyServo_AR(float newPos_fl32, float newInput_fl32) +{ + // Autoregressive (AR) model: estimation + // see https://www.youtube.com/watch?v=ANFOzqNCK-0 + + // Recursive Least Squares estimation with Arduino + // see https://github.com/pronenewbits/Arduino_AHRS_System/blob/master/ahrs_ekf/ahrs_ekf.ino + + // System: + // y_{k} = theta * y_{k-m} + + // init + if (rls_has_been_initialized_b == false) + { + RLS_in.vSetToZero(); + RLS_theta.vSetToZero(); + RLS_P.vSetIdentity(); + RLS_P = RLS_P * 1000; + rls_has_been_initialized_b = true; + } + + // write new observation to system output variable + RLS_out[0][0] = newPos_fl32; + + // cyclic shift of the model input + // h = [ -y_{k-1} ,-y_{k-2}, u_{k-1}, u_{k-2} ] + RLS_in[3][0] = RLS_in[2][0]; // lag the model input + RLS_in[1][0] = RLS_in[0][0]; // lag the model state + RLS_in[0][0] = -oldPos_fl32; + RLS_in[2][0] = oldInput_fl32; + + oldPos_fl32 = newPos_fl32; + oldInput_fl32 = newInput_fl32; + + // RLS the system parameters + // see https://de.wikipedia.org/wiki/RLS-Algorithmus + float err = (RLS_out - (RLS_in.Transpose() * RLS_theta))[0][0]; + RLS_gain = RLS_P*RLS_in / (RLS_lambda + RLS_in.Transpose()*RLS_P*RLS_in)[0][0]; + RLS_P = (RLS_P - RLS_gain*RLS_in.Transpose()*RLS_P)/RLS_lambda; + RLS_theta = RLS_theta + err*RLS_gain; + + +} + diff --git a/Arduino/Esp32/Main/.DS_Store b/Arduino/Esp32/Main/.DS_Store index 57ac87c1f1cb82529b6ba1169c61dc57026d0820..c6179262e7c765c76e309779dc1ed2b91f2b8d6c 100644 GIT binary patch delta 378 zcmZp1XbF&DU|?W$DortDU{C-uIe-{M3-C-V6q~50$f&+CU^hRb`eYt~w&zf7PA6C^M-K+=p137%Q6vy8GTBgep}zfV5H%aA=C-B$cA};JPj-P*CVXk@!&Xdfn9Ode^cY zOl3t{j(`wcD=u7-s1PT5>;c3LAywkci906*7x>TYWVLTM$*xfa6`HYj-+sI|Gw(Mu zZ+6B+B$_+!GLc0@6&zA7Jc83cNxqjyCYAJ)3y=c#M0HxDa~odJalDMSd0+?_0)~Jg zUeqZT28Lt0|#&9V7iFo>|ZM3Dx>X8MgzxF+TS_@uQwXkYCnt8-29QF<#M%r zy!?)RBbeCZ_IPL1Y!Ba(cdrG3=j>g#ool`BWNTsZQs9r4R!*LN?)=rQn_k}!K2+5v zp(6)98r{d|kFrjA+sk$*=ns@mY5S9`Mn7n^wA(WB+`0e$_YzbJWj}BWXbo;8OZ!O{ zn#$)rd+2+Czl}H2i^tI@Lvm?{dgN0;OY}UhJQ`CM&qvV)%w7YEk74muq5*TPneWdm z9?LH;#bPv9S1fYMNwFzt#aOL`tLjrxcJWQxpjOIn84#0xXY`q`^y%mO<(cyDte%=PdGU6n1NE36q9*+? z$q+CE9vp$_qn|7pyDnpHI^h5R2UnoU$q+CE9y$VIzGb(XsMg*NS-OUDuie7&E)JQb zUKmMbf|J^ghg93~xRIM;&*G4}@#Kx`hJF@C5>Jr+gFgd8v;NQSl$!Pb0Xqon1Ni^3 G{{I`AVt+pX delta 249 zcmZn(XmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAD6uhMH$S7qW*&i0jFTmVwI}}+ zlAjzSqB_}DM1FFPDCcHhQC3EIpbj8lVQ^;1XDDE(%*}UkNy^Dj0*Z0GEtN@`Tqq{P z0%lAUlVxIHn7lzOZnB<);$(gx_K=jHtPaFpQoNJ3r7R}zmzJH(AuT^yUPf?|jQqy3 z1|~sfu<;BM+(6nDh7#o8(Ln1>CLoSfaODRsyNy^X9 OVVJx}S^>qtS|$J`%{g!Y diff --git a/Arduino/libs/Copy/.DS_Store b/Arduino/libs/Copy/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9d5e4ee39ee0dd128cb4df3963c4343aff2aa614 GIT binary patch literal 6148 zcmeHKF-rq67=5V~ih|Td9PbZwsG{?=ToFY@xXnea6)pC>q84}l?%1DMJOWqO7iZ$<|TbEBxwMsdaqRl$^c3%g2g#j--LWGWgrSRBV?ufSiu@U z71R(7wDt+_fOp`pIUs9yNw3!!Rpi%i|9ze7Il&RGaE%jOc22ADahi0skiuqrQht&~ zQL~da$>XMyJv;@kwaNQv{ko6tSzgB-e*zZKK#V=C(uWG_*yei$8`Pdqd6(F7)T@uT z@mQ{A+*{3KjF+T&rIRpSeJ`S~j4hzOh zbj|LGt_AF(%{l7NSPhqGp~u_>Qb*HH{64C^t0#N5bM@mGu9opQj*fjb_7Bho->tLm?0K_8GI{2*jGGZVJVrVfl$P7anD$!7ty<#Xs zXFjm)LW`L}Lx<8MvmZOMvNsfEcTyGT=1`$QUwa3<1Fi!z=Cv&6e`EOl-zE7s?|^sU zUpb(PQ5@AN$)2qP;^eFiSPoevq+MoEQ&`#KSU<>7yv(A5-v#nO3@v5`nPK=p0@?;& Jc?YKIz$cJrvX%e< literal 0 HcmV?d00001 diff --git a/Arduino/libs/Copy/NimBLE-Arduino/.DS_Store b/Arduino/libs/Copy/NimBLE-Arduino/.DS_Store index 1de27d4f2c2280e8bf9ae3773ebd5e3284026d31..a0bc459a2290903f8aac419489c8cacf54c66c3d 100644 GIT binary patch delta 152 zcmZp1XmOa}&&aniU^hP_-)0^GQI`6gbi?4}{M-Tt5b)^c0FulM#SBFZ$+`J1E=f80 xNk9>xXv40J3P&B0WmE9T7Gxlq8UoY>H?=IdC@&{JFC8etD8Rt5d4Wg@Hvl9kBfJ0r delta 42 ycmZp1XmOa}&&ahgU^hP_*Jd68Q5K%E;G(>o{JeAq1_s8>x;(d-H?vFpWd{HW*$g%S diff --git a/SimHubPlugin/.DS_Store b/SimHubPlugin/.DS_Store index 4b9581db218be882110d16f1832ebd9d5f269b44..8c98c133528bdbe40de961e6b144940aecd613c9 100644 GIT binary patch literal 10244 zcmeHM&1(}u6n~r4CTZ=5;75xn3q=sEF|9=`USb*#JruAp)EqY*eOMO}hbAsRNBV0)P&oTNOO3AOD~>cYtO!?FJM*C{`c}8i-o@h+*lo zgB6HlJgfP;0S&~-QZqx3p4rkT6iXjHEL*XYl?|wA4FU#%UIh5;9;Y;IQES;1=l6RU zN&iwsiD@pkI_H%9dPDV%%`F_s*Zq86pZ|F?*1zxVvkom+_sauD8yjJ*>ky+6Do_KT zG?mCFk6u!Zsu3ICgHPI61eYgljIDeGSDe&{w6W_R+NejvHbzHFN;VJaI{am?qZ;-wW7ym2ff^iWYU9He zRjJiiBWw~HhiMtJ7r>mEjlh2gx>zxRY4bAHDwx0I|C z45U)Y)Y|0K&d%*ynOXbBoy_j6y|Xxv=Y_@j-Q863+|13p57#!`y63-Prw~MpF_*D` z9JU-D+8crT*z|{^5s7yw#1&Q&>FB7yc>EhrtmoTunx5->93pI85?i5w0N(5$O2peX zyaqk|!v1G7`~7rEPiW=K6%{!>x};CX^9k=(88VuP`Y|XOS(hSSjbLLp5rYkErl#76 zJ)6qnH47urS4N;g=>lZ>@<~Lxv!5?0M2_JVscs;zKn6~sOdz3@vA%Wq<{^32bdpZP zTcjJg=Q#BVFQ?7kx&c)pXw-E)sJf2F3*P`xVs}{tnSok>K!O`cxPo+VEd0(qnO`N4gArmT!{m6Lsciqj JU}GU8GXOk?9x?y` diff --git a/SimHubPlugin/SettingsControlDemo.xaml.cs b/SimHubPlugin/SettingsControlDemo.xaml.cs index 42bdc0e8..c7b63abc 100644 --- a/SimHubPlugin/SettingsControlDemo.xaml.cs +++ b/SimHubPlugin/SettingsControlDemo.xaml.cs @@ -21,7 +21,7 @@ using static System.Net.Mime.MediaTypeNames; using System.Runtime.InteropServices.ComTypes; using Microsoft.Win32; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; using System.Windows.Input; using System.Windows.Shapes; using MouseEventArgs = System.Windows.Input.MouseEventArgs; @@ -41,19 +41,23 @@ namespace User.PluginSdkDemo public partial class SettingsControlDemo : System.Windows.Controls.UserControl { - + // payload revisiom public uint pedalConfigPayload_version = 110; + // pyload types + public uint pedalConfigPayload_type = 100; + public uint pedalActionPayload_type = 110; + public uint indexOfSelectedPedal_u = 1; public DataPluginDemo Plugin { get; } public DAP_config_st[] dap_config_st = new DAP_config_st[3]; - private string stringValue; - - - - + private string stringValue; + + + + @@ -101,50 +105,50 @@ public partial class SettingsControlDemo : System.Windows.Controls.UserControl //} - private void DrawGridLines() - { - // Specify the number of rows and columns for the grid - int rowCount = 5; - int columnCount = 5; - - // Calculate the width and height of each cell - double cellWidth = canvas.Width / columnCount; - double cellHeight = canvas.Height / rowCount; - - // Draw horizontal gridlines - for (int i = 1; i < rowCount; i++) - { - Line line = new Line - { - X1 = 0, - Y1 = i * cellHeight, - X2 = canvas.Width, - Y2 = i * cellHeight, - //Stroke = Brush.Black, - Stroke = System.Windows.Media.Brushes.LightSteelBlue, - StrokeThickness = 1, - Opacity = 0.1 - - }; - canvas.Children.Add(line); - } - - // Draw vertical gridlines - for (int i = 1; i < columnCount; i++) - { - Line line = new Line - { - X1 = i * cellWidth, - Y1 = 0, - X2 = i * cellWidth, - Y2 = canvas.Height, - //Stroke = Brushes.Black, - Stroke = System.Windows.Media.Brushes.LightSteelBlue, - StrokeThickness = 1, - Opacity = 0.1 - }; - canvas.Children.Add(line); - } + private void DrawGridLines() + { + // Specify the number of rows and columns for the grid + int rowCount = 5; + int columnCount = 5; + + // Calculate the width and height of each cell + double cellWidth = canvas.Width / columnCount; + double cellHeight = canvas.Height / rowCount; + + // Draw horizontal gridlines + for (int i = 1; i < rowCount; i++) + { + Line line = new Line + { + X1 = 0, + Y1 = i * cellHeight, + X2 = canvas.Width, + Y2 = i * cellHeight, + //Stroke = Brush.Black, + Stroke = System.Windows.Media.Brushes.LightSteelBlue, + StrokeThickness = 1, + Opacity = 0.1 + + }; + canvas.Children.Add(line); + } + + // Draw vertical gridlines + for (int i = 1; i < columnCount; i++) + { + Line line = new Line + { + X1 = i * cellWidth, + Y1 = 0, + X2 = i * cellWidth, + Y2 = canvas.Height, + //Stroke = Brushes.Black, + Stroke = System.Windows.Media.Brushes.LightSteelBlue, + StrokeThickness = 1, + Opacity = 0.1 + }; + canvas.Children.Add(line); + } } private void InitReadStructFromJson() @@ -219,10 +223,10 @@ private void UpdateSerialPortList_click() } SerialPortSelection.DataContext = SerialPortSelectionArray; - } - - private bool isDragging = false; - private Point offset; + } + + private bool isDragging = false; + private Point offset; @@ -232,7 +236,7 @@ public SettingsControlDemo() for (uint pedalIdx = 0; pedalIdx < 3; pedalIdx++) { - dap_config_st[pedalIdx].payloadHeader_.payloadType = 100; + dap_config_st[pedalIdx].payloadHeader_.payloadType = (byte)pedalConfigPayload_type; dap_config_st[pedalIdx].payloadHeader_.version = (byte)pedalConfigPayload_version; dap_config_st[pedalIdx].payloadPedalConfig_.pedalStartPosition = 35; @@ -276,23 +280,23 @@ public SettingsControlDemo() dap_config_st[pedalIdx].payloadPedalConfig_.loadcell_rating = 150; - InitializeComponent(); - - // debug mode invisiable - text_debug_flag.Opacity = 0; - text_debug_PID_para.Opacity = 0; - text_debug_dgain.Opacity = 0; - text_debug_igain.Opacity = 0; - text_debug_pgain.Opacity = 0; - text_serial.Opacity = 0; - TextBox_serialMonitor.Visibility= System.Windows.Visibility.Hidden; - PID_tuning_D_gain_slider.Opacity = 0; - PID_tuning_I_gain_slider.Opacity = 0; - PID_tuning_P_gain_slider.Opacity = 0; - debugFlagSlider_0.Opacity = 0; - btn_serial.Visibility = System.Windows.Visibility.Hidden; - btn_system_id.Visibility = System.Windows.Visibility.Hidden; - //setting drawing color with Simhub theme workaround + InitializeComponent(); + + // debug mode invisiable + text_debug_flag.Opacity = 0; + text_debug_PID_para.Opacity = 0; + text_debug_dgain.Opacity = 0; + text_debug_igain.Opacity = 0; + text_debug_pgain.Opacity = 0; + text_serial.Opacity = 0; + TextBox_serialMonitor.Visibility= System.Windows.Visibility.Hidden; + PID_tuning_D_gain_slider.Opacity = 0; + PID_tuning_I_gain_slider.Opacity = 0; + PID_tuning_P_gain_slider.Opacity = 0; + debugFlagSlider_0.Opacity = 0; + btn_serial.Visibility = System.Windows.Visibility.Hidden; + btn_system_id.Visibility = System.Windows.Visibility.Hidden; + //setting drawing color with Simhub theme workaround text_min_force.Foreground= btn_update.Background; text_max_force.Foreground = btn_update.Background; text_max_pos.Foreground = btn_update.Background; @@ -309,32 +313,32 @@ public SettingsControlDemo() rect9.Fill = btn_update.Background; Line_V_force.Stroke = btn_update.Background; Line_H_pos.Stroke = btn_update.Background; - Polyline_BrakeForceCurve.Stroke = btn_update.Background; - - Line_H_damping.Stroke = btn_update.Background; - text_damping.Foreground = btn_update.Background; - rect_damping.Fill = btn_update.Background; - Line_H_ABS.Stroke = btn_update.Background; - text_ABS.Foreground = btn_update.Background; - rect_ABS.Fill = btn_update.Background; - Line_H_ABS_freq.Stroke = btn_update.Background; - text_ABS_freq.Foreground = btn_update.Background; - rect_ABS_freq.Fill = btn_update.Background; - Line_H_max_game.Stroke = btn_update.Background; - text_max_game.Foreground = btn_update.Background; - rect_max_game.Fill = btn_update.Background; - - Line_H_KF.Stroke = btn_update.Background; - text_KF.Foreground = btn_update.Background; - rect_KF.Fill = btn_update.Background; - - Line_H_LC_rating.Stroke = btn_update.Background; - text_LC_rating.Foreground = btn_update.Background; + Polyline_BrakeForceCurve.Stroke = btn_update.Background; + + Line_H_damping.Stroke = btn_update.Background; + text_damping.Foreground = btn_update.Background; + rect_damping.Fill = btn_update.Background; + Line_H_ABS.Stroke = btn_update.Background; + text_ABS.Foreground = btn_update.Background; + rect_ABS.Fill = btn_update.Background; + Line_H_ABS_freq.Stroke = btn_update.Background; + text_ABS_freq.Foreground = btn_update.Background; + rect_ABS_freq.Fill = btn_update.Background; + Line_H_max_game.Stroke = btn_update.Background; + text_max_game.Foreground = btn_update.Background; + rect_max_game.Fill = btn_update.Background; + + Line_H_KF.Stroke = btn_update.Background; + text_KF.Foreground = btn_update.Background; + rect_KF.Fill = btn_update.Background; + + Line_H_LC_rating.Stroke = btn_update.Background; + text_LC_rating.Foreground = btn_update.Background; rect_LC_rating.Fill = btn_update.Background; - - // Call this method to generate gridlines on the Canvas - DrawGridLines(); - + + // Call this method to generate gridlines on the Canvas + DrawGridLines(); + } } @@ -558,10 +562,10 @@ private void updateTheGuiFromConfig() else { Simulate_ABS_check.IsChecked = false; - } - // dynamic PID checkbox + } + // dynamic PID checkbox if (dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.control_strategy_b == 1) - { + { dynamic_PID_checkbox.IsChecked = true; } else @@ -633,45 +637,45 @@ private void updateTheGuiFromConfig() //damping slider double damping_max = 255; dx = canvas_horz_damping.Width / damping_max; - Canvas.SetLeft(rect_damping, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress); - text_damping.Text = "Damping: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress; - Canvas.SetLeft(text_damping, Canvas.GetLeft(rect_damping) + rect_damping.Width / 2); + Canvas.SetLeft(rect_damping, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress); + text_damping.Text = "Damping: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress; + Canvas.SetLeft(text_damping, Canvas.GetLeft(rect_damping) + rect_damping.Width / 2); Canvas.SetTop(text_damping, canvas_horz_damping.Height - 10); //ABS amplitude slider double abs_max = 255; dx = canvas_horz_ABS.Width / abs_max; - Canvas.SetLeft(rect_ABS, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude); - text_ABS.Text = "ABS/TC Amplitude: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude; - Canvas.SetLeft(text_ABS, Canvas.GetLeft(rect_ABS) + rect_ABS.Width / 2); + Canvas.SetLeft(rect_ABS, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude); + text_ABS.Text = "ABS/TC Amplitude: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude; + Canvas.SetLeft(text_ABS, Canvas.GetLeft(rect_ABS) + rect_ABS.Width / 2); Canvas.SetTop(text_ABS, canvas_horz_ABS.Height - 10); //ABS freq slider double abs_freq_max = 30; dx = canvas_horz_ABS_freq.Width / abs_freq_max; - Canvas.SetLeft(rect_ABS_freq, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency); - text_ABS_freq.Text = "ABS/TC Frequency: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency+"Hz"; - Canvas.SetLeft(text_ABS_freq, Canvas.GetLeft(rect_ABS_freq) + rect_ABS_freq.Width / 2); + Canvas.SetLeft(rect_ABS_freq, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency); + text_ABS_freq.Text = "ABS/TC Frequency: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency+"Hz"; + Canvas.SetLeft(text_ABS_freq, Canvas.GetLeft(rect_ABS_freq) + rect_ABS_freq.Width / 2); Canvas.SetTop(text_ABS_freq, canvas_horz_ABS_freq.Height - 10); //max game output slider double max_game_max = 100; dx = canvas_horz_max_game.Width / max_game_max; - Canvas.SetLeft(rect_max_game, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput); - text_max_game.Text = "Max Game" + "\n Output: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput; - Canvas.SetLeft(text_max_game, Canvas.GetLeft(rect_max_game) - text_max_game.Width / 2+rect_max_game.Width/2); - Canvas.SetTop(text_max_game, canvas_horz_max_game.Height - 10); - //KF SLider + Canvas.SetLeft(rect_max_game, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput); + text_max_game.Text = "Max Game" + "\n Output: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput; + Canvas.SetLeft(text_max_game, Canvas.GetLeft(rect_max_game) - text_max_game.Width / 2+rect_max_game.Width/2); + Canvas.SetTop(text_max_game, canvas_horz_max_game.Height - 10); + //KF SLider double KF_max = 255; dx = canvas_horz_KF.Width / KF_max; - Canvas.SetLeft(rect_KF, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise); - text_KF.Text = "KF: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise; - Canvas.SetLeft(text_KF, Canvas.GetLeft(rect_KF) - text_KF.Width / 2 + rect_KF.Width/2); - Canvas.SetTop(text_KF, canvas_horz_KF.Height - 10); - //LC rating slider - + Canvas.SetLeft(rect_KF, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise); + text_KF.Text = "KF: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise; + Canvas.SetLeft(text_KF, Canvas.GetLeft(rect_KF) - text_KF.Width / 2 + rect_KF.Width/2); + Canvas.SetTop(text_KF, canvas_horz_KF.Height - 10); + //LC rating slider + double LC_max = 510; dx = canvas_horz_LC_rating.Width / LC_max; - Canvas.SetLeft(rect_LC_rating, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2); - text_LC_rating.Text = "LC Rating: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2+"Kg"; - Canvas.SetLeft(text_LC_rating, Canvas.GetLeft(rect_LC_rating) - text_LC_rating.Width / 2 + rect_LC_rating.Width/2); + Canvas.SetLeft(rect_LC_rating, dx * dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2); + text_LC_rating.Text = "LC Rating: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2+"Kg"; + Canvas.SetLeft(text_LC_rating, Canvas.GetLeft(rect_LC_rating) - text_LC_rating.Width / 2 + rect_LC_rating.Width/2); Canvas.SetTop(text_LC_rating, canvas_horz_LC_rating.Height - 10); //// Select serial port accordingly @@ -1143,7 +1147,8 @@ unsafe public void SendConfigToPedal_click(object sender, RoutedEventArgs e) // compute checksum //getBytes(this.dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_) - this.dap_config_st[indexOfSelectedPedal_u].payloadHeader_.version = (byte)pedalConfigPayload_version; + this.dap_config_st[indexOfSelectedPedal_u].payloadHeader_.version = (byte)pedalConfigPayload_version; + this.dap_config_st[indexOfSelectedPedal_u].payloadHeader_.payloadType = (byte)pedalConfigPayload_type; this.dap_config_st[indexOfSelectedPedal_u].payloadHeader_.storeToEeprom = 1; DAP_config_st tmp = this.dap_config_st[indexOfSelectedPedal_u]; @@ -1275,8 +1280,8 @@ unsafe public void ReadConfigFromPedal_click(object sender, RoutedEventArgs e) } else { - TextBox_debugOutput.Text += "Data size mismatch!\n"; - TextBox_debugOutput.Text += "Expected size: " + length + "\n"; + TextBox_debugOutput.Text += "Data size mismatch!\n"; + TextBox_debugOutput.Text += "Expected size: " + length + "\n"; TextBox_debugOutput.Text += "Received size: " + receivedLength; DateTime startTime = DateTime.Now; @@ -1389,10 +1394,10 @@ unsafe public void ConnectToPedal_click(object sender, RoutedEventArgs e) Plugin._serialPort[indexOfSelectedPedal_u].DiscardInBuffer(); // send query command - Plugin._serialPort[indexOfSelectedPedal_u].Write(newBuffer, 0, newBuffer.Length); - - - // wait for response + Plugin._serialPort[indexOfSelectedPedal_u].Write(newBuffer, 0, newBuffer.Length); + + + // wait for response System.Threading.Thread.Sleep(100); TextBox_debugOutput.Text += "\n"+"Reading pedal config"; @@ -1410,9 +1415,9 @@ unsafe public void ConnectToPedal_click(object sender, RoutedEventArgs e) Plugin._serialPort[indexOfSelectedPedal_u].Read(newBuffer_config, 0, length); - DAP_config_st pedalConfig_read_st = getConfigFromBytes(newBuffer_config); - - // check CRC + DAP_config_st pedalConfig_read_st = getConfigFromBytes(newBuffer_config); + + // check CRC DAP_config_st* v_config = &pedalConfig_read_st; byte* p_config = (byte*)v_config; @@ -1431,15 +1436,15 @@ unsafe public void ConnectToPedal_click(object sender, RoutedEventArgs e) TextBox_debugOutput.Text += "Received size: " + receivedLength; } } - else + else { TextBox_debugOutput.Text += "Data size mismatch"; - DateTime startTime = DateTime.Now; - //TimeSpan diffTime = DateTime.Now - startTime; - //int millisceonds = (int)diffTime.TotalSeconds; - - + DateTime startTime = DateTime.Now; + //TimeSpan diffTime = DateTime.Now - startTime; + //int millisceonds = (int)diffTime.TotalSeconds; + + while ((Plugin._serialPort[indexOfSelectedPedal_u].BytesToRead > 0) && (DateTime.Now - startTime).Seconds < 2) { string message = Plugin._serialPort[indexOfSelectedPedal_u].ReadLine(); @@ -1447,11 +1452,11 @@ unsafe public void ConnectToPedal_click(object sender, RoutedEventArgs e) } - } - - - - + } + + + + } catch (Exception ex) { @@ -1594,109 +1599,109 @@ private void DisconnectToPedal_click(object sender, RoutedEventArgs e) TextBox_debugOutput.Text = "Not Checked Serialport close"; } - } - - private void Simulate_ABS_check_Checked(object sender, RoutedEventArgs e) - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.Simulate_ABS_trigger = 1; - TextBox_debugOutput.Text = "simulateABS: on"; + } + + private void Simulate_ABS_check_Checked(object sender, RoutedEventArgs e) + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.Simulate_ABS_trigger = 1; + TextBox_debugOutput.Text = "simulateABS: on"; rect_SABS.Opacity = 1; rect_SABS_Control.Opacity = 1; text_SABS.Opacity = 1; - - } - private void Simulate_ABS_check_Unchecked(object sender, RoutedEventArgs e) - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.Simulate_ABS_trigger = 0; - TextBox_debugOutput.Text = "simulateABS: off"; + + } + private void Simulate_ABS_check_Unchecked(object sender, RoutedEventArgs e) + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.Simulate_ABS_trigger = 0; + TextBox_debugOutput.Text = "simulateABS: off"; rect_SABS.Opacity = 0; rect_SABS_Control.Opacity = 0; text_SABS.Opacity = 0; - - } - - - - //dragable control rect. - - /*private void InitializeRectanglePositions() - { - rectanglePositions.Add("rect1", new Point(75, 75)); - rectanglePositions.Add("rect2", new Point(155, 55)); - rectanglePositions.Add("rect3", new Point(235, 35)); - rectanglePositions.Add("rect4", new Point(315, 15)); - }*/ - - private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - isDragging = true; - var rectangle = sender as Rectangle; - offset = e.GetPosition(rectangle); - rectangle.CaptureMouse(); - } - - private void Rectangle_MouseMove(object sender, MouseEventArgs e) - { - if (isDragging) - { - var rectangle = sender as Rectangle; - //double x = e.GetPosition(canvas).X - offset.X; - double y = e.GetPosition(canvas).Y - offset.Y; - - // Ensure the rectangle stays within the canvas - //x = Math.Max(0, Math.Min(x, canvas.ActualWidth - rectangle.ActualWidth)); - y = Math.Max(-1*rectangle.Height/2, Math.Min(y, canvas.Height - rectangle.Height/2)); - - //Canvas.SetLeft(rectangle, x); - Canvas.SetTop(rectangle, y); - double y_max = 100; - double dx = canvas.Height / y_max; - double y_actual = (canvas.Height - y -rectangle.Height/2)/dx; - if (rectangle.Name == "rect0") - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p000 = Convert.ToByte(y_actual); + + } + + + + //dragable control rect. + + /*private void InitializeRectanglePositions() + { + rectanglePositions.Add("rect1", new Point(75, 75)); + rectanglePositions.Add("rect2", new Point(155, 55)); + rectanglePositions.Add("rect3", new Point(235, 35)); + rectanglePositions.Add("rect4", new Point(315, 15)); + }*/ + + private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + isDragging = true; + var rectangle = sender as Rectangle; + offset = e.GetPosition(rectangle); + rectangle.CaptureMouse(); + } + + private void Rectangle_MouseMove(object sender, MouseEventArgs e) + { + if (isDragging) + { + var rectangle = sender as Rectangle; + //double x = e.GetPosition(canvas).X - offset.X; + double y = e.GetPosition(canvas).Y - offset.Y; + + // Ensure the rectangle stays within the canvas + //x = Math.Max(0, Math.Min(x, canvas.ActualWidth - rectangle.ActualWidth)); + y = Math.Max(-1*rectangle.Height/2, Math.Min(y, canvas.Height - rectangle.Height/2)); + + //Canvas.SetLeft(rectangle, x); + Canvas.SetTop(rectangle, y); + double y_max = 100; + double dx = canvas.Height / y_max; + double y_actual = (canvas.Height - y -rectangle.Height/2)/dx; + if (rectangle.Name == "rect0") + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p000 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:0%"; text_point_pos.Text += "\nForce: "+(int)y_actual+"%"; - } - if (rectangle.Name == "rect1") - { + } + if (rectangle.Name == "rect1") + { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p020 = Convert.ToByte(y_actual); + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p020 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:20%"; text_point_pos.Text += "\nForce: " + (int)y_actual + "%"; - } - if (rectangle.Name == "rect2") - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p040 = Convert.ToByte(y_actual); + } + if (rectangle.Name == "rect2") + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p040 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:40%"; text_point_pos.Text += "\nForce: " + (int)y_actual + "%"; - } - if (rectangle.Name == "rect3") - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p060 = Convert.ToByte(y_actual); + } + if (rectangle.Name == "rect3") + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p060 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:60%"; text_point_pos.Text += "\nForce: " + (int)y_actual + "%"; - } - if (rectangle.Name == "rect4") - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p080 = Convert.ToByte(y_actual); + } + if (rectangle.Name == "rect4") + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p080 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:80%"; text_point_pos.Text += "\nForce: " + (int)y_actual + "%"; - } - if (rectangle.Name == "rect5") - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p100 = Convert.ToByte(y_actual); + } + if (rectangle.Name == "rect5") + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.relativeForce_p100 = Convert.ToByte(y_actual); text_point_pos.Text = "Travel:100%"; text_point_pos.Text += "\nForce: " + (int)y_actual + "%"; - } + } text_point_pos.Opacity = 1; - Update_BrakeForceCurve(); - - - - // Update the position in the dictionary - //rectanglePositions[rectangle.Name] = new Point(x, y); + Update_BrakeForceCurve(); + + + + // Update the position in the dictionary + //rectanglePositions[rectangle.Name] = new Point(x, y); } } @@ -1833,203 +1838,203 @@ private void Rectangle_MouseMove_ABS(object sender, MouseEventArgs e) Canvas.SetLeft(text_SABS, x + rect_SABS_Control.Width); Canvas.SetLeft(rectangle, x-rect_SABS_Control.Width/2); - } - } - private void Rectangle_MouseMove_sigle_slider_H(object sender, MouseEventArgs e) - { - if (isDragging) - { - var rectangle = sender as Rectangle; - - - //damping - if (rectangle.Name == "rect_damping") - { - // Ensure the rectangle stays within the canvas - double damping_max = 255; - double x = e.GetPosition(canvas_horz_damping).X - offset.X; - double dx = canvas_horz_damping.Width / damping_max; - double min_position = 0 * dx; - double max_position = damping_max * dx; - //double dx = 100 / (canvas_horz_slider.Width - 10); - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress = Convert.ToByte(actual_x); - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPull = Convert.ToByte(actual_x); - text_damping.Text = "Damping: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress; - Canvas.SetLeft(text_damping, x + rect_damping.Width / 2); - Canvas.SetLeft(rectangle, x); - } - // ABS Amplitude - if (rectangle.Name == "rect_ABS") - { - // Ensure the rectangle stays within the canvas - double x = e.GetPosition(canvas_horz_ABS).X - offset.X; - double ABS_max = 255; - double dx = canvas_horz_ABS.Width / ABS_max; - double min_position = 0 * dx; - double max_position = ABS_max * dx; - //double dx = 100 / (canvas_horz_slider.Width - 10); - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude = Convert.ToByte(actual_x); - - text_ABS.Text = "ABS/TC Amplitude: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude; - Canvas.SetLeft(text_ABS, x + rect_ABS.Width / 2); - Canvas.SetLeft(rectangle, x); - } - //ABS freq - if (rectangle.Name == "rect_ABS_freq") - { - // Ensure the rectangle stays within the canvas - double x = e.GetPosition(canvas_horz_ABS_freq).X - offset.X; - double ABS_freq_max = 30; - double dx = canvas_horz_ABS_freq.Width / ABS_freq_max; - double min_position = 0 * dx; - double max_position = ABS_freq_max * dx; - //double dx = 100 / (canvas_horz_slider.Width - 10); - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency = Convert.ToByte(actual_x); - - text_ABS_freq.Text = "ABS/TC Frequency: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency+"Hz"; - Canvas.SetLeft(text_ABS_freq, x + rect_ABS_freq.Width / 2); - Canvas.SetLeft(rectangle, x); - } - //max game output - if (rectangle.Name == "rect_max_game") - { - // Ensure the rectangle stays within the canvas - double x = e.GetPosition(canvas_horz_max_game).X - offset.X; - double max_game_max = 100; - double dx = canvas_horz_max_game.Width / max_game_max; - double min_position = 0 * dx; - double max_position = max_game_max * dx; - //double dx = 100 / (canvas_horz_slider.Width - 10); - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput = Convert.ToByte(actual_x); - - text_max_game.Text = "Max Game" + "\n Output: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput; - Canvas.SetLeft(text_max_game, x - text_max_game.Width / 2+rect_max_game.Width/2); - Canvas.SetLeft(rectangle, x); - } - //KF Slider - - if (rectangle.Name == "rect_KF") - { - // Ensure the rectangle stays within the canvas - double x = e.GetPosition(canvas_horz_KF).X - offset.X; - double KF_max = 255; - double dx = canvas_horz_KF.Width / KF_max; - double min_position = 0 * dx; - double max_position = KF_max * dx; - - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise = Convert.ToByte(actual_x); - - text_KF.Text = "KF: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise; - Canvas.SetLeft(text_KF, x - text_KF.Width / 2+ rect_KF.Width/2); - Canvas.SetLeft(rectangle, x); - } - //LC rating slider - if (rectangle.Name == "rect_LC_rating") - { - // Ensure the rectangle stays within the canvas - double x = e.GetPosition(canvas_horz_LC_rating).X - offset.X; - double LC_max = 510; - double dx = canvas_horz_LC_rating.Width / LC_max; - double min_position = 0 * dx; - double max_position = LC_max * dx; - - x = Math.Max(min_position, Math.Min(x, max_position)); - double actual_x = x / dx; - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating = (byte)(actual_x / 2); - - text_LC_rating.Text = "LC Rating: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2 + "Kg"; - Canvas.SetLeft(text_LC_rating, x - text_LC_rating.Width / 2+rect_LC_rating.Width/2); - Canvas.SetLeft(rectangle, x); - } - - - - - } - } - private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) - { - if (isDragging) - { - var rectangle = sender as Rectangle; - isDragging = false; - rectangle.ReleaseMouseCapture(); + } + } + private void Rectangle_MouseMove_sigle_slider_H(object sender, MouseEventArgs e) + { + if (isDragging) + { + var rectangle = sender as Rectangle; + + + //damping + if (rectangle.Name == "rect_damping") + { + // Ensure the rectangle stays within the canvas + double damping_max = 255; + double x = e.GetPosition(canvas_horz_damping).X - offset.X; + double dx = canvas_horz_damping.Width / damping_max; + double min_position = 0 * dx; + double max_position = damping_max * dx; + //double dx = 100 / (canvas_horz_slider.Width - 10); + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress = Convert.ToByte(actual_x); + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPull = Convert.ToByte(actual_x); + text_damping.Text = "Damping: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.dampingPress; + Canvas.SetLeft(text_damping, x + rect_damping.Width / 2); + Canvas.SetLeft(rectangle, x); + } + // ABS Amplitude + if (rectangle.Name == "rect_ABS") + { + // Ensure the rectangle stays within the canvas + double x = e.GetPosition(canvas_horz_ABS).X - offset.X; + double ABS_max = 255; + double dx = canvas_horz_ABS.Width / ABS_max; + double min_position = 0 * dx; + double max_position = ABS_max * dx; + //double dx = 100 / (canvas_horz_slider.Width - 10); + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude = Convert.ToByte(actual_x); + + text_ABS.Text = "ABS/TC Amplitude: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absAmplitude; + Canvas.SetLeft(text_ABS, x + rect_ABS.Width / 2); + Canvas.SetLeft(rectangle, x); + } + //ABS freq + if (rectangle.Name == "rect_ABS_freq") + { + // Ensure the rectangle stays within the canvas + double x = e.GetPosition(canvas_horz_ABS_freq).X - offset.X; + double ABS_freq_max = 30; + double dx = canvas_horz_ABS_freq.Width / ABS_freq_max; + double min_position = 0 * dx; + double max_position = ABS_freq_max * dx; + //double dx = 100 / (canvas_horz_slider.Width - 10); + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency = Convert.ToByte(actual_x); + + text_ABS_freq.Text = "ABS/TC Frequency: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.absFrequency+"Hz"; + Canvas.SetLeft(text_ABS_freq, x + rect_ABS_freq.Width / 2); + Canvas.SetLeft(rectangle, x); + } + //max game output + if (rectangle.Name == "rect_max_game") + { + // Ensure the rectangle stays within the canvas + double x = e.GetPosition(canvas_horz_max_game).X - offset.X; + double max_game_max = 100; + double dx = canvas_horz_max_game.Width / max_game_max; + double min_position = 0 * dx; + double max_position = max_game_max * dx; + //double dx = 100 / (canvas_horz_slider.Width - 10); + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput = Convert.ToByte(actual_x); + + text_max_game.Text = "Max Game" + "\n Output: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.maxGameOutput; + Canvas.SetLeft(text_max_game, x - text_max_game.Width / 2+rect_max_game.Width/2); + Canvas.SetLeft(rectangle, x); + } + //KF Slider + + if (rectangle.Name == "rect_KF") + { + // Ensure the rectangle stays within the canvas + double x = e.GetPosition(canvas_horz_KF).X - offset.X; + double KF_max = 255; + double dx = canvas_horz_KF.Width / KF_max; + double min_position = 0 * dx; + double max_position = KF_max * dx; + + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise = Convert.ToByte(actual_x); + + text_KF.Text = "KF: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.kf_modelNoise; + Canvas.SetLeft(text_KF, x - text_KF.Width / 2+ rect_KF.Width/2); + Canvas.SetLeft(rectangle, x); + } + //LC rating slider + if (rectangle.Name == "rect_LC_rating") + { + // Ensure the rectangle stays within the canvas + double x = e.GetPosition(canvas_horz_LC_rating).X - offset.X; + double LC_max = 510; + double dx = canvas_horz_LC_rating.Width / LC_max; + double min_position = 0 * dx; + double max_position = LC_max * dx; + + x = Math.Max(min_position, Math.Min(x, max_position)); + double actual_x = x / dx; + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating = (byte)(actual_x / 2); + + text_LC_rating.Text = "LC Rating: " + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.loadcell_rating*2 + "Kg"; + Canvas.SetLeft(text_LC_rating, x - text_LC_rating.Width / 2+rect_LC_rating.Width/2); + Canvas.SetLeft(rectangle, x); + } + + + + + } + } + private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (isDragging) + { + var rectangle = sender as Rectangle; + isDragging = false; + rectangle.ReleaseMouseCapture(); text_point_pos.Opacity=0; - } - } - private void PID_type_checkbox_Checked(object sender, RoutedEventArgs e) - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.control_strategy_b = (byte)1; - TextBox_debugOutput.Text = "Dynamic PID on"; - } - private void PID_type_checkbox_Unchecked(object sender, RoutedEventArgs e) - { - dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.control_strategy_b = (byte)0; - TextBox_debugOutput.Text = "Dynamic PID off"; - } - private void Debug_checkbox_Checked(object sender, RoutedEventArgs e) - { - - text_debug_flag.Opacity = 1; - text_debug_PID_para.Opacity = 1; - text_debug_dgain.Opacity = 1; - text_debug_igain.Opacity = 1; - text_debug_pgain.Opacity = 1; - text_serial.Opacity = 1; - TextBox_serialMonitor.Visibility = System.Windows.Visibility.Visible; - PID_tuning_D_gain_slider.Opacity = 1; - PID_tuning_I_gain_slider.Opacity = 1; - PID_tuning_P_gain_slider.Opacity= 1; - debugFlagSlider_0.Opacity = 1; - btn_serial.Visibility = System.Windows.Visibility.Visible; - btn_system_id.Visibility = System.Windows.Visibility.Visible; - - - } - private void Debug_checkbox_Unchecked(object sender, RoutedEventArgs e) - { - text_debug_flag.Opacity = 0; - text_debug_PID_para.Opacity = 0; - text_debug_dgain.Opacity = 0; - text_debug_igain.Opacity = 0; - text_debug_pgain.Opacity = 0; - text_serial.Opacity = 0; - TextBox_serialMonitor.Visibility = System.Windows.Visibility.Hidden; - PID_tuning_D_gain_slider.Opacity = 0; - PID_tuning_I_gain_slider.Opacity = 0; - PID_tuning_P_gain_slider.Opacity = 0; - debugFlagSlider_0.Opacity = 0; - btn_serial.Visibility = System.Windows.Visibility.Hidden; - btn_system_id.Visibility = System.Windows.Visibility.Hidden; - - - + } + } + private void PID_type_checkbox_Checked(object sender, RoutedEventArgs e) + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.control_strategy_b = (byte)1; + TextBox_debugOutput.Text = "Dynamic PID on"; } - private void CheckBox_Checked(object sender, RoutedEventArgs e) - { - + private void PID_type_checkbox_Unchecked(object sender, RoutedEventArgs e) + { + dap_config_st[indexOfSelectedPedal_u].payloadPedalConfig_.control_strategy_b = (byte)0; + TextBox_debugOutput.Text = "Dynamic PID off"; + } + private void Debug_checkbox_Checked(object sender, RoutedEventArgs e) + { + + text_debug_flag.Opacity = 1; + text_debug_PID_para.Opacity = 1; + text_debug_dgain.Opacity = 1; + text_debug_igain.Opacity = 1; + text_debug_pgain.Opacity = 1; + text_serial.Opacity = 1; + TextBox_serialMonitor.Visibility = System.Windows.Visibility.Visible; + PID_tuning_D_gain_slider.Opacity = 1; + PID_tuning_I_gain_slider.Opacity = 1; + PID_tuning_P_gain_slider.Opacity= 1; + debugFlagSlider_0.Opacity = 1; + btn_serial.Visibility = System.Windows.Visibility.Visible; + btn_system_id.Visibility = System.Windows.Visibility.Visible; + + + } + private void Debug_checkbox_Unchecked(object sender, RoutedEventArgs e) + { + text_debug_flag.Opacity = 0; + text_debug_PID_para.Opacity = 0; + text_debug_dgain.Opacity = 0; + text_debug_igain.Opacity = 0; + text_debug_pgain.Opacity = 0; + text_serial.Opacity = 0; + TextBox_serialMonitor.Visibility = System.Windows.Visibility.Hidden; + PID_tuning_D_gain_slider.Opacity = 0; + PID_tuning_I_gain_slider.Opacity = 0; + PID_tuning_P_gain_slider.Opacity = 0; + debugFlagSlider_0.Opacity = 0; + btn_serial.Visibility = System.Windows.Visibility.Hidden; + btn_system_id.Visibility = System.Windows.Visibility.Hidden; + + + + } + private void CheckBox_Checked(object sender, RoutedEventArgs e) + { + } - /* -private void GetRectanglePositions() -{ - foreach (var kvp in rectanglePositions) - { - Console.WriteLine($"{kvp.Key}: X={kvp.Value.X}, Y={kvp.Value.Y}"); - } + /* +private void GetRectanglePositions() +{ + foreach (var kvp in rectanglePositions) + { + Console.WriteLine($"{kvp.Key}: X={kvp.Value.X}, Y={kvp.Value.Y}"); + } } -*/ - +*/ + } } diff --git a/SimHubPlugin/obj/.DS_Store b/SimHubPlugin/obj/.DS_Store index e0cb25ccffedc9bda53ac6b88a1769d297037a6b..d94d4bbcfb1ed9f7355cc113093fd10f3e4c6cb3 100644 GIT binary patch delta 328 zcmZoMXfc=|#>B!ku~2NHo+2a9#(>?7iwl^U7%*idDf7B6OMG65G1sO;-usZ;?Z?<3(VXQ~B zd3GC6f}J4<=&l?fPGl%%NJX|iT6iwZb_`Vr7vNTf>WT)SBdnSCFm7h&;O78_)8<6x Y@640=MI1R885o#=E@9XlA+m-U0Kg7Pod5s; delta 76 zcmZoMXfc=|#>B)qu~2NHo+2a5#(>?7j4YFRSac^pXW`#`f`x@~a}3*R#*GaE%$wOc f_&I=THw$unXP(S2;>f`O1dI#}ESn=l)-VGA11=Ij diff --git a/SimHubPlugin/obj/Release/.DS_Store b/SimHubPlugin/obj/Release/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..849a24dcb6924088aefbe6be15fd1c6d185ef3c1 GIT binary patch literal 10244 zcmeHMO>Yx15FM8aRRSTz2`YgWibO#uN+k|lkdl%VRRR=|!WEj2rb{>3)ut(M+dF@Q z0|z921wV=tycrwV-E2NcDgUd9 z75C%{q(Oh89g1n6`qZU2W3BapGN2471ImChpbY#C4B*V>w06!)EtLUfKpFVS0Q(0I znPtVv#7c1;C?o`cT*YHas3Q)LKAw{mClf2BE5@|ZgK=Gr3o(rCj`tonhpaf6SZTYH zvE9iyWaAE%h*i6V&op{PqAjMjim;2i897ht$m>e$FA5P6=@r*paN2*I9^d zuI8{W0oxb0+Th5S)ip5x4*Cb+tAjEqnE$5~W9u`<=wTdYW(b{)P!oQ#W6HeJW6qja zgqgK+W4y=O(qr71IrNf5AZ#P41mu&I0Q2-xx35Ro?%`V z8;`AUZ1)QT>G9U*o*$2AHCW(L%$?N!I14YrtBR;W^{fU6zF>0Optsd*hy4g^M!LX7 zW~_c#t2s}G9~{ZXhihNho8{VcX10kA(>U^*Ws9DRH;u8%2J|w5u2^GD?7O3smcS_1 z#kzZqmb3lhWX}Z6W|&xP25e32YqI0W%Ahs8;l(e|xV!YlNH2IocwjrX!9Wk4BF29yD1Kp8k=De(CI zzdrf@eJ=vwEAa&BkN+7k@vcDQe~Bx9=LSOK|9>+6{|-O)!TB!ku~2NHo+2ar#(>?7iyN4k7}+NqGV5%%U{Yli$VoR0PR`FQU;u*~ zQ6L$S+B)qu~2NHo+2aj#(>?7jLee_S#>sBu&6R_4rSZKxUt~}(`I%Keh#3z a&4L`?nJ4p$IC3xm0V4wg%jO7?HOv66eGyFn diff --git a/Validation/.DS_Store b/Validation/.DS_Store index b70d71e4260efa898366c10ed6c90cbfe94dbd60..fb64f33d4b05de55509a250e041d414ac14ea877 100644 GIT binary patch delta 179 zcmZn(XbG6$&&aniU^hP_-((&EyUF|l`T{xWhQZ1CxdjYhz_A-BVI-29@8Xh_lb-|> z<6vND(Agz^)DbF?f>lDGAOqPL0fx!vM3gpX3dl1uJ$nRXt8QK|_=c4YXjVmG_~eD+ f1_-9ga#j^RMFf%g%7AG_W delta 121 zcmZn(XbG6$&&ahgU^hP_*W~j8Mw9IXcqV5H$#1R{lxJjOV3>SQRCV)yp*O5-ty!B_ udw5OWC}DtLs!ZmV&lDGuUHwq)f2X*Bpyd(;smAd;J(;*yk;p9D1#E-|^2m6zH600UUp zT2}sgL52VZX9g#Rc!orVJRr_t$Y)3g^70u<8A=!mKx9t3VQ_MOZUN9N1_mGRy+D!( zUAg%#a2M=vn3r2T|EMFT&NyrqB0CikeDpV&dba(0b+tJJKtt)p2y5w65K#9xPoG5vmnQJ=E?jbo|FA~ QI5-#~5y!AOo@Wj-0B*-`GXMYp delta 247 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jG}fU^g=(?_@?nksl+wKeQugE%- diff --git a/Wiring/PowerPcb/.DS_Store b/Wiring/PowerPcb/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0