From 014963235cc7a3ee4917233fb9925cdc4a1ddbff Mon Sep 17 00:00:00 2001 From: Polarbearbo Date: Fri, 13 Jun 2025 10:23:15 -0400 Subject: [PATCH 1/6] done with header file for supercap --- README.md | 3 ++ control-base/devices/inc/supercap.h | 23 ++++++++-- control-base/devices/src/supercap.c | 67 +++++++++++++++------------- images/Locomotion_omni.png | Bin 0 -> 55202 bytes 4 files changed, 60 insertions(+), 33 deletions(-) create mode 100644 README.md create mode 100644 images/Locomotion_omni.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..63e79fa --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +![Project Logo](images/logo.png) + + diff --git a/control-base/devices/inc/supercap.h b/control-base/devices/inc/supercap.h index cf315c5..b0f6398 100644 --- a/control-base/devices/inc/supercap.h +++ b/control-base/devices/inc/supercap.h @@ -5,9 +5,11 @@ #include "bsp_can.h" #include "referee_system.h" #include "jetson_orin.h" - +#include "bsp_uart.h" #define SUPERCAP_POWER (20) +#define SUPERCAP_RX_BUFFER_SIZE (80) //larger than 6*10+2 +#define SUPERCAP_TX_BUFFER_SIZE (3) //todo finish this typedef struct { uint8_t can_bus; @@ -17,10 +19,25 @@ typedef struct uint8_t supercap_percent; uint8_t supercap_enabled_flag; + + //formate of rx + //printf("Vi:%2.2f Vo:%2.2f Pi:%3.2f Ii:%2.2f Io:%2.2f Pa:%3.2f\r\n", VIPMR, VOFWR,POW_IN, IIPWR, IOPWR, pref); + uint8_t rx_buffer[SUPERCAP_RX_BUFFER_SIZE]; + uint8_t tx_buffer[SUPERCAP_TX_BUFFER_SIZE]; // chnage this to other uint type if possible + struct { + float input_voltage; // Vi + float output_voltage; // Vo + float input_power; //Pi + float input_current; //Ii + float output_currenIi; //Io + float ref_power; //Pa + } supercap_data; + } Supercap_t; -void Supercap_Init(Supercap_t *g_supercap); -void Supercap_Decode(CAN_Instance_t *can_instance); + +void Supercap_Init(UART_HandleTypeDef *huartx); +void Supercap_Decode(UART_Instance_t *supercap_uart_instance_ptr); void Supercap_Send(void); extern Supercap_t g_supercap; diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index 4e5b933..620a1d9 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -1,51 +1,58 @@ #include "supercap.h" -#include "referee_system.h" - Supercap_t g_supercap; -CAN_Instance_t *supercap_can_instance; +// CAN_Instance_t *supercap_can_instance; +UART_Instance_t *supercap_uart_instance_ptr; extern Jetson_Orin_Data_t g_orin_data; - struct rx_data { - uint16_t cap_percentage; - uint16_t reserved1; - uint16_t reserved2; - uint16_t reserved3; -} g_supercap_rx_data; + uint16_t max_discharge; + uint16_t base_power; + int16_t cap_energy_percent; + uint16_t cap_state; +} g_supercap_data; -void Supercap_Init(Supercap_t *g_supercap) +void Supercap_Init(UART_HandleTypeDef *huartx) { // Initialize supercap - g_supercap->can_bus = 1; - g_supercap->tx_id = 0x2C8; - g_supercap->rx_id = 0x2C7; - supercap_can_instance = - CAN_Device_Register(g_supercap->can_bus, g_supercap->tx_id, - g_supercap->rx_id, Supercap_Decode); + // g_supercap->can_bus = 1; // can 2 + // g_supercap->tx_id = 0x2C8; + // g_supercap->rx_id = 0x2C7; + + //register uart instance + supercap_uart_instance_ptr = UART_Register(huartx, g_supercap.rx_buffer, SUPERCAP_RX_BUFFER_SIZE, Supercap_Decode); } -void Supercap_Decode(CAN_Instance_t *can_instance) +void Supercap_Decode(UART_Instance_t *supercap_uart_instance_ptr) { - // Recieve supercap data - uint16_t *supercap_rx = (uint16_t *) can_instance->rx_buffer; + // // Recieve supercap data + // uint16_t *supercap_rx = (uint16_t *) can_instance->rx_buffer; + + // g_supercap_data.max_discharge = supercap_rx[0]; + // g_supercap_data.base_power = supercap_rx[1]; + // g_supercap_data.cap_energy_percent = (int16_t) supercap_rx[2]; + // g_supercap_data.cap_state = supercap_rx[3]; + // // ! do not read more than 8 bytes from the buffer + +} - g_supercap_rx_data.cap_percentage = supercap_rx[0]; - g_supercap_rx_data.reserved1 = 0; - g_supercap_rx_data.reserved2 = 0; - g_supercap_rx_data.reserved3 = 0; - // ! do not read more than 8 bytes from the buffer +void Supercap_Timeout_Callback(void){ + UART_Service_Init(supercap_uart_instance_ptr); } +// fomrate PXXXP - sending XXX as power +// PVONP - Turn on supercap +// PVOFFP - Turn off supercap void Supercap_Send(void) { // Send supercap data - uint16_t *supercap_tx = (uint16_t *) supercap_can_instance->tx_buffer; - supercap_tx[0] = Referee_System.Robot_State.Chassis_Power_Max; // The power limit from the referee system - supercap_tx[1] = (uint16_t) Referee_System.Power_Heat.Chassis_Power; // the total power requested from the chassis - supercap_tx[2] = 0; - supercap_tx[3] = 0; + // uint16_t *supercap_tx = (uint16_t *) supercap_can_instance->tx_buffer; + // supercap_tx[0] = 0x003C; + // supercap_tx[1] = 0x003C; + // supercap_tx[2] = 0x2012; + // supercap_tx[3] = 0x0112; // ! do not write more than 8 bytes to the buffer - CAN_Transmit(supercap_can_instance); + // CAN_Transmit(supercap_can_instance); + UART_Transmit(supercap_uart_instance_ptr, g_supercap.tx_buffer,sizeof(g_supercap.tx_buffer), UART_DMA); } \ No newline at end of file diff --git a/images/Locomotion_omni.png b/images/Locomotion_omni.png new file mode 100644 index 0000000000000000000000000000000000000000..3bcad788fc89f8be4efd4ce4370329ab02e0a5bd GIT binary patch literal 55202 zcmd?R1yCICwl6y9;F91@(BQ#>O9&o3xF)ze3~s?;upq$+?(XiE;1Zl+2yPQ>@XP<4 zv(MRe_N{yOxmEAId+PPnn(3qfB~+h2qv!eT5{!;PL`*_T#=ywL{F;TAkN>TJppevi zX&G5Lc?FG+np)aAx_YK&<`$M#);6wg?jD{XFYk~qp<&?>kx_|BUz1Z()4rvD&o3w} zDlRE4tE+ElY-(<4ZR_hF7#tcN86BIMots}+{I#?U*@ABW-r3#TKY;x?zqq`*hTq)& zr56GK>0i}){{C0R{*zw#&w3#uBO@UL|I!Nq(eqi5@R3ny-=MybR0Do;e))E}e@e>ICkh=4tW$+z&ySiLBa7mn0Co9HRFA{6YtzyMf&X!>{B-Fs;)Jisv5H(sOaRM3p>#lE zR9^1E)$K{Fb=gw*o#?hA3pxM`fwUJ8k9PXgI2SRBHT`Tja>D>78_7G3!B7;(#wE?n zYVpvY37YE?=dldx|DlPhmp~y<`|lxM;{B)8 zhh1zi`-Pn1Xlq`$gGEbAwj2F0>O<}OG#Uq5MF+b}v9xMwn9}@UT$sCJxj;e67OSpV zn7~{;&ld&>q(oOE&$Il#+tZM2CHkc&K;A){ucyVi6|Sut9_zc^Qb3|?@vaiW%90J| z_YN&1#yN;j`AT$ZWBhAPuBv^2X&^zFlj|>cK2sT(a%APcHd#?d$sl`dJNNjTF*b7v zi-}Dx{&?3Zuq@%O&}qX~mZ8 zw<9{V^4xV_lCLpOTUcd%T~zk6`UQd=`BI&?|$_`MRAcYC`T&3J-)Ku-&&lSnK@Ae zF@k5Hs+v^qdAiqP;|!Ai?B>!V8Cm6Eh)5U1-5od(<~T1heobVU6Xat$Fmh~LBDtna ziUhtnV$*}04mQ7i+vYUGsA$V>VecT5FppYHoA5!cJSnaXo&F35p|=R=y2TkSMl{9O zFmt+_EtqH-1&M9QeTSITesaH=iO?+SI@9zC#$ywiZwPWBxnvi6h|E@c{8%eB7Wv)| zfrZ56`U16OBcd(qF>>n^4FtZEZOaz+u}%Bk++Zv)>`ZThb`9W3>alY{pz$d4wBJ%v z9D2LRy?<(5sQ6lB{fKXf zaotCpqQ_U1z3*|YpsrsU@vv2(v)c2!bz~ALWKi*p|7t%~ch(*{N8Nvwm^ZWYJY!J> zl+&(ruPIE6n%_M@d=pk7onYPlN#5^W z(tb8nBtl*$RiyJucTE<9*VFSQq01~GG6BMB;0-d4ivW^}!5R1R!Mcd^cbjWY!UE%^ zxAf!8_WMl|$+t@Lz|a#mcXp#e^gEg~G3vS+jbtWdENJ>{ zO}2akoT**ql~$yY&LlZW2^%g`@j?e!1w(REF#w4_nIfevc|G6WvP9)&UB(x?j))!# z!nFe-08dmN%tvz0J&wc%A1QEv%LDnqIn7Bd{ivLf9TyY?LL|`UUyG|B{X^*55wa|Yjgzpe)&wtFdjrcK6RYmkXb0HSs<#>!) z{Y!T9Tf>(*_L-fN1LndAIjm?B`yYb{6R6YK!gmYNzM5x6NtBI^nR+p|zFM%i%ef7v zSooQt8<~U<5VX+J*Yj*Ahd5++vBGU!;1W}~grgvfeM+8rogmDKTlNR~=&|nltFy(( z%VS$DF=~B}vnN2ztGYy6C=Iqffpg#(u^>bE2gEnS6!ATWBAPJ9MfthB88;>V-2tKe z;a$P#4t~#NnlWODoy~#G=S~;0q(UqUdi&l zb-_IZqv-;B7ccD-c%W9*84Mq^g3}EPCEl~oyRZ2^0jzAuM9%xU$W6~l(P))Xf$K=Z z-X2xa3UF6QEbYZr?QByPzn4R0^pDfu?V(!YJQQc;F&9I!d<7z`d6h-wR!wL%2Q$2> zwP7ZV9werVF;9Scu-Bmk*;Ji~!X8%vBH)7e7XRJ%5^@O=#HfT&kWBQ}>x=I2<*xdI z^=7Z6dH;gbGz8SNLzN#dp7t42tR3%s~{ViIoLKFy|V20%5Pz! z!E%l#F$>Ot8)t~fp_)-=+jKmgq3T_=1O=;Z{ zwGeEWL~Kba*l^$JGb0+@Pd`ZdAnZ(uc-UxTO-f*E~lf z;-PAXr-|8I$9EwXVe~TsDJhi3EPbQ%jPaXat^(qr$mX_?r$Dx<&(* z6N|lYPdaLreZHi%73>M{xqZ}TOACuMjHDLXVbTdCD&#Cd;bx34qU+9(QvNA_-!q** z&-aR`Dbi`wi>}m(r1l1I!wnLk&eA?B9#C@N#D!N6+&&bzSf_XvvHG}YaKyC|k7+F< z(X5I&6zoPFbkLoxD4i|TGUgHfp5IL|yQAQt7`CY6-$4Vys6yMIQGL_?X#042qt;b6 z&259Z7PeNHX{O=MqxN~=T~SQx@gmBe{>4W|c$`w=i3+ZcRnx5qSxlRIhYRX?6{VM_ zCNdy5aWDd4X311Rg$pm=@^jQY3#~XS@VKs5bo6ritjdukKhb+ntC>$9V;)I~%GweF z;SB#g=k7D?(`u}tn~(7)MlZ5{hoogQ6Urpwe3Lk1DWwV2)Dff!RR3FwB(FLdK#%!*AjW?Zn)asPlLdYK7WFOkujPZU!n8H! z@IW-P$D2_LXvfD;x!llquUG<0a!mk00K(MAum3&u|1ZrO@{C6=N&&A&{^}IsbIbuy z`~SJ9qWm{q_5Y<=|Nl})Q@GT?azM13TA4NDCkJ!T)mXa@cP2$lPD$lInXmtSBK&{T zeg!89=nKe4B}^`l_^qcW{_^rlQXIFeor{wb;>l+}6!UvN*kcaV?~NXtzKzg8l>1cyZ)4Xuz0zIVj+uXDpRH^O|S#mY;q+dN9mXjdFvt?894 zPT>8e$aP%HgkjL6NoDV9GGDowdv=x;S>)x)JzV;Q1!2QVs03-&&5Z<5WVVJfS?zIg zHlRT!dpR_>Q=F^mJoTsORcheMRaJf!d%vj2L94Jb5Nk#W+sAZ=OHey7i#DYpdUhnAi zY`lY)lyxY3+W3DK3s7^BPJl`wFwxH8*y6MK4qW=Crq2gkPBJ5rCNH>!PH0YU{X+xS zzDK=G=7b znbEK7BrHjPj*+*aB!a~zLbt3*Dir#Lpl*d}-a}`1$5I`??&I&~5($|{eH1(|WNBQu zafF}~9oA+0sYV=&l^v!~Y;74byHTnflpq%V4y)d#vcv(Zg6wvA5A>4=Y2TYQ=ZrWqb#R?5To=4} zRI5TC6=Ce5X;5Of=|23y*${>1@7*5Hy)@y#Eowe?QimtEo5jq~QUNpt-5u2@Z z)GA10LQ%R~$q%fVmL{YjP?HAyQ=&y3+o5I+!NplUxbA6*#-#XEGc%%0h#=NEX@Y*N zvwVC3y$x zggW8UaFLQ;QB5Z0+6c z=n_{{Ys|ra7Bp$UTOh~00GJC1eCkCEL;XphCWmpoz@Hvl+dRik+um&Vl3+SqW4{+! zi~R`@(vVbOthcA-;mt5V$BD7Fq))Fdo4r{AthS4qZCm7x*5x-m@ZcJK7-fi2M#%d)|7nz| zR{fW+@UPqw{68`=34E3pJ=YaOI%|%sa%X>WIK*G`OCMx2rT1$^mSw~u$x2F?kRJCd z0AW|;!S7uZ2ap^VuF}$Z#`kmZt4~!!E8W~Dq`PS@rY8X9nn80|vyB)IEFk9P$5a_V zqx}>1(}-Q#sEOvHwhhet{BK)aKm|FWQGoAw7JFd-v+t`6#l%rCTV=|>;3>mL!372vNN z#7CUdkA=s^-qTl)_;tEQU63)i;Ops2ncGq}R=i_2kp}ZBBbJZ=d=QK@wv?!Q*Rf|V zjd7&Sy~;P>VB>}Wi=Lb0nkC~j+(bSTIVPrR1G3AuKgY(sV!Yvlx9jDQN^QAdc7s=) zgUiAO5>YM7Ij>1h7qfY0(veg)aqkoD3GmmUPXO6b!^_Vgy8c>_O5Xw*J@>bTc^q@r z*rOl1U}4`MPQn-~r6&JjeRQ*FVW`QFL(SF&&R0!fU1aOdRtqK)wYl3&H;O6LET_}6 zt?5Vl93oLD33xOXJegcYh{0B{TbC3R*E!*%?JO@rK|FAZec1J8j<@p#Wev!wB}Xk& z0co`1zBcr5Qq_xe8*25Vi{XrI7M|bly&IOkqLQJIV3Nr%kusYn*+3EB3ZQU5?5Wy` z@&x>g7yRd9w~nU35|Ujyoubc?4*VN)ir{+UczgaB zoq?=_qTXE*#B$IxF143GJ> zYakA|_S4VwCFUy(Zi!jbVVsc+&8=i_!#^uN zc&MU9G@l%+J^{vcBkszCaVkJmxk&1#y7f&9M{Z#jw&U|&FL+6p$golaPO6-8ubHS? zrmF(_x`?9Rd!1ID6wEbd)QBwxaP0;%k75gybeNVMDy$N)AIzb>12tzgj&mp+{?UB^^ z^5pYJJNjU%>|#bAM%Vs$#AYx0R-m)TqkE)S%J=G&nXPqf0I+!;JP@M20r_#;d>@ zRDYmvVf6{n^D<|l&CgO^=u1j7o`IshyE$zNk<5)g9SXhimei0eFi;Y;)u)?cP4Aa% zF@JjH)=k<#x`AV>Cr%O%ETT4Sw0C%XQ9!~Jp3%DwJiB+&vGyluoO6#}tt`wCt`#_> ztEDf)IZ~pKEel~K`at??rrIC`h9-oz{@P{m(xP$)yW;NQ^` zng0Yt{C$K*$`(nWLSID}i(p}42LRG1{lYlgzeE%9+&VpeP#-_`C)aPepcE2BS7ZI* zG0JrsFXSdtEvR9bI)vtaY|dMaX{EJ@X+zPC;Zvw{GE?pd{T~_U=FD_Q@I|>2 zrqr3kx1#qnO-(S=95Ut$951ngZ21$fqQF7hV;>0ik&_MgWCfgC7Jt~u-};Cfq;;t_ zNUx$jzfrj zSUrRq-=+(vJ$T2Dh{ln3WkITjmFtIjo5SdYs1$`s6baQgX#(|UbH)6>lq#mJ#n=;H z?C(p)x=Yet?1NiNV`g*~r2Z*>f;6A;} zKFc4t>*RgGxQ?f#(3W9B@p}epqT>KBpUqgYE!ykE<$WoC>JGtH=NB(uU3Mg3FW-k%Sz$hdg=xS0c7=WI-A&Z5hpifFFS!X^Ec8hMKJSGC%y##d#+E3M z@yRH8n8r%5z@fxTHO)rMLwo)i#rFLfG&)jidI6*-Ky^0YKn1Zzy7DyYYf~XblhEtC zCQDYn-Hw*ucuxQ)-(h&|m^wl;S><&klMg4B;sZ`X9Fpm~ zsf!1UpOp=JzBRkP;2(POnU|if<1Y`C48hE~v7bW`Ujd>bS^zizq+G;;|JTEITv~WW zi8U2qVNv55|5lN2ZJx8=S#e?iI+hwjZ>| z9s4T&^+eH*#*M}V|1f$-G zXJG#xJd_t+mFIoXT_No`61e~4v+(U`4 z>SomeFJ?Og+>h)of+rgQ!FCaU0Wwuypi|AU3pFzX(vs(M_@&_+X$DYbK*e8HM?F$b znz~m?@?K8E$e(|N7I+vsFoIN z$M?+btqz$c8df;Z={X}AN${{r$eom7*VxiBtNUfbOpy%4aVoIs?hHcc?I;GYQdbN{eBEzpb zlZVZML~bs*ZKPvutN*3V{+mrN)2m9hE@v-W&lhNH1)qq#AxXgb2;1|~TxJI3cUk=- zBLDY}@NfGfr(3=?zu=QS%ivO$-a>uDRj+fwK3UorFX=eR5s~z8t8%!rXB58; z+nx3`&HEMGhHvG_emuo-#}BCiQor8zAZ2Rg?YXcZ)tF@L7}uL|?4q!7g~#T?w)~>n@H?Li=Q>!)3H;ns9seH3+Y>g3d=tL7AxdjhLwZc_VuyM6& z7Tw1E6y;m>GlWA|6FL9TmC&3?Zj*HzeX87l`vkzg)V-I5=v%f-S=!%LB~jnkU1sC2 zP!50a@!OD?y3C;T{1Bo(Q}tqN2I5H{eH$zkjEhVqnTvTTB|XdLR#Ig;J2aQFqaR7^ zak}3695X4aD0CXU4Rg=1Cwl@6QlG^e_7=Zep1pZtI8w_Nlou0N7y&E-T^67Q#C6dd z@A)&?bs9qx3to{1bbg!RmDMuqg7(=dD}9U{Sx0NZ>GFqyj)Kk z)uQ~k`vh2AXrZP6d46nzW#^adty9%4ZZ6uHhAmtfvqNhW{52SLs6uv--31P3Iyrm& zDMR|!No%Jo5tz71M`DUymEp2-jwq{e|Q&1nkhza3+FXOGp7l2fIG>6Fxc?2@{eR$>B%2S0 z0axi;TwYD7_GtPfAH@^AlBHcOfFvl^*Ks|R%`@v8kZUbQdDgk{&2QQVKLCx1RG7zTe4fU$Vy8P;(8QlZwWVO-cx(*9ML zPsH)OnG3$;YLD3;!O=2(ghpFi?7|9cCQI=6!i}1cQkzYc^{9 z%kr$z?bZFOG()JzZ|iW@Ib8poO1Jsn0eJWJ)WN<1d_NLyPQ@b0q=*I1-=BurnS}xp z<&a@Pqq*phuYVO#F--AsVtp|triX*qpEHrTk~iV!azl8yTcUzU*;(3OeBV68SkCbY z#~ow4+@YSpQmN&p0oi>_|iOB=G|E9`klUCT`;on-xQ$zT3V z=@-3K`?dwr<)YhaI!X-{vla|DX)L==$Y$|^MX0fa6QHaIeN#9%F>`p@YYN1xg zut!Fi=T-heYV%72FC+ViF!$zGHxSk82`_fRpNZR`2x zL$hqv)O^YfNix|SX&Yh#=KDjDaPBne*F{(66_tqRnx!t zy9&wwIn%=et}fTxN4Hrt3vF)&&xq!WcesZBG^(Q88Yc|tyYqpA2Lhl&X_TG+(>L=U z5nB}0#P{;1W(k_pVHhbvYUyxpmhu@{tQ+MKv28oIz ztwmfq?&?x;oE^tSHDG4ZsmHl#RFAFrTV=YrU(h_Sq|L>*XQq0c-DhhH2^CGpiju8< zVipHFOlzixtCn3nnk|$|0B``3kzwUN@w1J0*N=Mv(po!lLtptZ&ztrH_?=oY1^#s+ z^qer<#@VPOr=rFaG_Zf}H=a4ZWM_nM*gFurv|arzanONH7Q<8Z7kLf!mFqj=6jJcX zl+cnQX|+ayG20140#zyoGw!%y%Z0;{zOU`B$&in`KhBsw0aA?W-wB(x?8iB_PlG<6 z_tzhgEk?N=8@>KCS9$Ef@ixBPp`@xzC;QuSPsmhWF4ky+>83b=wFc-j>7x7shySQo zQPB>Vh$gv3`MZee4kg<0FlHGjRTCEaFciKiuSG6rFzi#6khUc{Lw(xavgt2V-nm{1 zlksA|80Fxt2A10;?ja@}fHuo4ljCX~ii=Aquab(E_HNyT{4?w+D;v;jU&T5B9*gI) z<+rDR_-F5~);V$4tsFn62vsFGP1)ebB(Z(T{GhYlbVMb8JWNt$IZXDLRRKR#oAFgc z&G*aSQ}4OD^$RVHUmcrH9Fn07b3%pWOf-wo-kpN8d3+pb^!3f+!5LSK;#4GBGQ~by zxG4AUVN%xK*gM6X5h+N;;{;w2LZuoV7XTvqJA_Q6_@3rF@dJj8fpqpVBgW+7)%+z{ z?+l9|^YssQ+|I#Wo${iG3xGjas#*G4vm$jW--^~qNOtS-aHIitTE0?n%69u=mu3rG$7h&F-8H5Ig17%$at8E$p{LX*l?sB%mU@q^OOJ zlZ1PZxHCtSQGB2jZA|Kn-;}d00AXZRInwPb(jnWQ7aKr$$`e2Z)3Ja*vN+3o=5a;Y zC;r$fx_!b4)R#i@g(4&q!;lB!H&L7iZ#&m){#0(mV^Ebv*gF!06*?Dl*1l4DvD;dP zG}XmmTMr885vr;-*;FE+8;v&!oaoi;#AU-R^oomUJR}bYBTgrWJF2H|>!GyH$)wci zdu_*M*3vO~9UzQuyH{Ng>Y)}^-czSar%>3~7r&!o?|FRWic!Vy9p~W5)E0#tt3$Vh zt^9rL=r)gy)#0^e*4iG4)!_`? zN)}!ilu7Y9Y$g|i7Bq36ebgm9vhiSHIiDatijFT2Yo62lm0tV~`H3Z|@!${#?g3OJ z7Hm&Gh%w&h#l~)m?x==X^zFK{tN~R!E0qk;IHN(yknYC|(Qvvh(Z1zR&h`YoRN`+m zujKga%q+2l@mE!Q^dlinUw*oB_rAEaCSi#y713rbzL!5++l{Ph;G1Lr0+Yv5m1D$e z<~YoxrFelm=5;vemY$MjUZ&evRA`OzyB+GLAw!9SBO{6IE_GXPF|p5<-O`z zQEbV&^>y?1+LFx4K82m6xk1_-6s2}W#FMXl^TFeMfXpn_^OkQt_SMhd6>sT@%vdU_ z(2#=3sRr=pv@_O0ibiuHitgs(;WU0iD;k~i>Ra*zvL1DVU&1L}eqKlJi3PW*gxp$m z7waFG>eS{a&SuL!_7+ciUWGLy$oW-xp(%3}7vatY+AhO`FU9CLKn^#icf3vb8^7u} z$Pt=^YA2aI>55QHtkcgA#b3G`YVr{^oh^nRV;9slw40>3tfc+%xX%yv3pf2J#D=dkoY(8d3w$`4l~HrPT4ME6y=daGyK zR|len5%aG!q#PgJR8d_5Fa{R=+4j_Q-*u71AKq4;5;bY{BafFr zK4TbA>ddeEl-+G#`{O*00D}LvAoIvUXT^<3n?|dpqN60 zmk*fA;{Ez1dG%m(&1!8?8FSm71CgAoy~VN3Ziibn-`cJl*|mFI&EL_H6gWe&vHe$}VcOb#-^M2RwC(W*EJpsVJ zw7|&YPbsgL`?c#F`G+29&wC!T_k60op5f%aS@yF$rH&m zC82QVMVNtyY+)Csq|fg26AM)?t`y8do1?d}S^WO|a3PfS5Fbx(-!y(Hzm>&(V4Ee_ zaM(`X%2vhxBUm-D2)!Th7K>~5=CYa*#+MQc33y?1WyDw0-7!=ktaZ}7~1?rH^~Ml!>GH~ zw!B0n#Id-?G`7oRWkn^%y=u)=gxlm44q{fDx?zX1mrcHo59p6;5I@^%>RUO8Yl zPHY=-JU6(Ap|zhoPB})u#i`SwBf*INo4^V*OJqMeXlYSARZ2xwZaFHjEi**XNb_uc zX5&3PYfA~UKXGIkrLn<9gi$Mj{X`y6mMA|;em>#C<*i*dZGv%bNM{)?#(${gQa5bB zg~@yh9qqfR&8iUVXeYZU+xFEy+m(P>)Ke8!54(CyOVEIE8@Oe1-+b=jz=39a4I@PX z4!y4ns=3SR=cnJrQ6}1@UISq{CD#W z4V-?qf<1r$GEWm1E>sm7*LZmoVcYR?A69vXY6dXLEA<(9x=)%u+u8Hy-7zB6l}km1 zTYk7QiUByQ1_d+LFNAmGre4%_*fxZY6D_r~X3GGn8X=cmu);a-iCViWZ;B7}vvv$5 zUJ-)&k>LlCQ-08-5W@^+nr);HI7mI7j~sJHZigeMBCH%yy-sX-Sq3zlWx*0!NHO@m z$A+Adivv5%0g#ue^0K=>AE)F=Jcju3!8ap(gNH)WPk?@VE$Dy|VY6)(2BhPshFsjE zuJ0_fzhrJ_x-qO~owdQxYeXGaIXO?75s0*XuS5Ok z27-Hc?X1^klwY~ml(cp)G0%(XW1{&vW${OhgWw3GR7iFY#(}euF3jQl=6C+A`X9`q=Ek=7Nh2+oF-<>Ch7BlUZn5x}ORnBqw}vDgrSHObATK-Q{NYL$o6=vXD0ClUEDZD%KUfXd>S#Tw}8m z#%i}y_EQa|QKSx1z8zRrE=WJAuHL^jpC4y=Wp!@IJ~+h1Utk_}F{FYd>Lqe3-g_88 zJe;TWHkQNOGb{O+wxu_lzIWmZ-~!tG^Jao4s2p-A9Ba6_aIf^;`YJuf>>)w+l(8uW z8s_q*BXie^WdG2R{jV4BIi~&J^p|Mmc)KP0pDm7TyFlbqOZ5|I%q>>mCpzy4k8Gk?1a98T^++xA1 zAK7(Zv+`Z|`X&va0{!TAjB+tactDo?HKIu`Q(=++IJ2_v)BEU^9cA)0$z8@~>p(SW z*L4mU=M`syY4OT)zksdhlD;CJo#o#=7y$s(Jh1VrOB$Tz_>fm=Y;Jcn2YqHB|ILM2 z`_e*^^1ZHaV~1BR+mFb{XWq;fSc!)MKW&umB=w1r2))e-C|wP(vQ7Q<*7J*L@iVl6 zfz#iu@zYIQ;ji{a3Bn)n!#+IF_XSegtO`CK#&bKzt-CYvyi1KW+oI>E9CfB0O+U|3 zaCRMa{J9=R8Ac`-ar5lw(_eXm?_I=GZ4D;D9hAT*cG?uupJCNzzT@QZ77+E+ZRrV1 zPEf}u=Mp0&$mz?zrf1(s-5LGekY@kcH)a=jJW5a||7#*%^vrbrXJ$`oCQ#vIn0?EU zeCZ z#JjFonZ@m^d(`})&+)!(7RpJhxoP>b^`gVH3W$7!L3xM{?&-F6{P?QUuWQQqA;LiR zsxsR$sl{pt!22{_@Ek&Cz{) zrJ!}*k%Fy1@RR0PS;C6IWXo_Njz{Y27^kTe(k+hphGx&%-;ReG4fF1P!g8@@bEhT^ zS^`q6p`%xmdMd}2Ja+;%>?QiqbTh6j5f5Tl&Wll-Y;0~nWe2HP=I*6Q+R01<6DHo$ zJKKqb?oS7dR>Wa1vs!hL2LD0kvJt9i7L&p%>WLvRfq^eN^QLOJwmaA6tIw78_Y(HV z9OHPgRX!?W3Kx6PGpOAcq0=EGKDW0yu@>H9KpET?MBJ@SErRSW2&^qwxVl`c@PX4V z0SZS4Q2%10SD7@>k@U89rH%VG-B1E8kH$(}tMAjNYYC1V(7JFW!Q=@79~_~D@YnhO zINSfo=~iJvvvU|W`d8Z9-;H|~DiYpv2<6jZ)!e=|H9S^dbi0^u&|l-%h&W~64$7!P zDm8d)n4&T~3mNjqn{|ue^|WsAQ}$I6zlt_lliQ@`QjoyHC7IwBLR#p2=Vz%Dd^Itq zIHGlM=ed->k&>aAhLhpE`IGY)Gt7K0Y}e3kCjg{E>7gpjv;s8wq&kMDBF$Er?I44GWkOWWti!g!Qg>95s|3#QkKNBW3 zLg0{xb&aVDN=udJ$|=WE>$j}V)=upS!v|>pdV(;NTZpgE*_AQDp;lXESi5t+!Jxx} zONW{R_d9t8$yJPO6_LxTgM{QKd$rd|C@S-e>;u@hEWgVVt`!rQsw6z z3!)CNyBvPeyT>_UwbH7nN^Z4@5^K*kt_cZ0y!yjBZY?DL(#*^q*djKZU?gh^?If3g z$3dIB^)tq!M~{y;8=3>h{@ke5aa|lZk5-j$o&=RxH{DK@mhA86$66d7b6H0OK$o~A zMmA9ew@pluf~Hidf}}sbT+33c{Fz>v_JynU+>85#q*B@l$*zZAtyU-vQTjxAOu{(@ zhfn&?`O61RnU8)lSInM23A@B#8?=3hsB)8~P(V7Q!*xsFCnu7M!gcp-m9*bTwO9WI!3buU?$ErEv}v97N=$9MNdbgI9JLD(P_xj4rK zz^S(ob(ml3!R?e@NHJ_j@2;nP1(f7}r$Guu(HBWn^7ahwz%7C+2yQpMB~A}r$Nu>+ zdzx-~q9S=DPBD)#tM+%5(S$!hhrLsvqUG1Q-zxZ`>2`EB2K)Q^YcDlcwN<3K1SS#T zeNeUbjQ%dBAUhF7GjT8C_id6hI-QaS68rb><_>cO?f3MU=5~+U& zqZdOYO9?OU709w|bFM+T9qpp}kxfGfP%msSRBEy5*b7eLe7G z7>=`6A9a9H`Y9P1oITfwA18D5>$oyX^VN;1#j&T~vsr0B7r-T8hKa{j_=>D9S;HRM z_Pry?W6S(nse|~aDy{7yxRm?eS&3d+Z9l5*LEnTun=qP$u$nI~t8VNey36jd$W@5- zq2v*i2%=6b+0EZ|ZR7i~@9hqe$AwIi`>UlAE?*V)>tC{vOokCPys)miKD>Sm$Awa( z+Ips6uBOvZ4}Yq7CGD%TS=1+HBD{^W<|28RJ`KwWzht)Kl^5Z$OHwKj{Ilf(9MiTE ziN_H*HEaQv?kiZ|@s)IStGOJ_`8MxY`|%1s0g(29lG6*M8xx&b9fzfHjPm3uyDgN! z-SsvM=5l#m^?1hMc9exSWKyW7s(yhO(R;AC@^Py)}FgL&i> zfP$|!RO8gaGFo7+Fd}I-Z-nII$%`H1FIdF=sY6ncM7NGSq8Tx}XJyL_4_%d8oyLQy zFIcR-&17cQrLL6)6Ndj##T{rn+D|cyj8$u8zK+9SHxgF0^1F3n*imckmAc-E3jgS%M?3m#(ERz6H2jr zi?7AU8J4b9=;!R`?p4A!ce=xt?es%rn+4Vf?$6XTQo^_6V}X5LBwny8=*gWgb1gK9Jt2*0jh+U(V8v0PA;GJ3h7{kF_5u?ESmH zFIs8o;(sD z$HWJJL+t~Oeh(FYEzCcAMY3U@-CuDW9h3;9pu%Nvoq7ZUqYi9?;o+O@<>f6MY7oSx zF2>rMuVA7};eiLREFdRO6m9+tH@3p})8{)nA5rDGqmG)?NcL4HkVx{R6r6&J*~A@b zy<=Q|`qZENKm#7$*YwjlS9#r{wBQ+%VC%H};zmNLT_oCdT1+PK8bL~GzQTQt8(UGK zML$FFudv9)sMw&`8eRzers}k0m$bsYzG8@ArNRHpFz1^!4iuLzz-Oy1Q>(HRmdw|Ez z(E}CUp1P=nfrOzTO$m(W4pbq4=(6!KGMQDuRTpt-$m zXe5{?9=(S>(4$nu40^MWm0e7^p6_Q?V<2<&At+mJtRN`WiFu6#C;Yi`p;Oudo@7vS zwjS+VZd1qWk)%_d|6xkLCWK-W@IE>iBzWI@t9ASM@xT)a<6Lfj2c}e2Y+Eft=IeChx?hCi z_H{d}_YX$4tbi!1N7QSCEoy>$>MeWE;pRX4MCX3#!g8GX_TB9%AVn707FatDob+_x zU^24eUZwnAYPNCK)H#3ca8b$H8tX99MbiTk^Ig zm?a5m$EP$$VsSD=eGGFP)81p}eO-H|EJ3!J4f~hSwvyj9-Z>?ur@V#=yPAz~kHr4+ zNpsVP#bYDG&W4GjKMG@LmS$QQ<-f3w4_H@yB{z++;NXk3LvOyu`El9bq{^D#oWXK5 z+a98_HWRIIZ3w#C|Df)zZG9x?7a)?xDL8RFsl#P`Z&; z>6B&wX_z5L7{>P=e8RQ&de>U--uv5oe}C{JX67Eaxvn#g^Ei&n%Wa0Q%c4rrBHD`i zc?R_|A$9T-DQZGFj1i57SPV=`lkOiNbgSUKio$We=1>n;V0M?2U}$Mwsb0zRa(O*2 zvohZ%fOhhr=Av2Q^ZdO09(%pKb1FwtJQ@vmunV4#y%M=jAWO`FpX4$H)(ea99i!=r z3Bw+;S0e?mhLVk!jDZp@@oY;w;oz`YCAiWBz+^N3+~T|ATeYn0c<-sSI%w;y@5%CV z5ZY&bn?(+2v;b|mh=o`gY+9v^Ty zsP7n#s{4A$ev6-y&Cm>0TV#!?W=xhg@2nUbU(su6iFTxbC;tF-j~e^{71w5+Io<2! z=_lW3oMv3&Z_e?G=TPd^p9*rdB_{Kcj@uhp&kGwN>>9@oi5EsMM%!q|IZmF9h}nQ< z7BlBPHSqP?cQo^k4b!YiZsNVi-o575AQZcushV^G0a+*p_ezCR;HD>l!nohU}p`9mc?GIoF{}(RWAz%!)jXGs-Olso(1xEKKiq?q=#y z^REmOI$7Sr9KRI17JOZp;g9QSanXMt`XK3W@3_y-F<)eu&5PL=RLaCParZyVR!8?e36#N!uj{u_WkT9{o;A4xPcC+zv+MEqsc z8V~bMT+9+E!>qsyF*olTlv1M|$j$GxbZ(vG=lit)M5D z2I*(pIVGD-7S&Hr^)td+7e3U#dYX!cyR>+Iagu|!dS3T#c$I)0-qktCUU!;)uRa~7 zV71=#DYn3c{5~rSH9GIeQUA=Wt*fE*s`C9Ejj3Hfad(@>hSY*&^BVrn-;Pzgaa}uy zy!emH0k1hwK2d9&HTcc$CZ1NI~+BrFvJ)UifQyL?vkZk(OIv9U4w(*jHL zeajcJf{L1;<^+vEp>&V`o-4+yR%FJ2k|6Jmbel77W zMjB?I({<`KoO9tCamLS0D!a`O>TL#`BZ<9B0-$yTujqWfG(hRX9PI7wpO3K9E)KrV zQDM6F(78D%b^}9r$azo;Fvx?D7TcHj5k?q}<)*RTxnTZseeFOsg<<*a+oYY8w-!bE zHfJ7`67?|k^WiV)dpQv*!G;M8-JePbs_hOC2{Oj{Mb;t#x%mqDi~5h5L!;LD$UoZC zfG`TUdqs3^KqMpENXGYT6K=v^K5>s9{}fCmedC3(Y(IrZkt!K>;EiMYQ_x_0M4NyL zWm`3W9vZt{Mcc5Wz!M9jMs_*76WYG1rtRebT&pt?kE9ag1?#>1g36-L-i}W{*Osr) zUsG@Y=p64Wm-wUhrt?POkS|}n*t_4R^nus)YyQbd4V7qI7R6B+uN=sD>0P?N zXFN{f&OT;^ZOPk4%EV~hUf8`U+dArS*Ph!q35dQDEIuCPOms`*9Rc#5zZ{LI&$^%g zax<7j|1mpZZTyF;K@Z$3s|Yh*F=Zlvp$H)f%kRzg1X!&aH~`4gjRJX4iL-C!=LN`V zdj1*j67U$LwS6f;J2G}Y!YJ>sxBPt~DdM%}F=IyFw6vi~FV}bCJ3l~GaaqV0%zTVB zfOHiX6%_yPA0^v9VFjsX;-|S{9#eIj#tKYAIN0Bp-C2U9ZUF6W`s1*k(_ELd(~)~u zX$9$np9f`&80WjVN*dqVG3MYt*o4+ih9OukA}T^ZKqDFjB0oSimx3xSu+to@ddN-B zI_PC{6yE};bcisW2gLcjBonlDaSoyhq*DY;T^|;8P=i=|FcyQs_y55!`ty&-FPk$l z(tB0&8D=ISb3^|&YhRAK+!4uu@=ALop}YqidA%=tlmS@=&hXUKkaCiQ#`?+p0KJQ% zL*4-H3#AL(970$>2qTn45XvC=7u6njtecG>OrtT|c)~Td-9qUGw%y14)Z35v=IAcM z5|F}1G{k7Z>7J24Kr!6{gMh4RMDjFWF^%#7X6v!{1LOew#b0+UqB*hTX51^!@qkiv z8K9+F%FUd#pX2`VonHHGgpy#`v4L-l7J>Nsnl|@F$;;s{Xyi;FdF%xJ4Zh)9wr#ZV zDDxG21LJxaHD$6WmaaBi%w4VFq2k{0Ik8Lb&lvR=oDJ7IW=W(Lk>}MaM}6&opE)$=T@x71d0Qz>B$x z4-9CI-@@jl_pwc#rvd@)9YKr)`^!!wPUA$`DOImq@RC%+J;Va@VfwqvjU}nj{$Y9&2+c_d!D~a6yqst9! zsvjVIYqZVuCl$FWqj#np%o4OF>{CNc+&(k(QYy!6id^8#RNU;D7IB98$Cq#^y!=Rd zCirq{^y98yl-d0UGdG*pG4BcYs@SypuD&s=fNMM%Pj$eKRIA`|p%n6azddup0yu_Z zRK9Ce!SX6N>k&yS6eDHB53^@8m@^X1;(Bz*CEH~^upogX(o%rnKKhS=)IP2WR@Ld?uKCRFEUyJ+4ku!Z7lNztfi#J?^y zOEtHRwo7Ho#v2W34lDmi3&X>=W%-#ug%5x5Chj*o5+&p-c`CHeWqFR5Ngn& z+`Mhd*A1DUmY!UHxGW%HCyu4KkbapA=;bq=ynP^ zwRg~atTEn9UvyhGJ$PyMoR{2%t72n)%aX`kAMubW=Um5A8N3A+0vuDTNvCtTx$}1<5t2MX&wq5@Xb__4GfAKv* z#N6jl1g|S8slV3>2uv?i9G;Zp zC9((+Ep5o37!!x-mJ$y2?T6Ff3OpIu1I&j=zTNgS^nW<@i2&cr55^6}xUK_1@*Otbj|9hGs3?t9Ok>y)QJ+g@fm|IS+~SU93h|O3&Jg`r`Qu-KL^th5XDO|xoBqQ)~jg-(0NVy z%O0BGd6nETgV^4Qh=snCmt4>DkC$U2C|VUV_2m0UE#GPzN8#%gCc2Z`?|*>CUiF<+ z^cHWQ+gFrZa5$>AJhdwL_||W!C<*I5tbWR$LKqiL03?|aXBBv=74r(1Kvhj|_q@V9+>Mg}_e zH5Um}Svf}Gl6GwVtm~WHZLf=G`*PsLOoveFEjzw8WLVW+jTfuYJqS|GHqqiz$NL^v0jwC;zvvPKVB9*#0>e8S;IC?5ukKz-g$kC60x z<*rnQBb3YU78V;Qatf3vugj}BkjUSEk9HQ=aV&=KMWQf6Ko|2-FaQUt6W-!tk!cWP zJ9AJ`9$i6t&k3K3>b<6H9(M=3kE`)zwr!JTq@D79jK@ol&RJfDVhpEkVGMDf<5Hb8 z?fNwJuSU|uQy*l_yP{(U8U0_L$mLa@Wdiak-0h zM?qSuB7n7_#*+@eLC6gME610*F#OlzX{n{Fs5f zP2h?r{+2z)*uiW!ZErRVCEfb|v?)yhO98Z5q6mw{g*t~ApA>!7-xhG0HJR&kcYH9% zq+ayg?3k}kz+;NkSzou4q_u{vmLck43EB+WlV$Jyu$6MKDvThCpT<`?;zNJbd*j`4F~ch^^UxffZ#_m7?7+eX*NJe(+vjg1?c z8FpS`X#Jw5xa=L#<(pw9rsr*MzmlQyaAZ-KIg{$!7iUA#A^RaLtwttv9kE!?<8#(* z0wzF6NYph9OW&W~wV1?zksc~LWf_{6>8x$4)qF;Czs#6Og~(55x&};SVrb(d`!@XB z?4tFXGe;-lx3^r-mjikG$SWVEbd9%nlefs7Mt0xGuge@+-e-S~PbJRXV`H$TEdY?3 z3h_$H_aN_79t>@0VX}%hU}bc`mavR%05EGL#?~ivHgzi3wa_O0*%7Y{;X6_^;?u{o zp6ITbt+s&?-A&P(v)3kyd8}qhYnW1BAjXHrS_&O6inxb8&MI?`m(VwTz%dm7U73(Z zakH9pI5oDai^RD5Ofn6v+*TPw{zJ6^n?27chqlIp(1*=3DH$`22bS$NoS|O(QDwFs zlB9gfmc5?frwK+MQU>ZQ*l6CTTr|Xc4SY;l;uz-NcUMv!<1&3Zy6b2fzoYMUBe1_YRK|+pnba2_>SQcos@5IN(c?i2<`|vva;{aG zRHawiQiT&(*d$B>q-uH`F9Z^qvyDm}s##;X3P!jS>{K%Xq1TU_9m#AnX#h=Va0TZ+ zU+aB})d_d-z0_w%?bEnb+Z~D67lux}>I%y@8~g|$ROAS5Mw=#!66Ts$bHUT3J>i5b z>#smJ=zY$ZqR(~=L~U6g2{_5wQy#~&ek?*@lkk&aY|L@o)E@V(wLslIrg|a(ml$ z+^S&aIu=_RJZ5TI;bCwMujwjSNKDn_t1* zcZcCLxObmTooJ66YoVrI3o}z{o2?XJD2g+x1a~RdDcKsheWiA;0MS8wlD%0{v^NW# z{$0pim!OB=UFu159>gu^(yx|yo{I1jdm;=<8c_F%Uyy6pc?@z|BJgvR$o1w5Z_z^a zd;MmslJ|}10oqT}sW2+>#;!J2Xg~;p?OXILiAO$7Q4S^@u{-9jK%D!pT1Jm;@l8Jo zSSvsbUbcQ`xfY^9O*9QlonNl(K`ctoo^v@n=bHm{k( zC416!V)+K#@$lu6$v3R1`@`^;(KdZ=bs!~bdjrNOcdU)kNLAaux+`?EU}Jx#<3&DW zJ*S+7b7V_Kw9#x$9dXXZWIF)zILkGReIhFfNS0F2oZ4gUiOM~<&lHulH^vrcF}av3 z00!9+d<-<iue)dX+~BAoCs!!gLZx@>4UNFhJQbw#(jg*lY~%(r?T_2l=&BsSalLgk!I68Gwn}?$Qx#Gb)U7?rNWy zS#NlM;2gszBzYvv!|TCxjXJYtUh4SMhMyKB42mqy)}vCX0oxhJD6gD;H}u~%&vfpi z)=Bfqf{?}X(>(0!ntep{)mFAwn3KLHNN?5?t?q+_UyatC1i!b0*o>CFYTE*f^l%f~ zN+agU!v)FNyRo2h*4xJ&7{z_kS&G^iQ^WN(`oUBCH*35(3Zvb%pWPM2#lQ&8i(iJy z*}P$Cr6>J6cORfQ|Le9TjgpbHH$r;qoRuBfbZrIX{Nw)I)?m)urLuQ{LM9PN!N!S7 zW?=lWVn9HohpRxb;_w3eS@(iEUY<^^@5wgmBG-Y7sHr$|S51}uT1{ttE;`GBUi6Vs zrtY>;!Zc-6VB%MMdQT2f^Q4b48GFJxk(_2hKvsU0i}9K!X7UpdM)BPYLxMiNZxJ1Y zB^2sY2CtsBCQG(dkx?bk1xo7QqHga6M=p|0is6-5&B}hDnLI9F{z@pUPO4=dF;@c> zrQB;HfcwE+J1C#m6vw=YL{17bW*oYP?33Mu1L&WUs7mCAuH_|+7+d?Bzp039Bgy+- zJiGo#Er-rGCE0b@c>cr~4Tc@_tmXZP`w!4fL;cHS^p_%0Dcr)U=M_-m|#NP*K$0;e02 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 Date: Sat, 14 Jun 2025 16:48:12 -0400 Subject: [PATCH 2/6] omg need to fix other stuff --- .vscode/launch.json | 123 +++++++++++---------- Sentry/src/robot.c | 4 +- control-base/devices/inc/supercap.h | 30 ++++-- control-base/devices/src/supercap.c | 160 +++++++++++++++++++++++++--- 4 files changed, 233 insertions(+), 84 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 802498d..1eea0c5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,58 +1,73 @@ { - "version": "0.2.0", - "configurations": [ + "version": "0.2.0", + "configurations": [ + { + "name": "CMSIS-DAP", + "cwd": "${workspaceRoot}", + "executable": "${workspaceRoot}${/}build${/}${input:robotProject}${/}${input:robotProject}.elf", + "request": "launch", + "type": "cortex-debug", + "svdFile": "STM32F407.svd", + "servertype": "openocd", + "serverpath": "/usr/bin/openocd", + "configFiles": [ + "${workspaceRoot}${/}config${/}openocd_cmsis_dap.cfg" + ], + "rtos": "FreeRTOS", + "liveWatch": { + "enabled": true, + "samplesPerSecond": 4 + }, + "preLaunchTask": "Build" + }, + { + "name": "ST-LINK", + "cwd": "${workspaceRoot}", + "executable": "${workspaceRoot}${/}build${/}${input:robotProject}${/}${input:robotProject}.elf", + "request": "launch", + "type": "cortex-debug", + "svdFile": "STM32F407.svd", + "servertype": "openocd", + "serverpath": "/usr/bin/openocd", + "configFiles": [ + "${workspaceRoot}${/}config${/}openocd_stlink.cfg" + ], + "rtos": "FreeRTOS", + "liveWatch": { + "enabled": true, + "samplesPerSecond": 8 + }, + "preLaunchTask": "Build" + }, + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": false, + "cwd": "/home/polarbearbo/RoboMaster/Embedded-Control/control-base/devices/src", + "program": "/home/polarbearbo/RoboMaster/Embedded-Control/control-base/devices/src/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ { - "name": "CMSIS-DAP", - "cwd": "${workspaceRoot}", - "executable": "${workspaceRoot}${/}build${/}${input:robotProject}${/}${input:robotProject}.elf", - "request": "launch", - "type": "cortex-debug", - "svdFile": "STM32F407.svd", - "servertype": "openocd", //GDB server - "configFiles": [ - "${workspaceRoot}${/}config${/}openocd_cmsis_dap.cfg" // config - ], - //"runToEntryPoint": "main", // stop at main - //"showDevDebugOutput": "raw", // enable debug output - "rtos": "FreeRTOS", - "liveWatch": { - "enabled": true, - "samplesPerSecond": 4 - }, - "preLaunchTask": "Build" // build before debug - }, - { - "name": "ST-LINK", - "cwd": "${workspaceRoot}", - "executable": "${workspaceRoot}${/}build${/}${input:robotProject}${/}${input:robotProject}.elf", - "request": "launch", - "type": "cortex-debug", - "svdFile": "STM32F407.svd", - "servertype": "openocd", //GDB server - "configFiles": [ - "${workspaceRoot}${/}config${/}openocd_stlink.cfg" // config - ], - //"runToEntryPoint": "main", // stop at main - //"showDevDebugOutput": "raw", // enable debug output - "rtos": "FreeRTOS", - "liveWatch": { - "enabled": true, - "samplesPerSecond": 8 - }, - "preLaunchTask": "Build" // build before debug - } - ], - "inputs": [ - { - "id": "robotProject", - "type": "pickString", - "description": "Select the robot project to debug", - "options": [ - "Swerve-Standard", - "Sentry", - //"Template" - // Add your other robot projects here - ] + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true } - ] + ] + } + ], + "inputs": [ + { + "id": "robotProject", + "type": "pickString", + "description": "Select the robot project to debug", + "options": [ + "Swerve-Standard", + "Sentry" + ] + } + ] } \ No newline at end of file diff --git a/Sentry/src/robot.c b/Sentry/src/robot.c index 9a412e6..d3daa5c 100644 --- a/Sentry/src/robot.c +++ b/Sentry/src/robot.c @@ -49,8 +49,8 @@ void Handle_Starting_Up_State() Launch_Task_Init(); Remote_Init(&huart3); CAN_Service_Init(); - Referee_System_Init(&huart1); - Supercap_Init(&g_supercap); + // Referee_System_Init(&huart1); + Supercap_Init(&huart1); // Set robot state to disabled g_robot_state.state = DISABLED; diff --git a/control-base/devices/inc/supercap.h b/control-base/devices/inc/supercap.h index b0f6398..2bb1eb8 100644 --- a/control-base/devices/inc/supercap.h +++ b/control-base/devices/inc/supercap.h @@ -8,7 +8,8 @@ #include "bsp_uart.h" #define SUPERCAP_POWER (20) -#define SUPERCAP_RX_BUFFER_SIZE (80) //larger than 6*10+2 +//todo ask why it is 128 +#define SUPERCAP_RX_BUFFER_SIZE (1) //number of bytes #define SUPERCAP_TX_BUFFER_SIZE (3) //todo finish this typedef struct { @@ -20,24 +21,31 @@ typedef struct uint8_t supercap_percent; uint8_t supercap_enabled_flag; + float Vi; //input voltage + float Vo; //output voltage + float Pi; //input power + float Ii; //input current + float Ps; //reference power + float Io; //output current + //formate of rx //printf("Vi:%2.2f Vo:%2.2f Pi:%3.2f Ii:%2.2f Io:%2.2f Pa:%3.2f\r\n", VIPMR, VOFWR,POW_IN, IIPWR, IOPWR, pref); uint8_t rx_buffer[SUPERCAP_RX_BUFFER_SIZE]; uint8_t tx_buffer[SUPERCAP_TX_BUFFER_SIZE]; // chnage this to other uint type if possible - struct { - float input_voltage; // Vi - float output_voltage; // Vo - float input_power; //Pi - float input_current; //Ii - float output_currenIi; //Io - float ref_power; //Pa - } supercap_data; + // struct { + // float input_voltage; // Vi + // float output_voltage; // Vo + // float input_power; //Pi + // float input_current; //Ii + // float output_currenIi; //Io + // float ref_power; //Pa + // } supercap_data; } Supercap_t; -void Supercap_Init(UART_HandleTypeDef *huartx); -void Supercap_Decode(UART_Instance_t *supercap_uart_instance_ptr); +void Supercap_Init(UART_HandleTypeDef *huartx); // in robot the input element is g_supercap +void Supercap_Decode(UART_Instance_t *supercap_uart_instance_ptr, float *Vi, float *Vo, float *Pi, float *Ii, float *Io, float *Ps); void Supercap_Send(void); extern Supercap_t g_supercap; diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index 620a1d9..1b162a8 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -1,9 +1,22 @@ #include "supercap.h" +#include "bsp_uart.h" +#include "bsp_daemon.h" +#define SUPERCAP_TIMEOUT_MS (3000) Supercap_t g_supercap; +Daemon_Instance_t *g_supercap_instance_ptr; // CAN_Instance_t *supercap_can_instance; UART_Instance_t *supercap_uart_instance_ptr; extern Jetson_Orin_Data_t g_orin_data; + +char uart_buffer[SUPERCAP_RX_BUFFER_SIZE]; +uint8_t uart_byte; +uint8_t uart_index = 0; +uint8_t supercap_uart_instance_initialized; + +// Parsed values +//float Vi = 0, Vo = 0, Pi = 0, Io = 0, Ps = 0, Ii = 0; + struct rx_data { uint16_t max_discharge; @@ -12,39 +25,110 @@ struct rx_data uint16_t cap_state; } g_supercap_data; + +void Supercap_Timeout_Callback(void){ + UART_Service_Init(supercap_uart_instance_ptr); +} + +void Supercap_Decode_Callback(UART_Instance_t *uart_instance) { + static float Vi, Vo, Pi, Io, Ps, Ii; + Supercap_Decode(uart_instance, &Vi, &Vo, &Pi, &Ii, &Io, &Ps); + + // Save values to your global struct + g_supercap.Vi = Vi; + g_supercap.Vo = Vo; + g_supercap.Pi = Pi; + g_supercap.Ii = Ii; + g_supercap.Io = Io; + g_supercap.Ps = Ps; +} + void Supercap_Init(UART_HandleTypeDef *huartx) { // Initialize supercap // g_supercap->can_bus = 1; // can 2 // g_supercap->tx_id = 0x2C8; // g_supercap->rx_id = 0x2C7; - - //register uart instance - supercap_uart_instance_ptr = UART_Register(huartx, g_supercap.rx_buffer, SUPERCAP_RX_BUFFER_SIZE, Supercap_Decode); + + //supercap_uart_instance_ptr = UART_Register(huartx, g_supercap.rx_buffer, SUPERCAP_RX_BUFFER_SIZE, Supercap_Decode); + supercap_uart_instance_ptr = UART_Register(huartx, g_supercap.rx_buffer, SUPERCAP_RX_BUFFER_SIZE, Supercap_Decode_Callback); // matches expected signature + uint16_t reload_value = SUPERCAP_TIMEOUT_MS / DAEMON_PERIOD; + uint16_t intial_counter = reload_value; + g_supercap_instance_ptr = Daemon_Register(reload_value, intial_counter, Supercap_Timeout_Callback); + supercap_uart_instance_initialized = 1; //turn on supercap uart } -void Supercap_Decode(UART_Instance_t *supercap_uart_instance_ptr) -{ - // // Recieve supercap data +// // Recieve supercap data // uint16_t *supercap_rx = (uint16_t *) can_instance->rx_buffer; + +void Supercap_Decode(UART_Instance_t *uart_instance, float *Vi, float *Vo, float *Pi, float *Ii, float *Io, float *Ps) +{ + // uint8_t uart_byte; + // static char uart_buffer[SUPERCAP_RX_BUFFER_SIZE]; + // static uint16_t uart_index = 0; + // sscanf((char *)uart_instance->rx_buffer, "Vi:%2.2f Vo:%2.2f Pi:%3.2f Ii:%2.2f Io:%2.2f Ps:%3.2f\r\n", + // Vi, Vo, Pi, Ii, Io, Ps); + // while (1) { + // HAL_UART_Receive(uart_instance->uart_handle, &uart_byte, 1, HAL_MAX_DELAY); - // g_supercap_data.max_discharge = supercap_rx[0]; - // g_supercap_data.base_power = supercap_rx[1]; - // g_supercap_data.cap_energy_percent = (int16_t) supercap_rx[2]; - // g_supercap_data.cap_state = supercap_rx[3]; - // // ! do not read more than 8 bytes from the buffer + // if (uart_byte == '\n') { + // uart_buffer[uart_index] = '\0'; // Null-terminate the string -} + // // Copy the buffer to rx_buffer if needed + // strncpy((char *)uart_instance->rx_buffer, uart_buffer, uart_index + 1); -void Supercap_Timeout_Callback(void){ - UART_Service_Init(supercap_uart_instance_ptr); + // // Attempt to parse the expected format + // sscanf((char *)uart_instance->rx_buffer, "Vi:%f Vo:%f Pi:%f Ii:%f Io:%f Ps:%f\r\n", + // Vi, Vo, Pi, Ii, Io, Ps); + + // uart_index = 0; // Reset for next message + // } else if (uart_index < SUPERCAP_RX_BUFFER_SIZE - 1) { + // uart_buffer[uart_index++] = uart_byte; + // } else { + // uart_index = 0; // Overflow protection + // } + // } } +// void parse_uart_data(const char *msg) { +// // Example format: +// // Vi:12.34 Vo:12.34 Pi:56.78 Io:2.34 Ps:50.00 + + +// sscanf(msg, "Vi:%f Vo:%f Pi:%f Io:%f Ps:%f", &Vi, &Vo, &Pi, &Io, &Ps); + + +// // Now you can use the parsed variables as needed +// } + +// void uart_receive_loop() { +// while (1) { +// HAL_UART_Receive(&huart1, &uart_byte, 1, HAL_MAX_DELAY); + + +// if (uart_byte == '\n') { +// uart_buffer[uart_index] = '\0'; // Null-terminate +// parse_uart_data(uart_buffer); +// uart_index = 0; // Reset for next line +// } +// else if (uart_index < UART_BUFFER_SIZE - 1) { +// uart_buffer[uart_index++] = uart_byte; +// } else { +// uart_index = 0; // Overflow protection +// } +// } +// } + + // fomrate PXXXP - sending XXX as power // PVONP - Turn on supercap // PVOFFP - Turn off supercap void Supercap_Send(void) { + if (!supercap_uart_instance_initialized) { + return; + } + // Send supercap data // uint16_t *supercap_tx = (uint16_t *) supercap_can_instance->tx_buffer; // supercap_tx[0] = 0x003C; @@ -52,7 +136,49 @@ void Supercap_Send(void) // supercap_tx[2] = 0x2012; // supercap_tx[3] = 0x0112; // ! do not write more than 8 bytes to the buffer - - // CAN_Transmit(supercap_can_instance); - UART_Transmit(supercap_uart_instance_ptr, g_supercap.tx_buffer,sizeof(g_supercap.tx_buffer), UART_DMA); +// supercap_uart_instance_ptr->rx_buffer_size = 40; // Start with 'P' for power command +// switch(Referee_System.Robot_State.Chassis_Power_Max) { +// case 45: +// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P045P"; +// break; +// case 50: +// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P050P"; +// break; +// case 55: +// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P055P"; +// break; +// // case 60: +// // g_swerve_constants.max_speed = MAX_SPEED_W60; +// // g_spintop_omega = SPINTOP_OMEGA_W60; +// // break; +// // case 65: +// // g_swerve_constants.max_speed = MAX_SPEED_W65; +// // g_spintop_omega = SPINTOP_OMEGA_W65; +// // break; +// // case 70: +// // g_swerve_constants.max_speed = MAX_SPEED_W70; +// // g_spintop_omega = SPINTOP_OMEGA_W70; +// // break; +// // case 75: +// // g_swerve_constants.max_speed = MAX_SPEED_W75; +// // g_spintop_omega = SPINTOP_OMEGA_W75; +// // break; +// // case 80: +// // g_swerve_constants.max_speed = MAX_SPEED_W80; +// // g_spintop_omega = SPINTOP_OMEGA_W80; +// // break; +// // case 90: +// // g_swerve_constants.max_speed = MAX_SPEED_W90; +// // g_spintop_omega = SPINTOP_OMEGA_W90; +// // break; +// // case 100: +// // g_swerve_constants.max_speed = MAX_SPEED_W100; +// // g_spintop_omega = SPINTOP_OMEGA_W100; +// // break; +// // default: +// g_swerve_constants.max_speed = MAX_SPEED_W45; +// g_spintop_omega = SPINTOP_OMEGA_W45; +// } +// // CAN_Transmit(supercap_can_instance); +// UART_Transmit(supercap_uart_instance_ptr, g_supercap.tx_buffer,sizeof(g_supercap.tx_buffer), UART_DMA); } \ No newline at end of file From 8d505f91f3761ef5a2a86dd815c057d348071857 Mon Sep 17 00:00:00 2001 From: Polarbearbo Date: Sat, 14 Jun 2025 17:26:24 -0400 Subject: [PATCH 3/6] error with supercap decode callback --- control-base/devices/inc/supercap.h | 4 ++++ control-base/devices/src/supercap.c | 29 +++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/control-base/devices/inc/supercap.h b/control-base/devices/inc/supercap.h index 2bb1eb8..d5e6f26 100644 --- a/control-base/devices/inc/supercap.h +++ b/control-base/devices/inc/supercap.h @@ -10,6 +10,7 @@ //todo ask why it is 128 #define SUPERCAP_RX_BUFFER_SIZE (1) //number of bytes +#define SUPERCAP_BUFFER_SIZE (64) // new buffer #define SUPERCAP_TX_BUFFER_SIZE (3) //todo finish this typedef struct { @@ -18,6 +19,8 @@ typedef struct uint16_t rx_id; uint8_t send_counter; + uint8_t receive_counter; + uint8_t supercap_percent; uint8_t supercap_enabled_flag; @@ -32,6 +35,7 @@ typedef struct //printf("Vi:%2.2f Vo:%2.2f Pi:%3.2f Ii:%2.2f Io:%2.2f Pa:%3.2f\r\n", VIPMR, VOFWR,POW_IN, IIPWR, IOPWR, pref); uint8_t rx_buffer[SUPERCAP_RX_BUFFER_SIZE]; uint8_t tx_buffer[SUPERCAP_TX_BUFFER_SIZE]; // chnage this to other uint type if possible + uint8_t buffer_for_construction[SUPERCAP_BUFFER_SIZE]; //storing each byte unitl \r\n // struct { // float input_voltage; // Vi // float output_voltage; // Vo diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index 1b162a8..bf372f7 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -4,7 +4,7 @@ #define SUPERCAP_TIMEOUT_MS (3000) Supercap_t g_supercap; -Daemon_Instance_t *g_supercap_instance_ptr; +Daemon_Instance_t *g_supercap_daemon_ptr; // CAN_Instance_t *supercap_can_instance; UART_Instance_t *supercap_uart_instance_ptr; extern Jetson_Orin_Data_t g_orin_data; @@ -31,16 +31,21 @@ void Supercap_Timeout_Callback(void){ } void Supercap_Decode_Callback(UART_Instance_t *uart_instance) { - static float Vi, Vo, Pi, Io, Ps, Ii; - Supercap_Decode(uart_instance, &Vi, &Vo, &Pi, &Ii, &Io, &Ps); - - // Save values to your global struct - g_supercap.Vi = Vi; - g_supercap.Vo = Vo; - g_supercap.Pi = Pi; - g_supercap.Ii = Ii; - g_supercap.Io = Io; - g_supercap.Ps = Ps; + // static float Vi, Vo, Pi, Io, Ps, Ii; + + // uart_instance->rx_buffer[0]; + if (uart_instance->rx_buffer[0] != '\n') { + g_supercap.receive_counter++; // R + g_supercap.buffer_for_construction[g_supercap.receive_counter] = uart_instance->rx_buffer[0]; // store the byte in the buffer + } + else // if the end of frame is reached + { + g_supercap.receive_counter = 0; // reset counter if \n is received + Daemon_Reload(g_supercap_daemon_ptr); + // Supercap decode logic + sscanf((char *)g_supercap.buffer_for_construction, "Vi:%f Vo:%f Pi:%f Ii:%f Io:%f Ps:%f\r\n", + &g_supercap.Vi, &g_supercap.Vo, &g_supercap.Pi, &g_supercap.Ii, &g_supercap.Io, &g_supercap.Ps); + } } void Supercap_Init(UART_HandleTypeDef *huartx) @@ -54,7 +59,7 @@ void Supercap_Init(UART_HandleTypeDef *huartx) supercap_uart_instance_ptr = UART_Register(huartx, g_supercap.rx_buffer, SUPERCAP_RX_BUFFER_SIZE, Supercap_Decode_Callback); // matches expected signature uint16_t reload_value = SUPERCAP_TIMEOUT_MS / DAEMON_PERIOD; uint16_t intial_counter = reload_value; - g_supercap_instance_ptr = Daemon_Register(reload_value, intial_counter, Supercap_Timeout_Callback); + g_supercap_daemon_ptr = Daemon_Register(reload_value, intial_counter, Supercap_Timeout_Callback); supercap_uart_instance_initialized = 1; //turn on supercap uart } From 056e50f2b6e0c55ba59ffbe2029e6247b59461a0 Mon Sep 17 00:00:00 2001 From: Polarbearbo Date: Sat, 14 Jun 2025 18:16:11 -0400 Subject: [PATCH 4/6] done with sending --- control-base/devices/inc/supercap.h | 2 ++ control-base/devices/src/supercap.c | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/control-base/devices/inc/supercap.h b/control-base/devices/inc/supercap.h index d5e6f26..fcebe4b 100644 --- a/control-base/devices/inc/supercap.h +++ b/control-base/devices/inc/supercap.h @@ -20,6 +20,7 @@ typedef struct uint8_t send_counter; uint8_t receive_counter; + uint8_t final_receive_counter; uint8_t supercap_percent; uint8_t supercap_enabled_flag; @@ -36,6 +37,7 @@ typedef struct uint8_t rx_buffer[SUPERCAP_RX_BUFFER_SIZE]; uint8_t tx_buffer[SUPERCAP_TX_BUFFER_SIZE]; // chnage this to other uint type if possible uint8_t buffer_for_construction[SUPERCAP_BUFFER_SIZE]; //storing each byte unitl \r\n + uint8_t final_buffer_for_construction[SUPERCAP_BUFFER_SIZE]; // struct { // float input_voltage; // Vi // float output_voltage; // Vo diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index bf372f7..06fced6 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -1,6 +1,8 @@ #include "supercap.h" #include "bsp_uart.h" #include "bsp_daemon.h" +#include "string.h" +#include "stdlib.h" #define SUPERCAP_TIMEOUT_MS (3000) Supercap_t g_supercap; @@ -8,7 +10,7 @@ Daemon_Instance_t *g_supercap_daemon_ptr; // CAN_Instance_t *supercap_can_instance; UART_Instance_t *supercap_uart_instance_ptr; extern Jetson_Orin_Data_t g_orin_data; - +char* middle_cpy; char uart_buffer[SUPERCAP_RX_BUFFER_SIZE]; uint8_t uart_byte; uint8_t uart_index = 0; @@ -26,6 +28,14 @@ struct rx_data } g_supercap_data; +// Function to extract float after a key like "Vi:" +// float extract_value(const char *src, const char *key) { +// const char *start = strstr(src, key); +// if (!start) return 0.0f; +// start += strlen(key); // move pointer after "Vi:" +// return atof(start); // convert to float +// } + void Supercap_Timeout_Callback(void){ UART_Service_Init(supercap_uart_instance_ptr); } @@ -35,16 +45,25 @@ void Supercap_Decode_Callback(UART_Instance_t *uart_instance) { // uart_instance->rx_buffer[0]; if (uart_instance->rx_buffer[0] != '\n') { - g_supercap.receive_counter++; // R + g_supercap.buffer_for_construction[g_supercap.receive_counter] = uart_instance->rx_buffer[0]; // store the byte in the buffer + g_supercap.receive_counter++; // R } else // if the end of frame is reached { + g_supercap.buffer_for_construction[g_supercap.receive_counter] = '\0'; g_supercap.receive_counter = 0; // reset counter if \n is received Daemon_Reload(g_supercap_daemon_ptr); + // Supercap decode logic - sscanf((char *)g_supercap.buffer_for_construction, "Vi:%f Vo:%f Pi:%f Ii:%f Io:%f Ps:%f\r\n", - &g_supercap.Vi, &g_supercap.Vo, &g_supercap.Pi, &g_supercap.Ii, &g_supercap.Io, &g_supercap.Ps); + // g_supercap.Vi = extract_value((const char*)g_supercap.buffer_for_construction, "Vi:"); + // g_supercap.Vo = extract_value((const char*)g_supercap.buffer_for_construction, "Vo:"); + // g_supercap.Pi = extract_value((const char*)g_supercap.buffer_for_construction, "Pi:"); + // g_supercap.Ii = extract_value((const char*)g_supercap.buffer_for_construction, "Ii:"); + // g_supercap.Io = extract_value((const char*)g_supercap.buffer_for_construction, "Io:"); + // g_supercap.Ps = extract_value((const char*)g_supercap.buffer_for_construction, "Ps:"); + sscanf((char *)g_supercap.buffer_for_construction, "Vi:%f Vo:%f Pi:%f Ii:%f Io:%f Ps:%f", + &g_supercap.Vi, &g_supercap.Vo, &g_supercap.Pi, &g_supercap.Ii, &g_supercap.Io, &g_supercap.Ps); } } From 9ea9cd63131c9d413cbfb526c10166657e6de803 Mon Sep 17 00:00:00 2001 From: Polarbearbo Date: Sat, 14 Jun 2025 18:19:10 -0400 Subject: [PATCH 5/6] clean up --- control-base/devices/src/supercap.c | 106 ---------------------------- 1 file changed, 106 deletions(-) diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index 06fced6..87ba66d 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -82,67 +82,6 @@ void Supercap_Init(UART_HandleTypeDef *huartx) supercap_uart_instance_initialized = 1; //turn on supercap uart } -// // Recieve supercap data - // uint16_t *supercap_rx = (uint16_t *) can_instance->rx_buffer; - -void Supercap_Decode(UART_Instance_t *uart_instance, float *Vi, float *Vo, float *Pi, float *Ii, float *Io, float *Ps) -{ - // uint8_t uart_byte; - // static char uart_buffer[SUPERCAP_RX_BUFFER_SIZE]; - // static uint16_t uart_index = 0; - // sscanf((char *)uart_instance->rx_buffer, "Vi:%2.2f Vo:%2.2f Pi:%3.2f Ii:%2.2f Io:%2.2f Ps:%3.2f\r\n", - // Vi, Vo, Pi, Ii, Io, Ps); - // while (1) { - // HAL_UART_Receive(uart_instance->uart_handle, &uart_byte, 1, HAL_MAX_DELAY); - - // if (uart_byte == '\n') { - // uart_buffer[uart_index] = '\0'; // Null-terminate the string - - // // Copy the buffer to rx_buffer if needed - // strncpy((char *)uart_instance->rx_buffer, uart_buffer, uart_index + 1); - - // // Attempt to parse the expected format - // sscanf((char *)uart_instance->rx_buffer, "Vi:%f Vo:%f Pi:%f Ii:%f Io:%f Ps:%f\r\n", - // Vi, Vo, Pi, Ii, Io, Ps); - - // uart_index = 0; // Reset for next message - // } else if (uart_index < SUPERCAP_RX_BUFFER_SIZE - 1) { - // uart_buffer[uart_index++] = uart_byte; - // } else { - // uart_index = 0; // Overflow protection - // } - // } -} - -// void parse_uart_data(const char *msg) { -// // Example format: -// // Vi:12.34 Vo:12.34 Pi:56.78 Io:2.34 Ps:50.00 - - -// sscanf(msg, "Vi:%f Vo:%f Pi:%f Io:%f Ps:%f", &Vi, &Vo, &Pi, &Io, &Ps); - - -// // Now you can use the parsed variables as needed -// } - -// void uart_receive_loop() { -// while (1) { -// HAL_UART_Receive(&huart1, &uart_byte, 1, HAL_MAX_DELAY); - - -// if (uart_byte == '\n') { -// uart_buffer[uart_index] = '\0'; // Null-terminate -// parse_uart_data(uart_buffer); -// uart_index = 0; // Reset for next line -// } -// else if (uart_index < UART_BUFFER_SIZE - 1) { -// uart_buffer[uart_index++] = uart_byte; -// } else { -// uart_index = 0; // Overflow protection -// } -// } -// } - // fomrate PXXXP - sending XXX as power // PVONP - Turn on supercap @@ -160,49 +99,4 @@ void Supercap_Send(void) // supercap_tx[2] = 0x2012; // supercap_tx[3] = 0x0112; // ! do not write more than 8 bytes to the buffer -// supercap_uart_instance_ptr->rx_buffer_size = 40; // Start with 'P' for power command -// switch(Referee_System.Robot_State.Chassis_Power_Max) { -// case 45: -// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P045P"; -// break; -// case 50: -// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P050P"; -// break; -// case 55: -// supercap_uart_instance_ptr->rx_buffer = (uint8_t *)"P055P"; -// break; -// // case 60: -// // g_swerve_constants.max_speed = MAX_SPEED_W60; -// // g_spintop_omega = SPINTOP_OMEGA_W60; -// // break; -// // case 65: -// // g_swerve_constants.max_speed = MAX_SPEED_W65; -// // g_spintop_omega = SPINTOP_OMEGA_W65; -// // break; -// // case 70: -// // g_swerve_constants.max_speed = MAX_SPEED_W70; -// // g_spintop_omega = SPINTOP_OMEGA_W70; -// // break; -// // case 75: -// // g_swerve_constants.max_speed = MAX_SPEED_W75; -// // g_spintop_omega = SPINTOP_OMEGA_W75; -// // break; -// // case 80: -// // g_swerve_constants.max_speed = MAX_SPEED_W80; -// // g_spintop_omega = SPINTOP_OMEGA_W80; -// // break; -// // case 90: -// // g_swerve_constants.max_speed = MAX_SPEED_W90; -// // g_spintop_omega = SPINTOP_OMEGA_W90; -// // break; -// // case 100: -// // g_swerve_constants.max_speed = MAX_SPEED_W100; -// // g_spintop_omega = SPINTOP_OMEGA_W100; -// // break; -// // default: -// g_swerve_constants.max_speed = MAX_SPEED_W45; -// g_spintop_omega = SPINTOP_OMEGA_W45; -// } -// // CAN_Transmit(supercap_can_instance); -// UART_Transmit(supercap_uart_instance_ptr, g_supercap.tx_buffer,sizeof(g_supercap.tx_buffer), UART_DMA); } \ No newline at end of file From 941e5e0417644f34bdfc73c651f974bac0716766 Mon Sep 17 00:00:00 2001 From: Polarbearbo Date: Sun, 15 Jun 2025 10:49:32 -0400 Subject: [PATCH 6/6] Super cap send function --- Sentry/src/motor_task.c | 4 ++-- control-base/devices/inc/supercap.h | 6 +++--- control-base/devices/src/supercap.c | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Sentry/src/motor_task.c b/Sentry/src/motor_task.c index 83e1a7f..1a1d0ac 100644 --- a/Sentry/src/motor_task.c +++ b/Sentry/src/motor_task.c @@ -7,12 +7,12 @@ extern Supercap_t g_supercap; void Motor_Task_Loop() { - DJI_Motor_Send(); + // DJI_Motor_Send(); // MF_Motor_Send(); // DM_Motor_Send(); g_supercap.send_counter++; - if (g_supercap.send_counter >= 100) { + if (g_supercap.send_counter >= (1000 / SUPERCAP_SEND_FREQ)) { Supercap_Send(); g_supercap.send_counter = 0; } diff --git a/control-base/devices/inc/supercap.h b/control-base/devices/inc/supercap.h index fcebe4b..45281d5 100644 --- a/control-base/devices/inc/supercap.h +++ b/control-base/devices/inc/supercap.h @@ -6,8 +6,8 @@ #include "referee_system.h" #include "jetson_orin.h" #include "bsp_uart.h" -#define SUPERCAP_POWER (20) - +// #define SUPERCAP_POWER (20) +#define SUPERCAP_SEND_FREQ (1.0f) // Hz //todo ask why it is 128 #define SUPERCAP_RX_BUFFER_SIZE (1) //number of bytes #define SUPERCAP_BUFFER_SIZE (64) // new buffer @@ -17,7 +17,7 @@ typedef struct uint8_t can_bus; uint16_t tx_id; uint16_t rx_id; - uint8_t send_counter; + uint16_t send_counter; uint8_t receive_counter; uint8_t final_receive_counter; diff --git a/control-base/devices/src/supercap.c b/control-base/devices/src/supercap.c index 87ba66d..c2ea9d4 100644 --- a/control-base/devices/src/supercap.c +++ b/control-base/devices/src/supercap.c @@ -3,6 +3,7 @@ #include "bsp_daemon.h" #include "string.h" #include "stdlib.h" +#include "bsp_serial.h" #define SUPERCAP_TIMEOUT_MS (3000) Supercap_t g_supercap; @@ -99,4 +100,8 @@ void Supercap_Send(void) // supercap_tx[2] = 0x2012; // supercap_tx[3] = 0x0112; // ! do not write more than 8 bytes to the buffer + + // UART_Transmit(supercap_uart_instance_ptr, g_supercap.tx_buffer, sizeof(g_orin_data.tx_buffer), UART_DMA); + uint8_t max_power = 60; + DEBUG_PRINTF(supercap_uart_instance_ptr->uart_handle, "P%03dP\r\n", max_power); } \ No newline at end of file