From e6ccaeb2c96cc8987af388c29b21afdd868ef5a1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 5 Sep 2024 12:35:23 +1000 Subject: [PATCH 001/463] Copter: rename RTLAltType enumeration entries removes redundant namespacing as this is enum class --- ArduCopter/AP_Arming.cpp | 4 ++-- ArduCopter/mode.h | 4 ++-- ArduCopter/mode_rtl.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ArduCopter/AP_Arming.cpp b/ArduCopter/AP_Arming.cpp index f33be96541745..681e684dd0689 100644 --- a/ArduCopter/AP_Arming.cpp +++ b/ArduCopter/AP_Arming.cpp @@ -179,7 +179,7 @@ bool AP_Arming_Copter::terrain_database_required() const } if (copter.wp_nav->get_terrain_source() == AC_WPNav::TerrainSource::TERRAIN_FROM_TERRAINDATABASE && - copter.mode_rtl.get_alt_type() == ModeRTL::RTLAltType::RTL_ALTTYPE_TERRAIN) { + copter.mode_rtl.get_alt_type() == ModeRTL::RTLAltType::TERRAIN) { return true; } return AP_Arming::terrain_database_required(); @@ -252,7 +252,7 @@ bool AP_Arming_Copter::parameter_checks(bool display_failure) // checks when using range finder for RTL #if MODE_RTL_ENABLED == ENABLED - if (copter.mode_rtl.get_alt_type() == ModeRTL::RTLAltType::RTL_ALTTYPE_TERRAIN) { + if (copter.mode_rtl.get_alt_type() == ModeRTL::RTLAltType::TERRAIN) { // get terrain source from wpnav const char *failure_template = "RTL_ALT_TYPE is above-terrain but %s"; switch (copter.wp_nav->get_terrain_source()) { diff --git a/ArduCopter/mode.h b/ArduCopter/mode.h index 031a9a0d26a6f..45ca97176d423 100644 --- a/ArduCopter/mode.h +++ b/ArduCopter/mode.h @@ -1420,8 +1420,8 @@ class ModeRTL : public Mode { // enum for RTL_ALT_TYPE parameter enum class RTLAltType : int8_t { - RTL_ALTTYPE_RELATIVE = 0, - RTL_ALTTYPE_TERRAIN = 1 + RELATIVE = 0, + TERRAIN = 1 }; ModeRTL::RTLAltType get_alt_type() const; diff --git a/ArduCopter/mode_rtl.cpp b/ArduCopter/mode_rtl.cpp index cfee04ff72024..e5d774bc33f4d 100644 --- a/ArduCopter/mode_rtl.cpp +++ b/ArduCopter/mode_rtl.cpp @@ -52,11 +52,11 @@ ModeRTL::RTLAltType ModeRTL::get_alt_type() const { // sanity check parameter switch ((ModeRTL::RTLAltType)g.rtl_alt_type) { - case RTLAltType::RTL_ALTTYPE_RELATIVE ... RTLAltType::RTL_ALTTYPE_TERRAIN: + case RTLAltType::RELATIVE ... RTLAltType::TERRAIN: return g.rtl_alt_type; } // user has an invalid value - return RTLAltType::RTL_ALTTYPE_RELATIVE; + return RTLAltType::RELATIVE; } // rtl_run - runs the return-to-launch controller @@ -410,7 +410,7 @@ void ModeRTL::compute_return_target() // determine altitude type of return journey (alt-above-home, alt-above-terrain using range finder or alt-above-terrain using terrain database) ReturnTargetAltType alt_type = ReturnTargetAltType::RELATIVE; - if (terrain_following_allowed && (get_alt_type() == RTLAltType::RTL_ALTTYPE_TERRAIN)) { + if (terrain_following_allowed && (get_alt_type() == RTLAltType::TERRAIN)) { // convert RTL_ALT_TYPE and WPNAV_RFNG_USE parameters to ReturnTargetAltType switch (wp_nav->get_terrain_source()) { case AC_WPNav::TerrainSource::TERRAIN_UNAVAILABLE: From d96926050be61ebb92004647b5e67ad17bea9149 Mon Sep 17 00:00:00 2001 From: Jacob Dahl Date: Wed, 4 Sep 2024 17:20:40 -0800 Subject: [PATCH 002/463] hwdef: ARKV6x: fix RC input --- libraries/AP_HAL_ChibiOS/hwdef/ARKV6X/hwdef.dat | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/AP_HAL_ChibiOS/hwdef/ARKV6X/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/ARKV6X/hwdef.dat index 0c2038deb060e..9a36471c7f032 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/ARKV6X/hwdef.dat +++ b/libraries/AP_HAL_ChibiOS/hwdef/ARKV6X/hwdef.dat @@ -83,10 +83,9 @@ PH14 UART4_RX UART4 PD8 USART3_TX USART3 PD9 USART3_RX USART3 -# USART6 is for IOMCU -PC6 USART6_TX USART6 # used for RC SBUS -#PC7 USART6_RX USART6 +PC6 USART6_TX USART6 +PC7 USART6_RX USART6 # Uncomment this line for carriers boards with an IO MCU # IOMCU_UART USART6 @@ -284,7 +283,7 @@ PG0 HW_VER_REV_DRIVE OUTPUT LOW PF9 TIM14_CH1 TIM14 GPIO(77) ALARM # RC input -PC7 TIM3_CH2 TIM3 RCININT PULLDOWN LOW +PI5 TIM8_CH1 TIM8 RCININT PULLDOWN LOW # barometers BARO BMP388 I2C:0:0x76 From 18e95c7979a506dae26bdef9710dc3b8dafb698d Mon Sep 17 00:00:00 2001 From: George Zogopoulos Date: Wed, 4 Sep 2024 13:28:12 +0200 Subject: [PATCH 003/463] Revert "AP_NavEKF3: Corrected logged units" This reverts commit 1f01f750360d197f0a631db15510da6062e45b19. --- libraries/AP_NavEKF3/AP_NavEKF3_Logging.cpp | 10 +++++----- libraries/AP_NavEKF3/LogStructure.h | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_Logging.cpp b/libraries/AP_NavEKF3/AP_NavEKF3_Logging.cpp index 03e23b7ab8753..50fa12558d296 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_Logging.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3_Logging.cpp @@ -165,11 +165,11 @@ void NavEKF3_core::Log_Write_XKF4(uint64_t time_us) const LOG_PACKET_HEADER_INIT(LOG_XKF4_MSG), time_us : time_us, core : DAL_CORE(core_index), - sqrtvarV : (uint16_t)(100*velVar), - sqrtvarP : (uint16_t)(100*posVar), - sqrtvarH : (uint16_t)(100*hgtVar), - sqrtvarM : (uint16_t)(100*tempVar), - sqrtvarVT : (uint16_t)(100*tasVar), + sqrtvarV : (int16_t)(100*velVar), + sqrtvarP : (int16_t)(100*posVar), + sqrtvarH : (int16_t)(100*hgtVar), + sqrtvarM : (int16_t)(100*tempVar), + sqrtvarVT : (int16_t)(100*tasVar), tiltErr : sqrtF(MAX(tiltErrorVariance,0.0f)), // estimated 1-sigma tilt error in radians offsetNorth : offset.x, offsetEast : offset.y, diff --git a/libraries/AP_NavEKF3/LogStructure.h b/libraries/AP_NavEKF3/LogStructure.h index 256cf0468bbe3..a5629ea3f3f6e 100644 --- a/libraries/AP_NavEKF3/LogStructure.h +++ b/libraries/AP_NavEKF3/LogStructure.h @@ -193,11 +193,11 @@ struct PACKED log_XKF4 { LOG_PACKET_HEADER; uint64_t time_us; uint8_t core; - uint16_t sqrtvarV; - uint16_t sqrtvarP; - uint16_t sqrtvarH; - uint16_t sqrtvarM; - uint16_t sqrtvarVT; + int16_t sqrtvarV; + int16_t sqrtvarP; + int16_t sqrtvarH; + int16_t sqrtvarM; + int16_t sqrtvarVT; float tiltErr; float offsetNorth; float offsetEast; @@ -437,7 +437,7 @@ struct PACKED log_XKV { { LOG_XKF3_MSG, sizeof(log_XKF3), \ "XKF3","QBcccccchhhccff","TimeUS,C,IVN,IVE,IVD,IPN,IPE,IPD,IMX,IMY,IMZ,IYAW,IVT,RErr,ErSc", "s#nnnmmmGGGd?--", "F-BBBBBBCCCBB00" , true }, \ { LOG_XKF4_MSG, sizeof(log_XKF4), \ - "XKF4","QBHHHHHfffHBIHb","TimeUS,C,SV,SP,SH,SM,SVT,errRP,OFN,OFE,FS,TS,SS,GPS,PI", "s#------mm-----", "F-BBBBB-??-----" , true }, \ + "XKF4","QBcccccfffHBIHb","TimeUS,C,SV,SP,SH,SM,SVT,errRP,OFN,OFE,FS,TS,SS,GPS,PI", "s#------mm-----", "F-------??-----" , true }, \ { LOG_XKF5_MSG, sizeof(log_XKF5), \ "XKF5","QBBhhhcccCCfff","TimeUS,C,NI,FIX,FIY,AFI,HAGL,offset,RI,rng,Herr,eAng,eVel,ePos", "s#----m???mrnm", "F-----BBBBB000" , true }, \ { LOG_XKFD_MSG, sizeof(log_XKFD), \ From 94062fce5cbbb8ee7e4d90b6fd0d81384da3aa17 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 14:41:47 +1000 Subject: [PATCH 004/463] AP_Mission: do not adjust ret_packet on get_item failure do not modify the return packet value at all upon failure, rather than indicating invalidity with a flag value. We return boolean for a reason. --- libraries/AP_Mission/AP_Mission.cpp | 30 +++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/libraries/AP_Mission/AP_Mission.cpp b/libraries/AP_Mission/AP_Mission.cpp index ea441be219ba8..f15e753e4a031 100644 --- a/libraries/AP_Mission/AP_Mission.cpp +++ b/libraries/AP_Mission/AP_Mission.cpp @@ -701,46 +701,42 @@ bool AP_Mission::set_item(uint16_t index, mavlink_mission_item_int_t& src_packet bool AP_Mission::get_item(uint16_t index, mavlink_mission_item_int_t& ret_packet) const { - // setting ret_packet.command = -1 and/or returning false - // means it contains invalid data after it leaves here. - - // this is the on-storage format - AP_Mission::Mission_Command cmd {}; + mavlink_mission_item_int_t tmp; // can't handle request for anything bigger than the mission size... if (index >= num_commands()) { - ret_packet.command = -1; return false; } // minimal placeholder values during read-from-storage - ret_packet.target_system = 1; // unused sysid - ret_packet.target_component = 1; // unused compid + tmp.target_system = 1; // unused sysid + tmp.target_component = 1; // unused compid // 0=home, higher number/s = mission item number. - ret_packet.seq = index; + tmp.seq = index; // retrieve mission from eeprom - if (!read_cmd_from_storage(ret_packet.seq, cmd)) { - ret_packet.command = -1; + AP_Mission::Mission_Command cmd {}; + if (!read_cmd_from_storage(tmp.seq, cmd)) { return false; } // convert into mavlink-ish format for lua and friends. - if (!mission_cmd_to_mavlink_int(cmd, ret_packet)) { - ret_packet.command = -1; + if (!mission_cmd_to_mavlink_int(cmd, tmp)) { return false; } // set packet's current field to 1 if this is the command being executed if (cmd.id == (uint16_t)get_current_nav_cmd().index) { - ret_packet.current = 1; + tmp.current = 1; } else { - ret_packet.current = 0; + tmp.current = 0; } // set auto continue to 1, becasue that's what's done elsewhere. - ret_packet.autocontinue = 1; // 1 (true), 0 (false) - ret_packet.command = cmd.id; + tmp.autocontinue = 1; // 1 (true), 0 (false) + tmp.command = cmd.id; + + ret_packet = tmp; return true; } From f7e0b9cb897569f650787d8ab46f60e0d7dcfee8 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 13:07:14 +1000 Subject: [PATCH 005/463] Tools: size_compare_branches.py: blacklist build of Pixhack-V3 bootloader we don't have a hwdef-bl.dat for this board as it uses a bootloader from elsewhere. This should be done on the hwdef content, but that's still coming... --- Tools/scripts/size_compare_branches.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Tools/scripts/size_compare_branches.py b/Tools/scripts/size_compare_branches.py index fecb45188b4d1..6ff77c1295a46 100755 --- a/Tools/scripts/size_compare_branches.py +++ b/Tools/scripts/size_compare_branches.py @@ -166,6 +166,7 @@ def __init__(self, 'SITL_arm_linux_gnueabihf', 'RADIX2HD', 'canzero', + 'CUAV-Pixhack-v3', # uses USE_BOOTLOADER_FROM_BOARD ]) # blacklist all linux boards for bootloader build: From 61b1a2d525a45f8857007e7bef44e9192588dda7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 13:02:34 +1000 Subject: [PATCH 006/463] hwdef: remove SMBus battery support from all minimize-fpv boards I doubt there's a single one of these boards on the planet using stock firmware and smbus batteries. If they exist, the custom build server can re-add this --- libraries/AP_HAL_ChibiOS/hwdef/KakuteF7/hwdef.dat | 5 ----- libraries/AP_HAL_ChibiOS/hwdef/OMNIBUSF7V2/hwdef.dat | 4 ---- libraries/AP_HAL_ChibiOS/hwdef/include/minimize_fpv_osd.inc | 4 ++++ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/AP_HAL_ChibiOS/hwdef/KakuteF7/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/KakuteF7/hwdef.dat index 281f1ad3b4095..fff9f062272e9 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/KakuteF7/hwdef.dat +++ b/libraries/AP_HAL_ChibiOS/hwdef/KakuteF7/hwdef.dat @@ -149,11 +149,6 @@ define AP_BARO_BACKEND_DEFAULT_ENABLED 0 undef define AP_BARO_BMP280_ENABLED define AP_BARO_BMP280_ENABLED 1 -# disable SMBUS battery monitors to save flash -undef AP_BATTERY_SMBUS_ENABLED -define AP_BATTERY_SMBUS_ENABLED 0 - - # setup for OSD define HAL_OSD_TYPE_DEFAULT 1 ROMFS_WILDCARD libraries/AP_OSD/fonts/font*.bin diff --git a/libraries/AP_HAL_ChibiOS/hwdef/OMNIBUSF7V2/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/OMNIBUSF7V2/hwdef.dat index 0f13a42fdaeb2..f27224e751879 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/OMNIBUSF7V2/hwdef.dat +++ b/libraries/AP_HAL_ChibiOS/hwdef/OMNIBUSF7V2/hwdef.dat @@ -132,10 +132,6 @@ include ../include/minimize_fpv_osd.inc #not useable for quadplane define HAL_QUADPLANE_ENABLED 0 -# disable SMBUS monitors to save flash -undef AP_BATTERY_SMBUS_ENABLED -define AP_BATTERY_SMBUS_ENABLED 0 - # one baro BARO BMP280 SPI:bmp280 diff --git a/libraries/AP_HAL_ChibiOS/hwdef/include/minimize_fpv_osd.inc b/libraries/AP_HAL_ChibiOS/hwdef/include/minimize_fpv_osd.inc index 11be0caeab143..71dafdf4a2c7d 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/include/minimize_fpv_osd.inc +++ b/libraries/AP_HAL_ChibiOS/hwdef/include/minimize_fpv_osd.inc @@ -28,3 +28,7 @@ define AP_TRAMP_ENABLED AP_VIDEOTX_ENABLED && OSD_ENABLED # force CRSF Telem text support even in face of normal 1MB limit: define HAL_CRSF_TELEM_TEXT_SELECTION_ENABLED OSD_ENABLED && OSD_PARAM_ENABLED && HAL_CRSF_TELEM_ENABLED + +# disable SMBUS battery monitors to save flash +undef AP_BATTERY_SMBUS_ENABLED +define AP_BATTERY_SMBUS_ENABLED 0 From bfcac18eb27be7b6eec1f3648f26fda6353d6dab Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 12:36:29 +1000 Subject: [PATCH 007/463] hwdef: GEPRCF745BTHD: rely on custom builds for external baros this is overflowing - it has an onboard baro, that will have to do... --- libraries/AP_HAL_ChibiOS/hwdef/GEPRCF745BTHD/hwdef.dat | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/AP_HAL_ChibiOS/hwdef/GEPRCF745BTHD/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/GEPRCF745BTHD/hwdef.dat index 1d84d2734a6f0..5c0e43a2a81f0 100644 --- a/libraries/AP_HAL_ChibiOS/hwdef/GEPRCF745BTHD/hwdef.dat +++ b/libraries/AP_HAL_ChibiOS/hwdef/GEPRCF745BTHD/hwdef.dat @@ -170,5 +170,13 @@ ROMFS_WILDCARD libraries/AP_OSD/fonts/font0.bin # save some flash include ../include/minimize_fpv_osd.inc + +#only enable BMP280 Baro +define AP_BARO_BACKEND_DEFAULT_ENABLED 0 +undef define AP_BARO_BMP280_ENABLED +define AP_BARO_BMP280_ENABLED 1 +define AP_BARO_MS56XX_ENABLED 1 + +# need to probe external baros even 'though we're minimised to allow custom build options: undef AP_BARO_PROBE_EXTERNAL_I2C_BUSES define AP_BARO_PROBE_EXTERNAL_I2C_BUSES 1 From 4d3e97533d39108009b1c17c2cf691fda3c45ea6 Mon Sep 17 00:00:00 2001 From: jamming Date: Wed, 4 Sep 2024 10:19:37 +1000 Subject: [PATCH 008/463] AP_HAL_ChibiOS: Add a new target Holybro DroneCAN-pmu --- .../HolybroF4_PMU/HolybroF4_PMU_Board.jpg | Bin 0 -> 64126 bytes .../hwdef/HolybroF4_PMU/README.md | 42 +++++++ .../hwdef/HolybroF4_PMU/defaults.parm | 6 + .../hwdef/HolybroF4_PMU/hwdef-bl.dat | 43 +++++++ .../hwdef/HolybroF4_PMU/hwdef.dat | 114 ++++++++++++++++++ 5 files changed, 205 insertions(+) create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/HolybroF4_PMU_Board.jpg create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/README.md create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/defaults.parm create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef-bl.dat create mode 100644 libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef.dat diff --git a/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/HolybroF4_PMU_Board.jpg b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/HolybroF4_PMU_Board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b37b6475b7231fc752053f7d7c747f89c53a7d78 GIT binary patch literal 64126 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�tkxCR72}NEwq#S)Pn@bNl9chEM zIKx8^f%<_po*|nh|Ar8Z!Rl?`n%!-}U;Iat!V)9f!94%@(;hMd-Go)Z(mMJoC?e%m zIEVRw8zATiWxa7mzr{mqHlOfPg|(53zqP1f^yMmwgT{V>oV*>PZ0E+ z@NE2BT#9xA9d>5(YoLw?i)z;M`uF5QuROB7I_c$j#g{?@IR0Wu^Mm@5WV!MycdjTx zJL4eNc-}uUH)8i3sgb0Zmn81C+aXZ$3TC*EeA&4@jdE)y7ba?z2HoP) zr#V&!k5VL#eriKCi~rc?%X&G`-eY+DTJbD|jT}tB%g>YI=Vyl>P^3Sv8bchRDkqu0 zAR?j&Q|^wL2d04w(vvn%q%}n=CI2^H>DRyn*3svQc^q`HUA}#h= z#LNN){`hE7WgtyL)BNoNKpM1VSJJ`}XD2GO-mCv*sFRJRu1)5BZCXn3`1KO`0v+P# zeaf1xSmbrA2hw6?z5X;AqTfDNE0&d`1St_lUUw={0W5zH)kRhnUV}k3o_K|kZ@1N1 zGH6Veff%`xZGOUlfip$RPX#@QSEv-4Zr z8>H75FyeCyBi! z|BoE>#P@3Jm;+6p-pg?Y=hK@kvg*mKO} zf*bhDb#^&pfj4EtS#962k5S)L|KQJu%K1Umgqj69%2*D1{w(Cv4>$=OY(O(-?8|L%B@+WF52=T*(&$ z97{t}DLTOL9jJV_A=3k%tB2t^I{XppAoLUfH)K;Rou_-_FT?d+YL7F3UNLwjUBwQ1 zN4K84;u)&s7dvo6Vbsn+i4{dq@W>X>IcF>HA0Qr72~2N}@^-4fE|Q&ICrZ8Kz1C5l zumzb{JI6+{TdiJQJ4lAkIawk5!svGY8go{<=zp&|WGCgIStjz^$1VfYR*T#(%L5G? zbcO9)W>ntAXb~&2kN+4kmEj5;xMt(x_Uh)PDkxc_P)R^1^e2p7=j;Q!L;p4OF3SmTDh%Uv3-lIwwi`NPq`W<9NRfYYS_h`A$n(jClAmf z-+vk~lYFa?WEPNhxIB?AF;cIRNsjq7J^tL9FWxz!W@lE2*nAB;&G41L#1S?Koui;*M=vMZ)bjU>D6z?d z$Qp#URB+rOgTxzh4@G_r$^O!QWTOaLwqtucE4pp$c_;niO#1A85q8gu49|5;XOFcU zevv+xRUI?Zr*B#6Do~R5{Poe(c%6CSTtEA$T8T`b`38h&&7kD20h=RT;Mv~PwXM}$ zEu&Ngvl#YYqmAuC2U&@IA8K8G;u7b-J5h^axu95xjwMODQJUL)c`4NThRs+Zo)NH; zAkPa(2tnk(qxebUuv46XTbZsoHm?_-5=0}?&)SJ79XA&Dy9s+_IO~C zDf2HOTFe`*YfKqBWI(}pGT}SU*|9gQ3=b3)pB)T1YdlG5x{-hRM4|Z{tQ-;%qfkEZ zEJ0N_A^Hwoc5n;QTW=JvE)ubv?FBodY^WGkd&kRHBxKxF3ODkTvik0Nbh^`=dmO#^ zaee4cJNqJbEb-hUB+_nxI(K1PuWX6`rcVsQ-w9gG((IpAo3{(Pi@ zqW)e#x@_{it+TZoBA1c$owzfllb2a=vsH^ZIL%xodT&2y2euA5vC8jz?z-hybUq(6 zU;g)ygUUBu+EIx(5u|wUgIBKtwWL&&#fI;J^qBuA-{pUM&3%5m-I=vZ;=6msWN$kI zyOG*yd$Xa^GvAKus4xYfDfbaLqR(R&ttWcW zceQ+~Hn*ad_GG)$Dli%Qn=rW*Iz*4l+2C>DHacZ#V|PFA6(3VkxG%<9p%`PO+$YR; zBCf|zu)_hkYTjQfTK@OE15B>r7J84j5?APd0Uv&{tGLUDcP`;QT>vh#dU!m6 z?X#{b{OFPnd%>**^p-?Em%Kt=w}+9#*EjzobS@k?sHZ*S*?-IvK+^Ff9l88d&LR`5#91?c2O#0&12^WaObj;cu>7VDx9%>%#PYBN|o|wKiEszhRkbGB`A0kE)Yw9srclKM1p@N=4p8llN1$fpb(1kYfx6K9P@iP0$ZAP6Cr~ zm4@h(UJ@%LnKYw!;HA4<1+xNDwdu$yc>$l(?L|n^pc)I7=Oq{wWsa25p5ghf1-1K( z&dUa7p-{6cvnXwx`OSJD@c()aoSPwA#%rO94GsXrzBF5=tB6utb?cc+CUAcl1m$9U zgu2cb_fc{ZPhh#%4XD*U#nj@6X)0#j% z?0|CU!@}b~j9Kcu5j^n>7{2dR+f;$ix`FLB{S1Yz4!Ed;l8>1Wt19UiYTMQ;;xMUy zex`PK?1~Ke0W#L@uDCF5i!+lhHVt{$Ird`uK3xgU9Q^X!d0F0dg#pG|SX|s2=ATbr zNvzhfY7J7gfC8`_R<_}8+QO^A`iuwdZrgP%M%_`^^V<2;4eQg_k-7&4YNg3-O*eC2 z{!}@+a+~E4HB};C%2(>3lwweWV5z2IEkMW{`O;e9Kj&jY$uxaxaH8 z3I;7{9&M9v!XaT$F(G0$b2)jkm~I&3Yo( zQFpEE*6;y*!1VTe8H8*odP9F+&qfY{A|0lVm_VW-^CtDY)R!bo;}gw5^~UrI)%}02 zDM&7{eJ>S{F;@B^-f-40YS%#t(yyW7L|W>jvwS3dJC~_*O-?V~usa6+jgQtlz`VfZ z4{0(Wi*KxtzvDrlQI>Ta>2=#bl(F^P-%93!{@$Nl_GnqI5ky& zS1Jq_{BCp8XM$3c8wa&mlT{1FOy@3r1qJF)!XbZ#{EMd}r*{}0$>5_CpC?*|F&GUb z>kE8STzdN{ayrw|_u$S_X8yTH@=`{_<>6At+w{69i5rFUeD)q;mX07xNM~H6k{8qq z64|b9<#IGni()uh4@@sojsXurDhEEmJ$T{eRY;pZa7IbDvyY#3<<`HJ@U^r#TdeI* zq}Z-%aKGuBPPdi>?=F8__dJP|@FyReM1isrTk^^y+uElo5|t^JeNXv5f91q#SbM`| zC*RdIY7m_K@s~k^&nRlqKdM8#?&0*Lgvv zDkd`h2o#1esQ6ne5d_1bb|4u_N=-koz zT*>C~U0Z~3TT*r5<+nN1nFAg;Tx@qoYoV!7DJK5Ee9(-52=My-Y2?r}PndW5>IyGG78E=BfW7{V{3g z{Z34A=Xb}@{labb>pMc_>`&gC^?RC?g?kTq@vyng$ViR0 z^P#jegQL_6XI_f?w)<^OY0?ruoz{^PdAOl&bi*w-)&jvxtQ~JD5N>&4ck`YwD!(9| ziTJp;?llKbpK{4{v-xoY(TO@l45AxEsS0!7%~gd z>4_Bix~}6WXZ!GWWw=^XPBVvEW$(TL4K`ItWP+N&KgsHW`Cxs z`6!d2=~s=&yLl`bPmlB)ttRPOHQonj93)-*pEVAEdjkWCQ*uWH0g(&>$`+|X9rUm# z#~Wwaj=!#~tNmc*sA#Cba?hjULZE@s2FilETsXU1Y6TslIevd6si{?|=_?UVof2 zky(z?cYMNW-0D%1$j4t>jDopnU4}5|hh+J<@7|lYc|YD24Abt||K>^()sl*qO9agE z5oKWI%~|0!phWQ;5YYHy^yU(B#@K-w*kY^#_crCwVaagv$FJxEA0%ZKCkdM1|HTbw zjM2oRi~s%V#40eGo;fsPah(7P`GGf8MIbj76enpca<4z%+9n9tNdj}-mhL~n$fs7= zTciY_B;w3|V>a}Rr!)3Hmqo60?po*!Bk2q1(SMV=!k7j7pd?MDR?>(=kt9xyK577z zMsxzhhPZ+NZhXORk0PDB+q@wTsl>1fowISkZchPntS**Q?(uvtNavOBMK)E2_)cfh z96%?3mR(!w$`3(ls^kV|?zjkKuX{kTrH&o7lf+IdmG1#IWo;Ov<8TP051qlv} zUqP>gOrd)N$eH7bGiT*I+5tUx+lox~XGNX`;936$83|Q-mS2mwv_b=_0QpP(WrqUP zv>uKU7YbnFl;G>!WdNNaNJft;sM1|U0laktGRl>*gmxk^YF8%-n~R)kXMAPCPL&`d z>(Oa!#9iU%_oAt_#Gz9=$ZD=VVfkq|R8Sd~v0~zlqv< z^IVOYKOGqj`%-}}XhKM20^6D>fsBeuV>K~}&d_jON86?WM5eOZU{AEe;5 zHgt-}nLT9#MwDxzs}Yi|+h zV#59*^+Rg-ah?_AxJto-^apUBmVDobgaMV|#;8GPO(p6gmp{wgpWTzLB5;=%H#*uc zCoYV5wazxO!lc8x#Z9e>e?!V`Yo$VdZ9KB3J=o0s^4#eQ1mQp8+_Sf+JnUP5*l~ytQF%5!qMitihJ7_0u^szX&%6cuYm*Q;(*n&sq3?G!wrRwJ>CTn)rCSD(}v* z>vDs?8V%3b#=^Vd;SmpMH)4TpMl%%1X1q1?LTUSQS z!=f2m86&%#HtByEwlLW%ZPQ{WGdgQ(!nKD|^2I*5gujLX7>tIN z1)o$^^4ZvqrWL<}im@5e&>O`2?la{s5lnlGTP8-s`vdINT@7JhX>0pp3> zl6c%VRy3(knrR^TJGw&`JZKVfJ!hdNSz~)(&re5~S zga7Vw^68IQZ%uPTbLwQnrTq)M1n1GLg?^__GR0?2oB#Bn|6?Nbb?ovNeyG-Yv8tvM!yCCza_UW)+gMiHKotVa+5HzGi$QpX z4(%W}0?#44hI46qWiuO*0(7JlaK*0uoAL7di)<0#U#FfeujiqMx({behyLKe6F5g98eP;MIr7QegLPwN4cw zr@5Eci1anOA9NYmpEb4r;oRhZ*pVr4Nc*z^-2|F|rN+i<2Sij(?LM7*qk{l2Ezl4+ zV)y1L-N;$vPk@C)vD5%}gMd84@j-0G4(#CY-%7;SQUg@c!`RJlPT=#kDfrX3_kQeq z(;op-3bY*<0NIQVW=n*=ZHw(bvME?ez~upqW9yzNkav>(+(6CQ|1M*A0kj7my_S5t ziFZ{@+g z(EPnZZ>anQb-`*Q!Mc@~e{!z(Fxo@sT~l;I$6Z$((M>hMP9)CelHj+Md&|(h-++A) z$;q#a);U6Bdq(DmiMEdGEep8VxOTQ)%hs|vJONKLi`d8X_L0REl96-rWMuwKoY7s1zRL{Kz35(h*E^+8T6VZD{8{1Z#I}3MeT}VMCWh zRjtc!QCYO;+?V@|1K}Dn7HP?)0<0PjhrFh4YejShBAxB|cj1f1kbI0HNqR$e7RmnJ z3^QY#ie$>NMYTpTFDC!;dS+mLTkvN9k1+Q&3%N;jjEb3%qX6x}pk5_>^V;+B5Z@d3 z=hUeB0ZH@h6Rf5~ip^i(q}Be^H*%o?=vj%@T8;Ta|JH;nPmGMxS5d^$RQ9IY9zU_;pzVhMa9TP4x=Tz5`8S>lUUB$v(xybDS zJm5vJ9a9u~T-+!;xr?~~XCS&V@b;MID*( z%&kHx>E=P}`(Hk%j(lTFG%n=V-LiXbq3=CssLfpG$J`9I*my#i{MDE1lH*HD>iwRK zL+Q=ab(V9`^_~K9@w2*mlR>%6j+n>I9neu2!RHW%Q$0nzhMIMjdAXCK@y=%X^R`In za7vxOk5&C+mDLqg_jd2K+&fA)VScc;x7dTh_vpF#eosQVOK`gU!oi;t9Vk?F`ZP`7 z&qWN6F7q=T9L(i+Hw^2i+Hicx56dGA$1OCPa+MjasV9mJJ?j6j6$s$&3@{?KK-rZ! z^VZImd=%FIk$DrpMN9%_eeg|U4jTFgV6*kZ-Pl1QCP|q$=Sp;re*P4- ztrRJ(5vNc=jqhw_(&CmLe3#B;2PQh<}eO z_g$Q#{BR3TfBW<2)7VF~QRm(~Z|AD4w080Bl;6abKpSc>Vb(XwgIZ=@Of6aIM+rxG zL6=7gp5v?0>WF4+sS<(R6`$rf!T%x!nc046e&cKuod8Wk1c`50oo0GSqzAv43*_n2 z9h@_h+<0y_uOY}#uyH?0FDYE#QC8=E(AO|c=Q4&eBfiqXFz(__HTJJxlL-<&U0s)2 z!iUp>7`Ka{*5uAv!0BGz@Y^UNQ8}QAGuiiY&q;KSPR9$CzwXjKZP018;ea_a0(FA2 zj4i&Da+T-VWf6vTgowWu%6#9pTlW3! z(^iYn4Z-;h4OFaWdWax|}xTcufS-BGa9u-ef{m{ID}a zX8TpSB~ScFe3y;&y@YO;+a*R%l=h9+4@1TW=msq-R-B=hcqBVnbfSk8+^C0ZIdlUY zi>5?`tj~F5_wQVGiW7`e`t60AJ$)-;GsNHtPl|TmoO$hduC}njt~4_c>x=usU5Fb# z*Y*v`U+@KW5*^q<7kROq%Bm>BC6UO{A5ec4N>~T+bQ~VaKwiE_;!<);*H>7*7EpZS zSyQ^{=4)_}Vb83Y5^I#|+r(+cV8~h{mC2r#Z+c)j@DnOsURQ=?TnpsgdrNf5{@NI* znl*B^^W5vwWL~(93*qkDlZR&|@R;$g_GDZehQ}gJQGLj!f2YNvu(snQ{9J13CnbAE zl$wOK0Ym$5J3}%{zG9H(=_{zMLTEXV{Fko(WiWC(34}Q8mFkO;TIp|NqXsH%X=YT6{ptkW9yb`N<6J~Np#TLS5a6RhY1`Bj@VNz9e_~&@g|Le* zld`EDK$HdTE>+%l+W@VMG^%Yj6_>5=dOoqC`*j{98?5Ww(EW7|k{Nb^#@G7aL0T9XaDlA;dWwm4an?V;Ti~J_Inh6nZ!J zTJU#dpGo_?w$=|?lKGo@wDv zAEoWnxY{iya8x3zAE1kP$2#?#2r<6z5c_QGDD^*uKz#+(l7)g42H8eqEpaKpU5ynXv<6- zql)wQSt+1r5bWc~hFbN@GPeG*{XIjAH#)>u8L(S+ zc@$V`xkQTeP8b?(a!zoM`6Q`3R0{oM-sSG{QQ%bk=-JUYZav2fH4005EuYJMB^GLq zv;$}JEb9y@bLOn1-wIo9u5L?v`AL4U`^9V(3&Savh4&2$9AsP)Vgh|;2OBYhfc&P4 z&x~`dR^G7E^XZM&e3ilUutjFYAJE&$f?w4v=CtN550RlZA2sdRb}%eO&mN_~MG%>9 z=B#)wvAoKc3S^fKol_{hLB*MziK66y)tLY0M8J-r@RJY*W#+&ylM{m0OH0J5lNXw+P#3!ILa{H zU=F75!@T!`IP-2qto#^#w8q-~2L1waYLkpB2<;*akBn$FFQqpx!1k z;UWAt1XNVwC%pOpJT(Ck{x>$U>#{I2>MdGYfXZxK*wQNR;~`_0?aQ!ec8UaDo-ndU zn$RrP;BP&9ZTKDo6Jy5F>~V>em8bcJBRKm7-vkaDS%KDivprZof1Wi%L+$}$XPsSF zqF>eQ>Q}THlX!m_;lG^S4~ipBQ1Dez4$AUy>8_(oYPsYI%z_Ne$tTnzxH(ynp8Lw3 zDN9P$f7TviG=RNGm+=7^S?n!NRd%t!+25(W9OG}S=YOh{xOv}_P3Xy8_wwv6Thdk- zsZYo!Xw71(d+b2*Oy;O*G5L_DEI&(f<`{o+&yhLj7A6&QS#o(O_4nCI?`vdNomi`p ziQ-@LzciK_+YR*%xhzSQfmaNzyrQ~hYd8!Yw zGMIbb3A4f4*zgv|)>pM6As%;8$3uUV&^+gaU&`+fj@?obwDfx6gb*7DxXqrDPf!>U zi=ZE>ojg39Q*T5H-H^v4&$tHbvVNUV6!>yGTbTA|CdBv2Lgjd2v%bHFe9QM&1NRp{ zQrFrFQ|>A~GKH!)xT%VNGiuYn<86W6qW0wn7*UMDq;F_tt1A>`X-Jy>U9^K$hQ~W6M+>M;SWXVtAQ|aB) zx9M8pcC1YoiMg)!i9OqQCwU=a>;|OwtFz8bfn7qG*s}zq>eyBz$bpOF_w);KRof}s zMY0>nNXSd*WRF&v-5T35FK5jC9+W&*$#rkC004*Oc9FrxHRSu`l3z1T4ok5D+4?WN zr0`<5THXzUG}F(>E_JIeovSNleF|2AgIaPGyrpk|%x^Mq!)}cNHqF(afGzlrF8?bj z>rc)bi9-&(2{9PqGl1AgPgYQuOLea2mx4Lt;ix4_!=0$m3cvk0u<<_^Q#55%x zo`Bc*lP*-@f|hnSCwoY?k2ZH2IE^&l(;P;ZdO^!Qh7ZP-Ct<|?THlwNd z0LOT91NI~iHgMC{ysS6)XdI8#LdIt3D;?7z^$M;;nbf~oMF-`M4hb_$y2w>^mOF+N2r z#BRm`QyfJ<+ha;c3jDi84)fQ*$ixM0=;j-`+~)e;$_wVzb3ozW4k5k&mK$CHK$Q1i zBGHXu>@qks>0ft-oi{nL;0wZT{c8vYB3&?57U7QH`?oGmd0uA0UzXLj$5 zf1S*j-Da2r$os4#p}4e0FaB|TS2R!o9s+JY!;YPUY<~OGL(U6@TG_uXI_AlYf4Ubi zd(`3%fY!d{36r%_Gj1F0Syo*6UC8-+BTmSn3=*U{5U-d8oZv1|fx;_mS4Hs%BLe0d z#;zVgd$gb-u3`XvNEG?vH}1fNJJV@XUfaEnGWRfcxszS=qsltLb2c9*Nu)tfXOnJT ztEjLk_S&@eoT*Cl~DXRR?W9s0N&tsJ^^k}w;h2+~wf+^X0=-5)3jHfyo zjX{63UlNY=%ch+U^t8XevgSx`*h>3t;RsHsz|7x3{_CD?Nk940rdPUR z#i{((^67)-r$B&4DWs}DS2(g)PoimlOkyQ+1!5EX>LOfoa>f2Wz_0hh8uG*HGlswC zsNVqarlBHI2vyVMdCbHW)gP0SDY^HieDIU0F98HI0vY43)orV`<+CCb_F&`kK+J4x zb~|$eXM$U|J&+sIgrzFqWn#1y=3BAW$4kXN1re?-G|b~Vny}OaZN*WqJEgzs`Kw`) z`d_Z- zX&(Qz4K5Px%SQ-@kZhWx2|lq?7S#()B1bDf@;|mI=U^3(2bKzE&5})QYvm90b zq2&H*^QH!KqNmGysfSZ%lm-rNnvWR54J(s#?&MW=U*AU=?j;&IyLxi^s@`WBCQK4G z*z0?0{V$*xcLTv3acyAPL5a1mWpONG?fDVa@3bbk7Ih4~Lh7c5xQWZtItUyQob&M0~O!3~7<^iK~g3a*JJi zV5r#c8(gRxsrOdb)yg`*0a|xvLSc_ zE8nlao$@ha88SN+!=%45oCV)mwsKo4<%~9^=aDsxXfjno{-QuG`HXNC?79BTogcW9SgJR93ffAXx08?A#fVB$bLptG z2IHC_h3;OECe#J%bP`9)QNip?RS)oh1@YC+f9)l{>gawWy?KRB;7KB06`3&ArcjD!GL{YV#v0AU+tb9kKhE2^XaLQ$OK+ty6rih@#E4Lm+t4 zDnKs+uSw>Ts5ii6qPAuiucZ5b@8kCV=?6)6(Z&972<1b0KeJ_Fn;Z%oo5&xGt^#g!9bwNP znSJC--@&m^Fi^XXsXBQzdn7+%fpV!S45>_|MP@1kdOGetUK>Y{;}&F~uZD66QvEwI z%OOM@fJj9Fc{Kn;rgiolJA2ay*})RD?anx7{&2ZCaA{k*s==tE+RUuyWW0 zwQ0$Zsw(eVHl9FsMV+@lDJ&LwCL5mPXFuBCv#gF*eZqTB^%7-^2=vJ|4C7S>u^!x6 zY?EzutDp=v`tsz&TQ*YKx>=0(V1&k%B+YXq{|yhtV`oKoNZ z*4t+&atX(bo5?R*gjVsBs}l-=z;;nFWQF5Bz;lK9-r_x+cr;XnO5wpZ6l3@4fVc+s zEs#g>(F(ZBslFXR#C~?7(tRbd%1xq(+7GZ1h4L%aWd2-k_&k^Sdw^~putJWTFo@}h zgG9ewphNg@h##%yuh3*dHUqWoGpaM7^$Ers?z`sI%wwsFFH=b(aTKFyZ z`y2BM?bkOtv|=fIZ5g25OdWg;8>C<#?t4V3LXRMAZp-0(I1SI294RsGRsh~;fZM}4 z+6SLAql<}bFsatd=?&dZ$ef~RWm33{EVFK+QO(!fzMXk(vc*_GJ~fv~QNdYGQb4xM z`)V(K0Cmqs0>xKKiu2*8AB|eoKy!tCNr0BVNCmg55L#H1kw z@IupyC$;?Ng;Js{@K~LtDvNK|NQ4-!f(1=DFgH}U$&!PcN?QvmCn18Z>L`{lU_2}N(`3>2^0AZ5E-He|O#$)}EAFwuS#8tHgu6NJx z49^U09R=11i7iFWhUoC+7Qx@4j6_?s+mwgWF#IK_zIgLR#b8{vDqPgkpqv^uHSzuA z+bQ}9?7GMP!b&~fNY^&>=j>MFf{?59bC{W_RlY~J9w8h9&9TvgI^Qd-D&<^E7!5k* z;+v)EKE@=py~#FGOG7k8y(fbNRa{vlO-c3iv6tqD(q_dt>IK7(KN0N0%YE}>>c+x) zl;54|YM&-5$7q>8ujScUsOg+;7>obmZZWDI7iBD#WA`p){>KSGKSTr*l!}Othj}Un z?{QmDGXQhrp7Kr)lH{6kx6A$~Cn3p|^B(7hGH-2?T778e6Z6qpC^b=RtPb`*5^iYH zHuLIAo=^IQm);1L9vJcU3@x@yW1sGjCmW1GyyuDq4mxy+NWo)SSq{60)3?eiBWCWf z(pP{pUlE6@+h-22=q)uv#_N)bnY{iUNL<0%!6$zqg-A z@l47KBtkRQ6z`rZ>#lhS(+DAA@oj0pZCD&BsN;BU5^0!D!@9R&@mOYI^3O#&FZzL* zU)ZlYTHZS`O`r5L^Ohj1R^u6F0NQ0rpUTza-V+8~=HB>U6y5H`IHEwqYl+$%O2n_({TV3H zohYckWfj9VsvOUKQ}OQPkL9o^0eYMO8TwY$HtZD>`OhRC4;(RVu{AnHU5tHy#!#t(%xdVhY}E!*p~j^`<^m%sz;$O>z7p zwmBOSLsz)mDkW73vN;nH5VQ>9swJ2u*=_bcy174_N%bhWBtdQ$u18JnM2Q+q+cPl& zJCjw(OcS%lM%^60XKa?IyD!etbEVIO(Y$-FY$b~vr;@`5<`}IzPF9y=;X90|ukG3o zqFN$k{L2n^d>=ev;}ZwSnwCHxfYn?w)qd@?@8P32?BjL1gcr zC!z$+vZNuOp~oNhU}Udqz>U;A;U{}x0e5lPXC?e({qd#Z7|5nR88)w_WbYNv3cS$( z6q%fi>C0$m`WHC-c_L@9>Ih1L1t2L534WImrX*|hIa7nQdIz(JT1&x&UnN0uN=A!`PCs1W!U1Q#mf(<% zm-gD%OOJ!O1a(Z4G`Hupis2y(Iob4Oce5`XFm4I?aerObN>O4I{4#v{=CUERp(};d z#bgB$Itte8f2e)@S5<%i{vA`Jk7wN(OEc`6axMIR9z(kVsB;Wys&}TQwnXF}g-lw< z0X8M|sdo2kh=81(Ky>R+3ihGU5B$Lg(8V-*@yp0t#*h$;=>?9U_V*)W#3$2IAIzdh zdC5BRSJr%XJ!b3dy~lLsPT1@Wl<@LSEW&3qzP5$98M8o--Gs$UZDeJHNt zmuzsjB%Nz;pU2`Y`RC?99fXS+&Z)4d^Q33-llAhz(yRS#vQ?xHh!nN*?Ma?T%fo^9 z>skD>4ySA0zSNMehSY%rBM`%QhgG(rf|V_6bI0{SCU3`eHMr1Pu0|k}bvi!G&GK_k zcAu$fXc|}5>5u^cGnh-&^KFf;eucR5Z4HU5KGCg6A5B)vR)3+D3!u49huPcQUt7;c z?xtSQXcM`cNwJdrx$44E=0aS;!vwdh-_il~ms)GeDhWFYQubhY_TV?#-`mQXcHpnm zWt3M0FumxA*lj!fmDW!!)Z6=&D@#B)ha~tr;e_R=j6jzUgBcSlAD72zgs9VPmt8h| z(MjQO`H_(SFB#YM7gj9^9kY^sFJ{G7YUJOrF+XKvgQnB!$;!Pea1vB}R<-|fUsgL& z{z=vezr(W=_476z65>{cvfbd|z4R{dS4t+1ii4FTbBAYYd(cdZyEgS1wv{!UgYp?E zM$!~XR70EEAFUX}viu~L@LWs&m8{(loydkeOHrO3`RoRA%AS(7%?9V>-tb*vWm9*O z)zux%xNGP)JQmO$X4TCN$1b-#qu2pY3qdV7|e=%u{V$DQe~`#rAX)QGi_qDqK1k z6ppf?P<#!~^XfMT2l;b2H>EzS&e-i0VPMlz0e;Gfy4VAcHq&C*%m>ef{5FPHj|$a9 zmFtJ?(<(|z6LwY0 zz=PQby)P@M_Vij??CV`1lSM;(nWhTnfm72oWS>Ze4||b( zbpv!w^2}Ep`YGcXouiXdH?8Lq8finij+62~zyu>WD+dm~Jy(DJU`MG}2zVa+#E8=c z9Tn}3pS|3d)4${`C^L)Hqk5(T}58`(34$^7B>`E8LStx?rb>1ou0qAeHsGJ!4v z8gQVA-0XtjiuPY;vHskC%*js_fKej*(LfIJ94&HQ6~KOt8j%P5Yghsmh@j`ZoFG^F zm{atht&sn01Z#x-tC3?x^y^f55P+!qVb`DoNZdsTE*se#hXavlCPm2<9b~58c8t5C zlYY`jf+m^jFN*K7&jF+e$gT#eZ5b>5lpweuYfqrA_7awmuv1sMt`zHgm#qca47e@8 zA^6D@N@PYn&Z_a-V$&puOabIIw2s*opK6qys`CJetAXNkkC98S`hn6*7z?1|`{!3U zG-40E=)c+m6k4%N+3$c~fcMjHeh>Jl}F!<+6TH4vkB6L6)pRzJSNpCPi>ri8u#l@E$pB0r9= z!#!&q_Q19Te}>2fr9Q=V6P6b5)NW6kjz^S!M?6e=i^9PZuCtPgJi;CQBT$;&BQ?WG z1!-l)mJ_{F4iy;?l_vO?z3BJF6xpFyaSK9g6?4?m09y_JR^R*?=9A{L`QLYm-4m7? zpfs4S9ME`PmdNXU;z8`{b6ni#I%Oc{J>Z~?Y@x|=WelZI}-6nB+4RPpLah%ryqW97+} ztFMQX4YoD!JwHr+rsI1-CBHT&`_j=-?$gC`4PI5&gX{vt$Zbryyk3fe7_H6`u$hKN z+1$PA|2Q-AT$~-n9S*o7aDM^yB|xmnE;BRpH=yd0{6~xlP`HGb0Xj?%6aI+7WJRF? z9T*M;S-U$FQm@lr1JW>b;{t!g-_iiNI2Axg;9qYpZeI-lkPK8DTdw*mmz`>VRX^_y z&Ex=(Zv_gavQy1GuMl5hKpiSob365X=5N(7jX&c{UBD60j~b`|6gK$;tN~E`?*GM~ zMbtgV(vs$!pWv^ja}5$6#U6T1?)NYi3#-RsWS-~~q)Jzzf(pIU1edh29A4-9)090o zuoGc^WDfCeTJlzcfN~FT{4wpx+zZ^H{oY-X&3%TBgt?0ji#JJsf zA*lvF9Vq!CmF0EHzD(wR5ujT&WNGXfPbGOYE|@YHWb$A2-yDbo^TG2M zpce|4;0-T=06>qy5Qm}NV9404*w1GaoV!jhI|dZD)pQ(9bI8%-ypafJ~)ZHZgi=LW^}M)cMUD*t|e*vJHEOC#A{N@pHDHlYc>1tsw$kjtnrw!DwWEP6&QDbo{*aW zV1@!W|9^M4)&3rfS$`CTG+qI!gcNpw**f`;T!lYl7TEkF3-+(?fQ`X7=s$zD7Z5GF zru@(G{3iA*5L=;`1jbf~A)sk!{%2wQ_fo9??l$ZmVld^N4Ei(6tIzuv61E!2_+``{ zD9~53(1s>sT~9BH^PX57#1HfFkBUwyX4+WR-s(#U|I}FD%3(D;Pc`=xa{e`I>1fuUkrSv_BH|McFnkdM2&1$qNlgCiz0Z$np5qs`o~0r` zQ)JTx!y+~}(zxid4L-FS^_B^M=r5lkZ11DDT#brS{L{> zL}5)QNCCm+k^d~NMP@0|dGDc4{=qXc%^7||PI-Q4E?mXzDBomoyp-F(s}32gK{(T4 z@oqg61jm@^z3&yXaWxfS3k~@q%&+3BK^3=q+4rU~=im^ff`|Y!K<<7wRdd1b|EFj9 zU)iz$ufFqK?GSc2<7spk1es6Cw90pALT1_O9}t8?5c_2cDR>A_blsTG zCtw?GG2=#_rzycTdO9G9*bdU`Y*ZKOwc8>FG`ud72IfH##(gm$%^n;j};(bv@=EYEysdc@QivI6~b9O((3`H=?h$v zuG50TPkRF7UQ3(JpeFU^0NQ9F7^lhlm-g;-n0@UKFHhik;(!$?dT2akx#0$(_FZ4P zDd&Um{MxFbs@n9`yk{}%rH@b`4@V!3^ede#qz6-GW1L@P5dcOZh9CWo>uZ1LmHc(v zLB6c1Nh{(BS?7Q{L_)8>oX7i|eOVmoO+>&*hqjCW?GlrtAHH+g#^Hgeev$`4 z6#q<(P(PL^&6XnTlkIo(EmF7sB?QmazU=g7FOaL?*y0Ldo!&ItQ!tz72V_()-(67+J}hIO_& zCBVkypL!uJPwB+|3<56*R&IeX=qhBOIfe6krD!Ls(`+F|l9G0wCn>b&4 znLSQ34Qe=*;YBTn{5XoaBUNjcVs`e-hX=KA+;W!4imRzlv43}`dNc=S{ zZ2u0EvI?XSy!!Pty3xbpwI|alF?$*F1^bS{?|j(|7`Kht)ke1d8ohN4gkWR+7{>N9 zc9I7)Y-}gGmpp)Ql8=(rqVT0BLR1f@iwegiJ2%;t2kf(kFzP?Er`{KMd+V`fZ-^6+ z>L|@0yp6NILSx&z@5r~-%oOFe>u!umcqR>ohL(cgT+icXKkXPCaKuuGg9yh?2*S}J)2dzt(sJL$&P1-$=;N1&hTu(8wFT6b zzIorrP%4%R^RJQKI=A=-(ABz96{j&tQo5yg+RD1PADO@I>hij(q@gvovbz;<_C|Rw zUYIDh;F;okZTy~-ShvxQXg@!-p}UeS5MUjt8$sN zT&7C($7OTyvNS--hi`*2^+Kj00G=OcDcqHyDEn`qhyUZx+VH{H1T_kufU~Djv)4oj zJLv!sh2flzTg)-jI;c#(8VWLzGA{;_T0>2d65hH}9X1476~N2L-RN8QiGnYG^F|8F z&9>vvGAgS+at~*odY^<6H!=9KM=>as#WLsRX$$0)izFLsxcFo{|2-iHRHxFY)mIxd z_#I(W8N7QjeSZ7FnoGjuBZ%b1BKEW85@M-j*QAAXo6r-k;RgzW_aa|paJ`!|Sm zYf762MA6R4jkMCKv{^I!O6-sJmcEWxCjiPgzq9oVExtaP;a!+9C+-4BU5wHv=1vjb zZomDYYwISDV%m5=3!jl2bW<(vL)FhpTFEK}dtjQR*l9l;^~9C&3wD8bN9!w(%t*zO z4j)gydYR^I`=)lyDcg7Kc>VAKtr{mUxtlV@7w+CZ(@mPP40jqg$s_Ma0zr?%v;=?wrX-;X8{77jbbTejbIf5Sqt)MPLLGl%|kyL!le zDV&N@vhL&8Nate%=S~bz7UT~q&kh7j7&N`xZ_BjJps=&>xff1uf^-huK#l{y-!A zdCURR^4@cc!G%a~C)+jANi78yL$2`C@4`3AUMhWO19g&J=ez_A4o+^#EBNTjphfsh zz0h^IU;LBH5@$^lNupuGb=~jJo-EYuO?k46%bl|wlgwu*GwfvpJaoe_YjvOCL zX6feHwc8e`LZ>1x9=eW!*{oTp@_t|X=EZb^%yjd%ZAMz48R=A;juXT?<$kmI44a;T z{-P+N^Zqq?Hu+#Rn~moLCDBs%@L?fe#XFQ8X0(pa;#8}EdVZwE6gU;AzJl+_gt`nFAM9O9W zg9u^u(Uq5e^E9Me-;3+Aip}5@P7Tt*e0rEuS$_q~y7FVE>@1x5nR}M%x6^O?UuUASeZkaMk^-j!F%7$%;B4r!(Y3p>=4zabPxL4^q8-a;hA!O{FY*rVfVI|P zejuE>u+~%N1f?+XJbjU?#!{zi9cQzx@~Bmqrw79VEEvHHkDOUEOp^N4#oEqFb7LYd z2h$<1+IVVT4Vo+yie&s~wY7tc%tLVDv%|oQ8$acfmuJutR=3ifu#t>R8I_RtcQO9p zD}eW>cxU25aJZeqIIET~{dHI_7smm_@Ql9^%S;r&vkyKh6Mj3h{mtskmRSz?N-Q|r933U~$prcS$O?d72s`D`QLa)f5fqW`Zoi0JKAt0qu`DooJMoX0y>g8o zbBMilFNI8q+He_#<_>T*AcdO}|IEUB2zaP>Q|Vy~x&Wj`Lml9H<#la__Wq5Hy0K0} z!$e_2Be#<$a#S$KD*A$g2bY?d_E_35wAer&6UTD54y=#W2=sP?yJRMA#58z4i6hi_ zT*IZdj|#q#Hrz1D ze?(?=2K&ASHLiVzE@aYE%Er*E;K7bu&Ehh$8`azpErjU>Sqb;`R1Mu*PI4SR@`4Pc zeCt-ONEwdVLC1vuex;!x*#EX8#2q)cCy=lD81x9yk1S~j#>+f9MALsdaJcTY#j+eU zcjkW#t(rSN!~iGbCQus_eDhT^J)+g3Mm>JX_0}sDd54g`=oY~iM4M;neKZGVp<@Sx zo#^wtjc@c(dF4vN4L9_M2M0$$;bEoYM4VJS$Pjg=Z!9vwLI;Bq?Ma{ORB_8il2E!; zqX9+z6B{2u2v4_M1nn8=G0+x-lYbVazaWG<+ccO=*}7hv+u_PNV0Q!i z5p)2xo6C6QM`EbF?+v3LS^-C>2I|rXq}I;9|l^An&?X|LBv(i55cJc zFH>~-Ne{T-BYRkY+37ns1^#+_LSg+V>U}F!mle|DSQ6_qbpIw;CUtE}kz0USTb_;en&#UN%KHimD)rXqR0O0#q%KpqS@+&y zq}U#|&l-44Kdt&Q^Ut*U=j5^n{FrE0jvPv7MYt4Df|?)>&?x-JnkMVYkz1xtRr&Xv zlyzkTc4tV7PZ0mdD}C=RiLdIE34h~&8PkuiDDc6pDbgi09$$nj8CpbTs8&yC`0CH; z7)XXn&&NW`+Pkk#{Wj**R&hkNc4;_Gu&iO^Q47nMqnyf=;opYR~FTr&!+>rk;CN!9yF(Qht2)qZz%^ z%CMie=c9>dMDG#v$y+LrOy}+}r_SvjG7P82LceHw1QVaN#-yMZ_&>oO4QGOO0K*i2 z)G+O8R1gBrN{!Ym58a(=#p*HbEB(%f?9FH$ zI%|}-{7mjK+OSP9c2)C{0L=o)fD`XqHuZ2o^uqVvO|xmdl6f(A!Y}hT3!>f$CyCFtpCl@;MJ2{+g>mO;gg!}!x$cC zhTYqJ$I43pBiS;_9G1RZwf0t8|BYGZUli2CgsHde`YMCzA|Jn&^)@Fb9Q+ddoeTeC zaisylZGpdCVM=keOdFNIK|niCsg6I2DetUHHpG-_RFSc-9!+|I8vmk@IZVL#!nsIE zqx&Lj8JY$1;m!*Jg2Pj6)BbJH3!ef#?BntF0WNmS-jAd^UJkRjp(gC>`oT(@CJe2Z z%f0i+tFQd7Em!DZ>*~YRL#z)AA=JTCk+5rbt14;iQEN7m^M+U3Gzk{va0Qday6 zTq{>lTh%9Q*8JN{aHifj4BcV$M(7_{eEum^ul~ z=SQ|MZQG3Z%Ij+`YqCd&)<6WwBIHg}S%U7qv4SlLlR>pNW#qFNF|m`qalu1!B_Us2 zK~Bw9T3WE>9M(Dhx{lxmm;UQ~+7Ch^0c0I z@Tqz|+DELi4krF`#4K9=+AlhF2Wmq06T74K*D^sLR2J-9y+d^`3M4b+m>VS^Th*+f z?}P^&*QWXF6<+{$GEroz-oMo`qGgW%UJ5e6STQf zJo4s?E9JMhp+U*0kzSUg7y=w~*A~Vyj)HeTN8;y%$_DG;shgo#=xBihOOaWXF1egg zFV$R#Xsa~p;+03b5pr0d_}DMAym6rsiM)I%ANonyhLRG9d(y2LMGH$geL2wdfLAR3Qhd5TOZVP~+6GA%^dD zVi!1~AgcwBS84z@=*wn{woc%Q%n4)jq8oPVg)4|eA^S{B9|wpaD0yI$w%Q!KOa15c?{J~B8M5%%f9;?(;- zzI-6+dJj342Z->xU~xFiM}9KQ6+%1@BI;0f^<{}G+O9+bS4Bg3id;U^1Q}@n`o6#s zn-N!m+W(^rQj_k( z$b$ZRrR#VFpMqJO1|~4H8PGq2kcvTz>dHXN+XRdFR+-O0MZU|G7_`0yjHi;wm_J{| zW+eXvh-OQZV^kan0@;4%XEk7;OClgghQO)c48T~Wh>ZJ9H@Q-{hhgMN1~Ol+8gMu; zZj>QrKD3X(h$h(p4ed2xG~K}GPlu@9KrVO9?mo(kMmDLZO?>mY6Fut^Otc2Na9080 z^JnMh^#GoRxLyf3=(0$>jxLNKc(JTy374F3wu{84-a~vEfF(I0o7C!F&N{b@!cWkf z+V+sSEba%9NY{+@RUbgOu4_4`ROxMyrBb#3+BP z9u51so*pmC(Q2XHkV)a9=cc~hZWG+pn<2!gDu4l!L0|Um*dg_^5kvQmeasJ_7H#&r z>LN5q#&WtlUZk+wu&c*OS*sm-mT9|G6)M@f?82kRz__!WyJPu{oi(>=#Nky(zdM%g z4np|eb%>{N*;CV){k~nbr&&} z{&4@WME`SxSBwd9VngdAOYJ52nzA#8u~O2~Ldm`HE=sOY9$%#s$xPRrdonJ(pqcxe zx@wv0sLLfKR>}19{TE*|tf_g6{Mzt#&IMg&P4~>p=2Pw1v-=zBY2S zZV8@y?d>Azt{i1hR;!mBpwfBe+GfbeTKAb;ODx|(wx{U2=Js*+;+5!^i7|kvPWSh0 z{fTGE83(<}O)IhKY|9$UK;nKNN1%{DbCXi6z_7Yl?FEhtG9fpBoQt5tE8#q?UY4!r zFG$gFrXDNGLIKqz*z+AA^?5G(XUZdL?boxBy+HEQhZiHm%lZ}|b65!ue5)(aMtExo z;Le;!^$}vDbl}4~31`^(pZl*AR}(_{sS=!0Vop8rmLURpE$5OS2lopADNr)82|zBL zB_sRa@H=JM*Ohg(R0cUhEedWSkD8`nmc%(H@Dw6H%vv! zx-!i{*c!M+tf zyyMV>&zE_tSd)=60QQ_nNg$*cb93V_w70RU+E(kEd7n352P*s%rzcx-pT3TFym?r} zq1$gS5r3R5l=MN!2h8VTVDirD+cLptA>cbqSvdYwpz8j4&JPdh1jjmOFJY~_XRj2n z>sD}|y@JJXCjGp6a2}ATK9mY3Dr6JTYO320He~ay$h>j^Yf9#a7|i!iLARwsA(wg| zywlawimf^J0*4J}wn@SpPscRoXkJl8T;SBqf^Sh(rGvj}G-gr7l+47rJ_va}9$VeV zLX^SHqJ&?v??l?=2(U8TrdwQVNtmJQkXW{fv#PQ|MImkj&t-WzNz6~-j$qe|gG=_h z9Dy@_BqhmxNGrp*!vf?3@u%>;M7=W8DE&XWb6lYNLk$u*w6$6;cdRbw`Ls^znvHWV>A3tPw48$23~}6x5cdICC6=@rHB`OcSnw~Vc59@ zcYGOYe%oed{{0Kpuy#c9W;4;`jE(pb7x%3%b=u@9c5iT6Zs72QhGbKHhKjmAftERG z<%YAr@#54o%lEiqIk=Osmm^@j-JW9Rqw2t`w59-dQB4;Kyi;X)bEoMr|NUmA z+Y;*z?@N~!9ryCUi02=*p|9PRd3Ezvo_jwM2_m6e>E8D3z+UL}CygGW+tm!Op09li zI|}sNH0lN2qB+&l@63+59nYRp=zz~DrF1pp%s*hVLkL*2824p8;9g?K7kLkTO!OYG z5K3v03XubOPLxAnG_wYi?QMohwcX-2QpKQ0%be6%&rd!eqr2+;UJvf znzJ)=;Z^D>y(m&XsRp|J5Ownfl1jnvu#I43#dCuhLuoo8DMb|I>fYN>FF74UWz|a{ z-8@;y=WRx?VWO#!JHvj+I=E4fRlaD`&to$OGe|fc&VJXOMFZ4c_Y-`}=F_b3CaS$a z2`{9l746o6PwT5P;r=*#an~K$(Q1Xya0qa(!z2WQgQ}k3p}MdWufE~oP&`ae&hsQ) zT~`)D(2@#3NkU|th@5q1A2v_MSiyoe>0~2Kz#1C`%8sf*pR?Gx@`$YU?e1hoP{0`5 zaxu8PtpjhXYkHvt-5x~9&3}j-)JO2ee*Zox)y&2ca7$}5Ar=y_`e6u>R(A^hJXwI= z1AM7uJ%>+|xj+?hHt2J9j zaF0E_sXOThc^IFMWtB)&P|_M0Y8@zb1Z~1B$!#?)rUZV&k5boWgaQwylK!GtyN#9S z8P2?SN%AOr3zRR1_lO$ff7_YKGs}xKB%}z1#2Sh6p%;AlRI_f0YHe1tR_dA&hQXRr zxkNZ?wB|%dJS+D%Of#%*3*m3CMIrsC zFs$b#$za9aqp0xXoA4WFX>mR3brgae-g*glfCMkLY*RzY`lM3kzSzKG`9SCHlu7op z%JPmG!^DwG!EeW=8~fgfoesOy zGps`vzo1b$P~euI==txg76RmxdOxMyYl<{L9{<@O&HxC&F zyeeDW`rJb{Ca7j{u-1=+(dF}Bx-w0mUbPxka(LzZd?q&O+Vo}Q=UMty-1L5UVBu6W zW9s{sp-p4H{D7|dZ}K8gfe_xaEj+ALM~ zzbN$XbKWNhH9*-uxL9uADutNOlWzuzT%id?977=len<|ye!EkZS}Z(E8+@vbSoqSF|5`K_i?^z8P+jk1!>bwj0; zM6H0^Is$KQuj`>C*mjWgNVqUV+qE{k{0Hmqs~>uhE*+bb^$~2E3zAX%2G@dgzAjw@ zz}95F<{OhGvBSHs>f8zeA_z;oQcLxDb>q4UzkRr4ENYgj69hl96^+MvqAoUP zZY%@kh?TIlzFO*fc{Ptpf512BqbGz&gz8W$*Dmrdr}J+P>lMLkGP5x6Dw(CkOrB12 zvjAx0F?=*o!9x}u|7MSxcTCqY7Oc^`jn$`^o!^05z*PUVkcgK;e~rhw-u%@h?jIg7Vjs>+u5KQ z-pGtvTz%S$X~U^9WGVo;4(wU~%veZSD}=_^0nW>LGQqKcjV|3}oO%7&0+6u!wu!~P z%x7czt%|3$Mh04j`$Hlz)%(g?ouNljCeU7C7@4MYQC73PYj4n{kHe}7;?LB)2`i3k zqZ9Q&DaEeQhqLK|zV{+Z2P*A2G1Z7krNxUSXF|jm10&&mK@N?ewj;fc)sRJ3hK~&b zL*oUf_qvqS)k8=F((;P%C?&>$uTheb3_50!CmL2$^4XCDF{uF8Z(wrtdn}Gh`)$9& z8;E>NGw5j$*3F@gYTizjZ?nZqp@lokmNki-Z@>b&;6vrX5I;xa;3s=dq#@UCYV4v? z7(CEHPVhngnGcqyxp{@=ebbHvz3sN+t!`Ym`p>xL*i`h6@@=wzKJ(_096`r5iSVA! zyPy|6CShvU3pn64qqZsfLu%i)4$s)!&#n;f*71|?xNA_6e#V`CFIdOUp=W6TxGhfY z36$i90(w8Y_kKONV+l0j%N>8@MkXODrjSjt4XkR(Xa^MeA`tqpWI{_3Z#c}ie*5j| zgT*lcVH;2l`YeKbvGN50g}LnZW&#&aqmKIhJZFTfabD|bVK?Lpra-vAZmZ)hNs>`7Nv9;hHw=DF;Hbd*0#rqSw+@97_(1;m-EAuYfB*wHiVL~Us>O&kV$t3* zKv}z~{Fy1ZH-QAWqkN(*z_+7^R0saR^?X4#iIKUEM-Blh&I%hyAsFrk2yJwkueeUP ziNHp&deLN>Xxxb7sZ6YzG^Yn1@Sx(X$TcgEJR>2#2caW zfce`kuMZ#+tw^GMA%JI`#}S?}5NkFZ4y&Q$+cC@I?pX*K-{g84qV<`q7dz=2>WG2> z;f5^ec+Bn^ivo#wdOW0n28NE#{#A$LY@pwi>S%_x5F)-Qu$_`@;iO(vWd2bWWZZr3 zz?`g*HoN<3#0fOsF}Gb!O}_fu)0@2KiA>knrBgwh<6pqt>9K<146oq>Ywlsv6<>fP zeKo|~IzSLN+gvDi{A8|B8pu4j3#VRc9bLvYVuN+7_J~*J|Dqr;C*A;54kYU5&s2O- z%{hQ#uX1NuG&L#O5HP7mcEo-(zx|8Cl?F3y1Pf}oRtyx1!>(9Yj05yNGCl&t*vfkc zXR1sS4t8`kNH^ZgkXy>_&|H-=<^jl+t%mD_yrls80H4k2*y&Ev1z+W}Yu4^HA|(q7 zb^hDqypBxomE@8TF{d^q>5gU2+c2K>1Yv9t(b@4rk|G4Wp;#qP`T7zo3AzYFJNm-S za3P8At3x}bVC>B>#~X<%zXVs^b?=@XhCe-71;EwDgT)#NpPkT zl$_SX01>e%@arh-k$pgAC?&K4|AB#h8TDlsgfZS(d%G^$(0qg3nXjjDGAf>}+1YYX z(8qv1y(|E6i98*xDW0@3FVJw+$?9>Snev=uPU+aa6ayWm1&yK?UUZhnU~6;$wn6bz zT`PZsA>|YrX>aeJi-20UJ|axW-SAVN?E}j0)<%T(LbZ#a>9%UjeDt*HcWQB8H-zDKd5 zh)5Aoh=@`JqzeL35s)U*r3r`#p-S(>21t!`rG*wEB}9Z!Lz5D!Na&$SZw3-N35j?6 zyzd?7jPvE5bHCjCDSMBMy~oPV+H1`@|8xE(%d_Wh4~F*7T|2r%$1HP<97)#8(?z3| zXJ2Zl9lkIdBrQVi(hbu5J(|>TKSZcj9O~mX8!CU}`(``NV1XOYhNTnUJYh;uB^7Gj zRD@KP++$&{BzXNij{l2DxuT_C`1AN*{K=r!V-=CgV^=gsDll<;qZZ|f_&tv7v!}Q% z4}s>ABPfl5-9FvCg3_MYOzV+lpv%K0Ani2=o75cVjbuv@21y6YgR=s8r(#FEIAa8^ zz7^XT=QqDt^2I^mgo4^Lz4`vPoRm~*1DjhV?k37|Lkg%{-lO=Sv)UbI+|wq*vJ%Ng zNas7FNa(hzXC+xS0iEL0_#9d(8eAlfxhc+grpFh@t-5R9_Kd9#?_N+`E)TG@!IkKG3D4fkI78i@ z9%gDXn$9qr>x`;xGKnpqF7H*5PgYzT5_gkiJAkDc^v_)YYj4T|zu|tpZ8gESJ$GZE z<|CBfnuN1ka}!u9zbctNTaEBtEZUTfOaE2r5&!J`NXq%3-X}7i-+r-!QGT33!x06= zZXRwM3O-u}%<#_97mnN^w+`28fL`OpEx2LnVL_2e9???olk!=y19+eeLWDi}wQycq z)|Buuh3Cl&(RcEFZ*x~AWM02uW|7d|%_6bB zLRx_;sCCp@;}3(MJQ!cxL?lG|Zt3cT(F=MafAf#!VwFcM-kdA=kx@E%`;!YZ=ojcg{DGaW0=aYp> z%Rk79@w)42bF6*HKE9=OTuV{I?9d!;-a2;6ofAt#aNn5Q*W>M4eH>NwjRwg-pA#RM z@YsaVJUTBwMA0laGo(#p82y~c7EfkTlfgXwBgvSl%y-$ZoOdhi<=_N=L7Uc?+p@}e zlNteHBB=MP=6+J2cEtw9s??n&$fdrTIvSvA<@(9?L>VWteBCsw$~uU48@?7 z`Ohjm@bB&i1np4SpT~h=JYf_@s6d2|3&w8iZmqS;rQtvRfVO3`;*X46ZHL5D?T(}` z@P@Xa&yf3@Rn&AK5RhE)$3R^shuvE-&Uu}H3@<5;eWB<^-j!_e4>9ZNZ1yo98qH77&ydlV$sWH~ zi_JIF)NAxKK!@`}UBdLp9g5ix(;iWy5vBZH*Xr0;yNMA3lVQQ3%l&YtY=KC@0+^v_ zbM_g<6MkjyEJ%HOuvb54EOb1st$pLSXsa1Cc+*U9=}8vS8_(ZZeZKPiI)Yp9(~3t` z^`}I)5O{_vCf5VSRdzk4Gb6|C$bJ>(;k^7}a7wGy_*O;RB->-TtNs!J0mhn72n$KN z#2dC7ipoP@CoQcXeOb$qYUy0H`qY@BFZX=LG*N_+L1sfnQz`f}&2*sBV4yDt;_Z0M zcxQptJn2A?JL~-g?-j*%Gnnyt{3277(wVU@Mmr@GKg3n3PVRC6dlz}n&7Z^6xX+>i z(Jp>3^nTTkc`w!|Q|9twUFz;eL|A_4RF-wu+$zhbUows7HhA09F|fVhIK6zE{lA_i3$KB@8@dm4tdsOn+W+GO2I6Z z$_gb@j&C&AYUI-7Iq7bnA7@>2ePu(XP#y6j%Mb{UJ&V19 z>{Bk^Fm^id$as^T@_4@a;)kAsS{oBvXo}CRRu0}>W4YOZ`I$mZc+k z2RVTizj_DF^*eb5&0gVCi`ZL@83e?62VpjBU}dkB3IPI2l$ zq1!gE0)B;*OUoYyM!Dj?BHtKAL~{*-G!jGYZ|FjtYCNYOt9myQPAu7^Qk)k+eAv*_ zAVM`W{jkqw4|SpXb_fe>^$yS-4_3Q3mtn)!PJI-x1x`VaHBaL^eeN^b$%aMq*d{A87=5oKnE$rdIRJt7a(^9u+`fJS%`A;@I$Kp(P_XT zj4GxNw(bkjbO5WV{-4YG+a+A)nhqdMynrS-2|Zu|@;BK4mz-H)e&&!G1NabtXBJfy zSO}_-IM+L~MFTWl7L1ojz%Dupw3mADc1qG7a0J2MOLVB}M`|CToeyFA_KXyOPUUPz zvBI<{CQTdIfDcYjCZ~{GXRgxut>A~}r-Z0T4ima$$i1|(`cOE8S$_}37nMP;zfw)^^gm05lG`L~`*Z`B#W~!`i@+ z{!cAQx4GHnC>HADlWKw(WCtRfK74QYGqj^g)dGCUDs;Uhk!8O?HnO!23&5((fGYOV zY1g`YD=akzrA)@llEbVWw>NXox}t>bS5xJ^$5RnYXPUh z^n4>AoGgiGrGG6Aab$aR`EbO>rd=hzleD4rxPQEQ+Y#bRwLd6xnD8iA{R!VZGYKD# zv$X=U(JyX%`i+f0Nng9qcY3~B?wxFqcub0LJapW)b(@3HnV@Xr$5HxBhHXR>p?|YG z4}D$~8kOr$-kcN6O`ui0`V2U5u4ad(#xobOfk89aQC~(l#rYAc#AOQnyIj}Seu=sD z`Rkk)v8k$a`E{e$BAi%lo$y)@H8dO?uEO-~pR7IS+kUx2I^eo%)T$nm@J6s=j@oEx z(&RyPRyPa=U9^^WsH=nSBkZkJHlz75b-@mUfVVbLA9i-15j6kEcYv2Rd9KQw-@1!$ zcAHNc$=fW1^fXuX$IeXq;Zj9Od1+l&tB(YfGMfSs;7!Fs_?c&Xxv=4NWK0{rvm!Ka z=spv_pu3qPax^o{H^pU+?0dzsdrko?>-Fl?=7Ug{9geK}&ehmrmApia0FuezmI;)z z=yLNQ8Gb8FPCkEbeAtwIOx`!)u|Llbk4sifX5g%shrwC5!vn?Anr6?Y)qY?>2_5kx zg8D8mo0MYj=_Z~nU}_IjyLR(_=i2Eih=*@5OiWy^)}5|(rAa%yr`EJ2%rbSf1qN>f z3p{+r%ef^M*sVw%%L8#a2-Ku3Y|kI_6ZoZiH(Nyn?=li`WmqR+VN(8JUf3&cb!OFc zRxdx%gSA2vpML)PzIr)aaoaZTVBf%kKgdjyw0G!0dK}%n5cBH&ABH+$vTCn14vCT1 zR*g!8_Z*vz-zQH7OPd?Kn8^0~S$sLYY*ejjt1vVd+F2GBkklpiG+|af;gc=r!q3|^ zOGVC?K`Y-lW?y&SDIwqR=kx^1O{dlkdNaO>BiS=Q6#5>9*=5dem#N``c&kcW&h^)a zSVl|NODF~LIggYVe{hqq4sdb#0MND~xoKk0DBWViQoZ$Qsx?Ki*;PtFH*C4<+2PzV znwZ$CZJskdLG!Rxvu}{EmWaw=0WPbgSjyn4SOJUaxU$=z9Bhtb+!G>96aoV*fUBn8 z_DXHot)AbRzoK&qxfwDE(yn~ylNyofC@M0{+ZdA4Z)Kcv@^ycZ-jFQ?|Ab$}DWCm3 z(8uT^g>Rj-wN1=s863;3bRGa5oVy6tHG70<3E{_HS}`*PGC9}}kGM4tcs3)o>FHhT z!6A*|kI6O>k@M!^VEgD2ki76ZU}cGj^z4TRYo@EF1mS_Q4+h`Ae(wlSR`VadiW!;N zDRw!>(}&iCk0l$GKXN*Dn^_i#P>N=V%3nq)bnh3fa{FJ!f8B6cOTQV9VZ0ye!ZD=z z_8X8f24)TWp~^SxuM(RCNmKv}{eT1cCOo^FlKAwV=ne#rFGpdSza6;&c4F2pIT0uX${)YTS{;x!muAM z(oEPsJAGS3RegGOmar&LSB!+Kx#=(DihmVICk7C zsN!p$QcAuw44$I%X@U|xi-EnS-x~D)EE|Ztf8@6SY)UzaF8!&;OBJGapN5I{kU`83 z8+?>Ar|uB-F2ge4nyt7LHj=VN;QW>`A~|-1hhj(T($+%gZqr&`?uQhnfFl)?fG+98 zHSZFEKvc5g>1kB!oJd~6RnbVbkN0q@SYzfw3dvcp-2I;1xok-_zm?(XcB-{!9^{-X zqTohW>8Y^V(+#?W{j3wwZINLA#jD<92;hpyB9kjMq(K~UNcvU#f#O>l}u=N7_=A|F5R7AVbd=E zTt<*OZEMWwb@v#}xpZ1IUW@y!s}-s7Z4FE@T!^5L5;7nA@(ZF~%lqvhk<<1}ziJA? zrSz$F`F+FFxZmrj1yZ4TaEU*FA>bE^|9J0n_L~lHS_ig;=y~7i4_2u4Y`M+4+&K-t5wDQ_R2lB;%qHZlhIJtDB zcP?oc)vqQPmmL|qx!(vMbjiI|cAuv1X+uhwDmle=)bj2)yW_RxGSS=yiN&ZJ*;)n5 zh2cgmU%Iwk{lTP9Qg#@be%)P^;_fQ{$D$|iFP``O{^R~mS2GY8gA+0^%&(TYZzS|v z2$-M-Om6!u4QItupqDjycYmD1Uk1`|(ET&zj?fG%@gn=Sr{MgO^?|#juurLt2lcM_zjQ z<<>q8k9xaTGaDT^ASolTF+yMVJMQrd&uMRbRDtr#hT}7{&#Fa^tMF0OCfw@bs}`(B zTx8u(Kq?HV1JE!`_VaPuMWcIA zatyTh67+!8fCix%BDX5eIv(5v;J5a`_gnOcWEu3G>kUy*M<}{hr!e|Csi1WE?$Kq5ae%$~s?iH}b@eiNJmq?0ZHkm}MucZ6^&)^9x#w zYw5E)fNCpUc!M0v+>Bs8tCSf|}6kmvM=Owgx${RiQF{+?Zpa`s)e%z@|_3FV&9XJfCwzxo&sZnIADq>S48 z7wfpsvc8f!G_73u(Pil!G>I+ur&r2DTr%lnwYxN7`dAHax-2EKl-_gaFn@B@nOl4= z@xFit>e|ZKQtb>;=iQO<4DlRnGrg&J1o|R7Kmw`Poc{{w*&;{8?XQ6``ZNmE2z``G z!upc&#!{uZo8vIs?gzd>lKxYm zK_tR~i}}jE3QoSU7M(Efq?cfU>0Q>S$$TA znh3qhAVX=!dsawaSn5Xy^!`wnMXzdGqOGTYQ}aSW>c`{=9ixPh>S z%_VuH1wtV}3$2EelN>K;y&P*nuq;vDVQPt7w<^r1inu>_lS44#odRjhp|3&P$s@Pq+ArPkf|ut;dd z3qW8>C)n@eR&8EM{;r<|NUN^ky@@{zDD9bV`|rxz{LS~_z?l&($*8kwcb)m@8x@e3 zndQ^?R}G*JS~foD-}S%f>%feKLMcOJ>g|KOU^(m$l|@A)EeU)r#5aO&4z-b)mHb^@ zpkx$0It?cEW}gF))mlxPtAIuw@si|tL;-9%s2=$D=fiWfz*gw3CiG{L{+=aXK5-cl zN(NBf{lA(Hw*cjF!bk@=8wAeC9@K*&K!bE#(4_1}u5yEp$MHRHMck!cP#YrK%$^S7rt|F$_Ea)o8;CsCi;0^63;5rLb=B5<eZ%3I*2Uy*zTUUb)@U-=!OYsP|gxwPJ>5#vG0T zeNos1)N}E9&0M`{t5J2vABGztihlv*^DkhptW}!EFP{cen7zWT9k9%8GPCXVF|8mW z*YxF}kC!^by- zG@25>A#iAlKsVcPJ-$O)T!S|8^)K7xFe6TSBvc{y_3uys1M4NU3M?9)GDukZHn01l zD%vKHl!gA?Kd<=7@eyl$ZDK$Nn7lSxO-sg_%PZWBg>LrK8Ab_B<4r_ZH-K#4!!25r z)SAam|vHl zS$sB6gVTpKX`lJ+qf9ivE@7Tp=s0Cw`cb|;U7`GKW-pkeQo?eObgKr4Dd9-H+7UTCr}M&jUguhmX z9zjpy{y>=AOnB<`qu^KQv1Jm+a~-(cXP6KwRG}zD`KO!l;za$Q7`rMjhR-gZc~Pjz`s5zANn8<{su=CjX&2sD)6Rv zCz%Qi>?(fP`Yo|=n)+3dp0Xz#i`LdFtg@22fU%hZgvowtn6(I9sB<7dq0L*u{wGGB zFAuK^75$ohjQlV&j`0a-^Ip%<`ntB#NJ+$Pnlre$Z+W;W0VIqg;o86bl8E#|((+1< z`pjX!{xHP8P+mO=oz4c+MH>cWylIA)jKr>ayey*erlE#rV+tDKd2LATncNU3s#@sERrm&Xr?!CDx#F za9jO}mHQp!g}2cnXMiw}?Y|%EqXx*(Kiyj>{|#i_#aO&O`#-UqRb~eHXlnpu1|T}w zlmEHFzuUX~b36r*%m5(JJ8qz2GX8e^I{qX4)!pDHSKhAs2t*#o)ppM9k{-+KU_z(WupQ7?0IW4{GueoCl zjWd9evJM!!0mIf*S4Ii`3o!Q|L^<)h0IuL)&z~8<&jI+u42aYJfkr6ehmU5^H3T@B k|AkNR|JC_1VIY_05-`aB)4~7vP5p07{r{Ku1pgWTUtC+w#{d8T literal 0 HcmV?d00001 diff --git a/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/README.md b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/README.md new file mode 100644 index 0000000000000..56d14eb425c76 --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/README.md @@ -0,0 +1,42 @@ +# Holybro DroneCAN PMU + +https://holybro.com/products/dronecan-pm08-power-module-14s-200a + +## Features + +- Processor£ºSTM32F405RG 168MHz 1024KB Flash 196KB RAM +- Voltage input: 7~60.9V (2S~14S) +- Continuous current:200A +- Burst current 400A @ 25¡æ 1 sec£¬1000A @ 25¡æ < 1 sec +- Max current sensing: 376A +- Voltage accuracy: ¡À0.1V +- Current accuracy: ¡À5% +- Temperature accuracy:¡À1¡æ +- Power port output: 5.3V/3A each port +- Protocol: DroneCAN +- Operating temperature :-25¡æ~105¡æ +- Firmware upgrade: Support +- Calibration: Support + +## Interface Type + +- Power & CAN Port: Molex CLIK-Mate 2mm 6Pin +- Battery IN/OUT Options: + --XT90 Connectors + --Tinned Wires + --XT90 & Ring Terminals + +## Status LED + +- Flashing quickly continuously: MCU is in the bootloader stage, waiting for firmware to be flashed +- Flashing quickly for 3 seconds, and then on for 1 second: Waiting for CAN connection +- Flashing slowly (one-second intervals): CAN is successfully connected + +## Mechanical Spec + +- Size: 45mm¡Á41mm¡Á26mm (not include cable) +- Weight: 185g (include cable) + +## Loading Firmware + +You can upgrade the *.bin firmware files using the DroneCan GUI tool. *.apj files can also be upgraded using mossionplanner ground station. diff --git a/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/defaults.parm b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/defaults.parm new file mode 100644 index 0000000000000..20e564e87810e --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/defaults.parm @@ -0,0 +1,6 @@ +# Enable TSYS03 +TEMP1_TYPE 4 +TEMP1_SRC 3 +TEMP1_SRC_ID 1 + + diff --git a/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef-bl.dat b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef-bl.dat new file mode 100644 index 0000000000000..abdec0497edaa --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef-bl.dat @@ -0,0 +1,43 @@ +# hw definition file f405 Holybro CAN PMU + +# MCU class and specific type +MCU STM32F4xx STM32F405xx + +# crystal frequency +OSCILLATOR_HZ 16000000 + +# board ID for firmware load +APJ_BOARD_ID 5401 + +# setup build for a peripheral firmware +env AP_PERIPH 1 + +FLASH_RESERVE_START_KB 0 +FLASH_SIZE_KB 1024 +FLASH_BOOTLOADER_LOAD_KB 64 + +PB0 LED_BOOTLOADER OUTPUT LOW GPIO(0) # blue +define HAL_LED_ON 0 + +# debug +PA13 JTMS-SWDIO SWD +PA14 JTCK-SWCLK SWD + +# order of UARTs +SERIAL_ORDER USART3 + +PC10 USART3_TX USART3 +PC11 USART3_RX USART3 + +# enable CAN support +PA11 CAN1_RX CAN1 +PA12 CAN1_TX CAN1 +PA15 GPIO_CAN1_SILENT OUTPUT PUSHPULL SPEED_LOW LOW + +define HAL_USE_CAN TRUE +define STM32_CAN_USE_CAN1 TRUE + +define CAN_APP_NODE_NAME "org.ardupilot.f405_HolybroPMU" + + +# Add CS pins to ensure they are high in bootloader diff --git a/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef.dat b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef.dat new file mode 100644 index 0000000000000..5373728eb07f1 --- /dev/null +++ b/libraries/AP_HAL_ChibiOS/hwdef/HolybroF4_PMU/hwdef.dat @@ -0,0 +1,114 @@ +# hw definition file for f405 Holybro CAN PMU + +# MCU class and specific type +MCU STM32F4xx STM32F405xx + +# bootloader starts firmware at 64k +FLASH_RESERVE_START_KB 64 +FLASH_SIZE_KB 1024 + +# store parameters in pages 2 and 3 +STORAGE_FLASH_PAGE 2 +define HAL_STORAGE_SIZE 15360 + +# board ID for firmware load +APJ_BOARD_ID 5401 + +env AP_PERIPH 1 + +define STM32_ST_USE_TIMER 5 +define CH_CFG_ST_RESOLUTION 32 + +# enable watchdog + +# crystal frequency +OSCILLATOR_HZ 16000000 + +STDOUT_SERIAL SD3 +STDOUT_BAUDRATE 57600 + +# blue LED0 marked as ACT +PB0 LED OUTPUT HIGH GPIO(90) +define AP_NOTIFY_GPIO_LED_1_ENABLED 1 +define AP_NOTIFY_GPIO_LED_1_PIN 90 + +define HAL_NO_GPIO_IRQ +define SERIAL_BUFFERS_SIZE 512 +define PORT_INT_REQUIRED_STACK 64 + +# debug +PA13 JTMS-SWDIO SWD +PA14 JTCK-SWCLK SWD + +# avoid timer and RCIN threads to save memory +define HAL_NO_RCIN_THREAD + +define HAL_USE_RTC FALSE +define DISABLE_SERIAL_ESC_COMM TRUE + +define DMA_RESERVE_SIZE 0 + +define HAL_DEVICE_THREAD_STACK 768 + +# we setup a small defaults.parm +define AP_PARAM_MAX_EMBEDDED_PARAM 256 + +# keep ROMFS uncompressed as we don't have enough RAM +# to uncompress the bootloader at runtime +env ROMFS_UNCOMPRESSED True + +# ---------------------- CAN bus ------------------------- +PA11 CAN1_RX CAN1 +PA12 CAN1_TX CAN1 +PA15 GPIO_CAN1_SILENT OUTPUT PUSHPULL SPEED_LOW LOW + +# use DNA for node allocation + +define CAN_APP_NODE_NAME "org.ardupilot.f405_HolybroPMU" + + +# ---------------------- UARTs --------------------------- +# +SERIAL_ORDER USART3 + +# USART3, for debug +PC10 USART3_TX USART3 SPEED_HIGH NODMA +PC11 USART3_RX USART3 SPEED_HIGH NODMA + +# ---------------------- I2Cs --------------------------- +# +I2C_ORDER I2C1 + +# I2C2, for TEMP SENSOR +PB8 I2C1_SCL I2C1 +PB9 I2C1_SDA I2C1 + +# ------------------ BATTERY Monitor ----------------------- +define HAL_PERIPH_ENABLE_BATTERY +define HAL_PERIPH_ENABLE_DEVICE_TEMPERATURE +define HAL_USE_ADC TRUE +define STM32_ADC_USE_ADC1 TRUE + +PC0 BATT_VOLTAGE_SENS ADC1 SCALE(1) +PC1 BATT_CURRENT_SENS ADC1 SCALE(1) + +# Set the Default Battery Monitor Type to be Analog I/V +define HAL_BATT_MONITOR_DEFAULT 4 + +define HAL_BATT_VOLT_PIN 10 +define HAL_BATT_VOLT_SCALE 18.0 + +define HAL_BATT_CURR_PIN 11 +define HAL_BATT_CURR_SCALE 125 + +# ACS772-400U Zero-Current Offset +define AP_BATT_CURR_AMP_OFFSET_DEFAULT 0.409 + +# ------------------ Temperature Sensor ----------------------- +define AP_TEMPERATURE_SENSOR_ENABLED 1 +define AP_TEMPERATURE_SENSOR_TSYS03_ENABLED 1 +define AP_TEMPERATURE_SENSOR_I2C_ADDR_DEFAULT 64 +define AP_TEMPERATURE_SENSOR_I2C_BUS_DEFAULT 0 + + + From 2675e293edabeead251c96e260217b4a06e77a4f Mon Sep 17 00:00:00 2001 From: jamming Date: Wed, 4 Sep 2024 10:19:37 +1000 Subject: [PATCH 009/463] bootloaders: Add a new target Holybro DroneCAN-pmu --- Tools/bootloaders/HolybroF4_PMU_bl.bin | Bin 0 -> 19308 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 Tools/bootloaders/HolybroF4_PMU_bl.bin diff --git a/Tools/bootloaders/HolybroF4_PMU_bl.bin b/Tools/bootloaders/HolybroF4_PMU_bl.bin new file mode 100755 index 0000000000000000000000000000000000000000..76803ecc545c872a6dca813d7a9d67f71b0b19b3 GIT binary patch literal 19308 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 T@f&R@gFqKx4e`|Qd%^z#bSoDp literal 0 HcmV?d00001 From 2bb6846d4773c6457046f82a078636ea4aa9afd4 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 18:35:16 +1000 Subject: [PATCH 010/463] AP_NavEKF2: stop including AP_DAL.h in header it's not needed and will slow compilation down --- libraries/AP_NavEKF2/AP_NavEKF2.cpp | 5 +++-- libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp | 7 +++---- libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp | 8 +++----- libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp | 5 +---- libraries/AP_NavEKF2/AP_NavEKF2_core.cpp | 6 ++++-- libraries/AP_NavEKF2/AP_NavEKF2_core.h | 5 +++-- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/libraries/AP_NavEKF2/AP_NavEKF2.cpp b/libraries/AP_NavEKF2/AP_NavEKF2.cpp index 3e6c4e80af324..01ecc7df9b33c 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2.cpp @@ -1,6 +1,7 @@ -#include - #include "AP_NavEKF2_core.h" + +#include +#include #include #include #include diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp index 3e8476963f102..929c0edd37b50 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_AirDataFusion.cpp @@ -1,9 +1,8 @@ -#include - -#include "AP_NavEKF2.h" #include "AP_NavEKF2_core.h" -extern const AP_HAL::HAL& hal; +#include + +#include "AP_NavEKF2.h" /******************************************************** * RESET FUNCTIONS * diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp index 459d3de3983a3..ed19bd078ffba 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_Control.cpp @@ -1,11 +1,9 @@ -#include - -#include "AP_NavEKF2.h" #include "AP_NavEKF2_core.h" -#include -extern const AP_HAL::HAL& hal; +#include +#include +#include "AP_NavEKF2.h" // Control filter mode transitions void NavEKF2_core::controlFilterModes() diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp index 2336c522db9d2..8653ad4a7e58c 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp @@ -1,9 +1,6 @@ -#include - #include "AP_NavEKF2_core.h" -extern const AP_HAL::HAL& hal; - +#include /* Monitor GPS data to see if quality is good enough to initialise the EKF Monitor magnetometer innovations to see if the heading is good enough to use GPS diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_core.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_core.cpp index caf78f8745631..08d59b42a2ba6 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_core.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_core.cpp @@ -1,8 +1,10 @@ +#include "AP_NavEKF2_core.h" + #include +#include +#include #include "AP_NavEKF2.h" -#include "AP_NavEKF2_core.h" -#include extern const AP_HAL::HAL& hal; diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_core.h b/libraries/AP_NavEKF2/AP_NavEKF2_core.h index fcb48be5ccb1f..0dc9c6881908f 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_core.h +++ b/libraries/AP_NavEKF2/AP_NavEKF2_core.h @@ -29,7 +29,8 @@ #include #include #include -#include +#include +#include #include "AP_NavEKF/EKFGSF_yaw.h" @@ -341,7 +342,7 @@ class NavEKF2_core : public NavEKF_core_common private: EKFGSF_yaw *yawEstimator; - AP_DAL &dal; + class AP_DAL &dal; // Reference to the global EKF frontend for parameters class NavEKF2 *frontend; From 89c9b186e2b3f94bc0ccc1c8202025381bef4737 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 17:45:57 +1000 Subject: [PATCH 011/463] AP_Camera: add missing include for AP_AHRS We use this library's singleton --- libraries/AP_Camera/AP_Camera_Logging.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/AP_Camera/AP_Camera_Logging.cpp b/libraries/AP_Camera/AP_Camera_Logging.cpp index 08da836d21217..47cc479895294 100644 --- a/libraries/AP_Camera/AP_Camera_Logging.cpp +++ b/libraries/AP_Camera/AP_Camera_Logging.cpp @@ -6,6 +6,7 @@ #include #include +#include // Write a Camera packet. Also writes a Mount packet if available void AP_Camera_Backend::Write_CameraInfo(enum LogMessages msg, uint64_t timestamp_us) From b5cd3370eb27330151ab7b8c60215ea60234dc0b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 17:45:57 +1000 Subject: [PATCH 012/463] AP_InertialSensor: add missing include for AHRS we use a method from this library --- libraries/AP_InertialSensor/AP_InertialSensor_Logging.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/AP_InertialSensor/AP_InertialSensor_Logging.cpp b/libraries/AP_InertialSensor/AP_InertialSensor_Logging.cpp index 4fa6c6ba64118..fa71deadd954c 100644 --- a/libraries/AP_InertialSensor/AP_InertialSensor_Logging.cpp +++ b/libraries/AP_InertialSensor/AP_InertialSensor_Logging.cpp @@ -5,6 +5,7 @@ #include "AP_InertialSensor.h" #include "AP_InertialSensor_Backend.h" +#include #include // Write ACC data packet: raw accel data From 8b8307c132a1de18974fe881afb58aa577a76fb1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 18:21:22 +1000 Subject: [PATCH 013/463] AP_NavEKF2: correct includes --- libraries/AP_NavEKF2/AP_NavEKF2.cpp | 2 ++ libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp | 7 +++---- libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp | 2 ++ libraries/AP_NavEKF2/LogStructure.h | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/AP_NavEKF2/AP_NavEKF2.cpp b/libraries/AP_NavEKF2/AP_NavEKF2.cpp index 01ecc7df9b33c..dfd2aa7b6d3ab 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2.cpp @@ -1,3 +1,5 @@ +#include "AP_NavEKF2.h" + #include "AP_NavEKF2_core.h" #include diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp index 009a59f358a25..cdd25bc13383c 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_Measurements.cpp @@ -1,14 +1,13 @@ -#include - #include "AP_NavEKF2_core.h" + +#include "AP_NavEKF2.h" + #include #include #include #if AP_RANGEFINDER_ENABLED -extern const AP_HAL::HAL& hal; - /******************************************************** * OPT FLOW AND RANGE FINDER * diff --git a/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp b/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp index 8653ad4a7e58c..859930bdd01de 100644 --- a/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp +++ b/libraries/AP_NavEKF2/AP_NavEKF2_VehicleStatus.cpp @@ -1,5 +1,7 @@ #include "AP_NavEKF2_core.h" +#include "AP_NavEKF2.h" + #include /* Monitor GPS data to see if quality is good enough to initialise the EKF diff --git a/libraries/AP_NavEKF2/LogStructure.h b/libraries/AP_NavEKF2/LogStructure.h index 753d9ceb0f4b3..a7f1a8862557e 100644 --- a/libraries/AP_NavEKF2/LogStructure.h +++ b/libraries/AP_NavEKF2/LogStructure.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #define LOG_IDS_FROM_NAVEKF2 \ LOG_NKF0_MSG, \ From 33f95138541594675023288bace0dacb4d9a18d2 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 18:21:33 +1000 Subject: [PATCH 014/463] AP_NavEKF3: correct includes --- libraries/AP_NavEKF3/AP_NavEKF3.cpp | 2 ++ libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp | 5 +++-- libraries/AP_NavEKF3/AP_NavEKF3_VehicleStatus.cpp | 5 +++-- libraries/AP_NavEKF3/AP_NavEKF3_core.h | 2 +- libraries/AP_NavEKF3/LogStructure.h | 1 + 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libraries/AP_NavEKF3/AP_NavEKF3.cpp b/libraries/AP_NavEKF3/AP_NavEKF3.cpp index fbf4796a6785d..e3a8433b9ce2e 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3.cpp @@ -1,3 +1,5 @@ +#include "AP_NavEKF3.h" + #include #include "AP_NavEKF3_core.h" diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp b/libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp index 070e1f6460e1d..9e1eab32eb29d 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3_Measurements.cpp @@ -1,6 +1,7 @@ -#include - #include "AP_NavEKF3_core.h" + +#include "AP_NavEKF3.h" + #include #include #include diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_VehicleStatus.cpp b/libraries/AP_NavEKF3/AP_NavEKF3_VehicleStatus.cpp index 3e5651b43b5ba..3fd1c80e2bf5c 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_VehicleStatus.cpp +++ b/libraries/AP_NavEKF3/AP_NavEKF3_VehicleStatus.cpp @@ -1,6 +1,7 @@ -#include - #include "AP_NavEKF3_core.h" + +#include "AP_NavEKF3.h" + #include /* Monitor GPS data to see if quality is good enough to initialise the EKF diff --git a/libraries/AP_NavEKF3/AP_NavEKF3_core.h b/libraries/AP_NavEKF3/AP_NavEKF3_core.h index c7bef11e76c37..ee4d17a6f5c51 100644 --- a/libraries/AP_NavEKF3/AP_NavEKF3_core.h +++ b/libraries/AP_NavEKF3/AP_NavEKF3_core.h @@ -128,7 +128,7 @@ class NavEKF3_core : public NavEKF_core_common { public: // Constructor - NavEKF3_core(class NavEKF3 *_frontend, AP_DAL &dal); + NavEKF3_core(class NavEKF3 *_frontend, class AP_DAL &dal); // setup this core backend bool setup_core(uint8_t _imu_index, uint8_t _core_index); diff --git a/libraries/AP_NavEKF3/LogStructure.h b/libraries/AP_NavEKF3/LogStructure.h index a5629ea3f3f6e..9218c6d60bf84 100644 --- a/libraries/AP_NavEKF3/LogStructure.h +++ b/libraries/AP_NavEKF3/LogStructure.h @@ -1,6 +1,7 @@ #pragma once #include +#include #define LOG_IDS_FROM_NAVEKF3 \ LOG_XKF0_MSG, \ From b3c1cd1a5e71151422429dedca81cd507b4cce4b Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 30 Aug 2024 18:29:29 +1000 Subject: [PATCH 015/463] APM_Control: add missing include for AP::ins() --- libraries/APM_Control/AP_AutoTune.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/APM_Control/AP_AutoTune.cpp b/libraries/APM_Control/AP_AutoTune.cpp index 64d5fab2ee831..24a8611bacf58 100644 --- a/libraries/APM_Control/AP_AutoTune.cpp +++ b/libraries/APM_Control/AP_AutoTune.cpp @@ -28,6 +28,7 @@ #include #include #include +#include extern const AP_HAL::HAL& hal; From 35d0f5c104f618f8108c4c1f5722942fb69a5041 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 31 Aug 2024 07:34:29 +1000 Subject: [PATCH 016/463] AP_DAL: add missing include file for Replay build --- libraries/AP_DAL/examples/AP_DAL_Standalone/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/AP_DAL/examples/AP_DAL_Standalone/main.cpp b/libraries/AP_DAL/examples/AP_DAL_Standalone/main.cpp index 6a9371ada0b73..16e02dfadd9e6 100644 --- a/libraries/AP_DAL/examples/AP_DAL_Standalone/main.cpp +++ b/libraries/AP_DAL/examples/AP_DAL_Standalone/main.cpp @@ -4,6 +4,7 @@ // #include +#include #include #include From 690947537ab25f79700b112297ed3d01c2b00406 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 31 Aug 2024 08:11:37 +1000 Subject: [PATCH 017/463] AP_HAL: examples: add missing include for AP_InertialSensor we instantiate this library in here --- libraries/AP_HAL/examples/DSP_test/DSP_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/AP_HAL/examples/DSP_test/DSP_test.cpp b/libraries/AP_HAL/examples/DSP_test/DSP_test.cpp index 23e079f23ead8..78737f12a846f 100644 --- a/libraries/AP_HAL/examples/DSP_test/DSP_test.cpp +++ b/libraries/AP_HAL/examples/DSP_test/DSP_test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "GyroFrame.h" #if HAL_WITH_DSP From adcf5d35035844bef0b0488de0b875612d0091c6 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 3 Sep 2024 14:00:12 +1000 Subject: [PATCH 018/463] Tools: Do a CubeOrange build with EKF2 as part of CI need to build at least one ChibiOS-based board to be sure we haven't killed things --- .github/workflows/test_chibios.yml | 1 + Tools/scripts/build_ci.sh | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/.github/workflows/test_chibios.yml b/.github/workflows/test_chibios.yml index 57fc94a44863b..08e3381e350f5 100644 --- a/.github/workflows/test_chibios.yml +++ b/.github/workflows/test_chibios.yml @@ -156,6 +156,7 @@ jobs: build-options-defaults-test, signing, CubeOrange-PPP, + CubeOrange-EKF2, SOHW, Pixhawk6X-PPPGW, new-check, diff --git a/Tools/scripts/build_ci.sh b/Tools/scripts/build_ci.sh index e62b133914321..1513e9cbe3f8b 100755 --- a/Tools/scripts/build_ci.sh +++ b/Tools/scripts/build_ci.sh @@ -327,6 +327,14 @@ for t in $CI_BUILD_TARGET; do continue fi + if [ "$t" == "CubeOrange-EKF2" ]; then + echo "Building CubeOrange with EKF2 enabled" + $waf configure --board CubeOrange --enable-ekf2 + $waf clean + $waf copter + continue + fi + if [ "$t" == "SOHW" ]; then echo "Building CubeOrange-SOHW" Tools/scripts/sitl-on-hardware/sitl-on-hw.py --board CubeOrange --vehicle copter --simclass MultiCopter From c05441b9592b1b42d2e0e0afb4be507f5ad37c33 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 27 Aug 2024 13:12:15 +1000 Subject: [PATCH 019/463] AP_DDS: remove instance check for DDS Client this is probably a flow of control problem. But the code block below this resets some state variables before returning, and will also return false in the same case this removed block does. Resetting that state might be very important to the caller. --- libraries/AP_DDS/AP_DDS_Client.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/AP_DDS/AP_DDS_Client.cpp b/libraries/AP_DDS/AP_DDS_Client.cpp index eb54a54eff09f..41d71b35a2c56 100644 --- a/libraries/AP_DDS/AP_DDS_Client.cpp +++ b/libraries/AP_DDS/AP_DDS_Client.cpp @@ -123,11 +123,6 @@ bool AP_DDS_Client::update_topic(sensor_msgs_msg_NavSatFix& msg, const uint8_t i // https://www.fluentcpp.com/2021/12/13/the-evolutions-of-lambdas-in-c14-c17-and-c20/ // constexpr auto times2 = [] (sensor_msgs_msg_NavSatFix* msg) { return n * 2; }; - // assert(instance >= GPS_MAX_RECEIVERS); - if (instance >= GPS_MAX_RECEIVERS) { - return false; - } - auto &gps = AP::gps(); WITH_SEMAPHORE(gps.get_semaphore()); From 76c43f1f825fd343e58c21f858d88155d754de01 Mon Sep 17 00:00:00 2001 From: muramura Date: Wed, 19 Jun 2024 22:13:47 +0900 Subject: [PATCH 020/463] Rover: Make the definition name a class type --- Rover/defines.h | 10 +++++----- Rover/mode.cpp | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Rover/defines.h b/Rover/defines.h index 150afba023eba..0db0a92ba3b6e 100644 --- a/Rover/defines.h +++ b/Rover/defines.h @@ -80,11 +80,11 @@ enum fs_ekf_action { #define DISTANCE_HOME_MINCHANGE 0.5f // minimum distance to adjust home location -enum pilot_steer_type_t { - PILOT_STEER_TYPE_DEFAULT = 0, - PILOT_STEER_TYPE_TWO_PADDLES = 1, - PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING = 2, - PILOT_STEER_TYPE_DIR_UNCHANGED_WHEN_REVERSING = 3, +enum class PilotSteerType : uint8_t { + DEFAULT = 0, + TWO_PADDLES = 1, + DIR_REVERSED_WHEN_REVERSING = 2, + DIR_UNCHANGED_WHEN_REVERSING = 3, }; // frame class enum used for FRAME_CLASS parameter diff --git a/Rover/mode.cpp b/Rover/mode.cpp index 2b626ca4bb38c..ee1a533e11c23 100644 --- a/Rover/mode.cpp +++ b/Rover/mode.cpp @@ -67,10 +67,10 @@ void Mode::get_pilot_input(float &steering_out, float &throttle_out) const } // apply RC skid steer mixing - switch ((enum pilot_steer_type_t)g.pilot_steer_type.get()) + switch ((PilotSteerType)g.pilot_steer_type.get()) { - case PILOT_STEER_TYPE_DEFAULT: - case PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING: + case PilotSteerType::DEFAULT: + case PilotSteerType::DIR_REVERSED_WHEN_REVERSING: default: { // by default regular and skid-steering vehicles reverse their rotation direction when backing up throttle_out = rover.channel_throttle->get_control_in(); @@ -79,7 +79,7 @@ void Mode::get_pilot_input(float &steering_out, float &throttle_out) const break; } - case PILOT_STEER_TYPE_TWO_PADDLES: { + case PilotSteerType::TWO_PADDLES: { // convert the two radio_in values from skid steering values // left paddle from steering input channel, right paddle from throttle input channel // steering = left-paddle - right-paddle @@ -92,7 +92,7 @@ void Mode::get_pilot_input(float &steering_out, float &throttle_out) const break; } - case PILOT_STEER_TYPE_DIR_UNCHANGED_WHEN_REVERSING: { + case PilotSteerType::DIR_UNCHANGED_WHEN_REVERSING: { throttle_out = rover.channel_throttle->get_control_in(); steering_out = rover.channel_steer->get_control_in(); break; @@ -123,8 +123,8 @@ void Mode::get_pilot_desired_steering_and_throttle(float &steering_out, float &t // check for special case of input and output throttle being in opposite directions float throttle_out_limited = g2.motors.get_slew_limited_throttle(throttle_out, rover.G_Dt); if ((is_negative(throttle_out) != is_negative(throttle_out_limited)) && - ((g.pilot_steer_type == PILOT_STEER_TYPE_DEFAULT) || - (g.pilot_steer_type == PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING))) { + ((PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DEFAULT) || + (PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DIR_REVERSED_WHEN_REVERSING))) { steering_out *= -1; } throttle_out = throttle_out_limited; @@ -139,8 +139,8 @@ void Mode::get_pilot_desired_steering_and_speed(float &steering_out, float &spee // check for special case of input and output throttle being in opposite directions float speed_out_limited = g2.attitude_control.get_desired_speed_accel_limited(speed_out, rover.G_Dt); if ((is_negative(speed_out) != is_negative(speed_out_limited)) && - ((g.pilot_steer_type == PILOT_STEER_TYPE_DEFAULT) || - (g.pilot_steer_type == PILOT_STEER_TYPE_DIR_REVERSED_WHEN_REVERSING))) { + ((PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DEFAULT) || + (PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DIR_REVERSED_WHEN_REVERSING))) { steering_out *= -1; } speed_out = speed_out_limited; @@ -167,7 +167,7 @@ void Mode::get_pilot_desired_heading_and_speed(float &heading_out, float &speed_ float desired_throttle = constrain_float(rover.channel_throttle->norm_input_dz(), -1.0f, 1.0f); // handle two paddle input - if ((enum pilot_steer_type_t)g.pilot_steer_type.get() == PILOT_STEER_TYPE_TWO_PADDLES) { + if ((PilotSteerType)g.pilot_steer_type.get() == PilotSteerType::TWO_PADDLES) { const float left_paddle = desired_steering; const float right_paddle = desired_throttle; desired_steering = (left_paddle - right_paddle) * 0.5f; From 10991589a7e46d50b4dfbe72683f67e60d8941c1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 16:33:06 +1000 Subject: [PATCH 021/463] Rover: use AP_Enum for pilot_steer_type --- Rover/Parameters.h | 2 +- Rover/mode.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Rover/Parameters.h b/Rover/Parameters.h index 8a19324bfaf9f..ff8d29c38b369 100644 --- a/Rover/Parameters.h +++ b/Rover/Parameters.h @@ -257,7 +257,7 @@ class Parameters { // Throttle // AP_Int8 throttle_cruise; - AP_Int8 pilot_steer_type; + AP_Enum pilot_steer_type; // failsafe control AP_Int8 fs_action; diff --git a/Rover/mode.cpp b/Rover/mode.cpp index ee1a533e11c23..ae858691ea33f 100644 --- a/Rover/mode.cpp +++ b/Rover/mode.cpp @@ -123,8 +123,8 @@ void Mode::get_pilot_desired_steering_and_throttle(float &steering_out, float &t // check for special case of input and output throttle being in opposite directions float throttle_out_limited = g2.motors.get_slew_limited_throttle(throttle_out, rover.G_Dt); if ((is_negative(throttle_out) != is_negative(throttle_out_limited)) && - ((PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DEFAULT) || - (PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DIR_REVERSED_WHEN_REVERSING))) { + (g.pilot_steer_type == PilotSteerType::DEFAULT || + g.pilot_steer_type == PilotSteerType::DIR_REVERSED_WHEN_REVERSING)) { steering_out *= -1; } throttle_out = throttle_out_limited; @@ -139,8 +139,8 @@ void Mode::get_pilot_desired_steering_and_speed(float &steering_out, float &spee // check for special case of input and output throttle being in opposite directions float speed_out_limited = g2.attitude_control.get_desired_speed_accel_limited(speed_out, rover.G_Dt); if ((is_negative(speed_out) != is_negative(speed_out_limited)) && - ((PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DEFAULT) || - (PilotSteerType(g.pilot_steer_type.get()) == PilotSteerType::DIR_REVERSED_WHEN_REVERSING))) { + (g.pilot_steer_type == PilotSteerType::DEFAULT || + g.pilot_steer_type == PilotSteerType::DIR_REVERSED_WHEN_REVERSING)) { steering_out *= -1; } speed_out = speed_out_limited; @@ -167,7 +167,7 @@ void Mode::get_pilot_desired_heading_and_speed(float &heading_out, float &speed_ float desired_throttle = constrain_float(rover.channel_throttle->norm_input_dz(), -1.0f, 1.0f); // handle two paddle input - if ((PilotSteerType)g.pilot_steer_type.get() == PilotSteerType::TWO_PADDLES) { + if (g.pilot_steer_type == PilotSteerType::TWO_PADDLES) { const float left_paddle = desired_steering; const float right_paddle = desired_throttle; desired_steering = (left_paddle - right_paddle) * 0.5f; From 792941d4de1cad4da93fc164e814e7394948e06e Mon Sep 17 00:00:00 2001 From: David 'Buzz' Bussenschutt Date: Fri, 6 Sep 2024 09:43:27 +1000 Subject: [PATCH 022/463] AP_HAL_ESP32: bigger instruction cache on s3 helps performance --- libraries/AP_HAL_ESP32/targets/esp32s3/esp-idf/sdkconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/AP_HAL_ESP32/targets/esp32s3/esp-idf/sdkconfig b/libraries/AP_HAL_ESP32/targets/esp32s3/esp-idf/sdkconfig index 0ab73700f0deb..72986234fa42e 100644 --- a/libraries/AP_HAL_ESP32/targets/esp32s3/esp-idf/sdkconfig +++ b/libraries/AP_HAL_ESP32/targets/esp32s3/esp-idf/sdkconfig @@ -252,13 +252,12 @@ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 # # Cache config # -CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y -# CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 +# CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB is not set +CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y +CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x8000 # CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS is not set CONFIG_ESP32S3_INSTRUCTION_CACHE_8WAYS=y CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B is not set CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32 # CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP is not set From bbdbf33c218414068cfc21b50ab4d62e20e84ac3 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 4 Sep 2024 21:02:52 +1000 Subject: [PATCH 023/463] Tools: param_metadata: do not emit Legacy fields to rst/Wiki --- Tools/autotest/param_metadata/ednemit.py | 3 +++ Tools/autotest/param_metadata/emit.py | 3 +++ Tools/autotest/param_metadata/htmlemit.py | 2 ++ Tools/autotest/param_metadata/jsonemit.py | 3 +++ Tools/autotest/param_metadata/mdemit.py | 2 ++ Tools/autotest/param_metadata/param.py | 3 ++- Tools/autotest/param_metadata/rstemit.py | 5 +++++ Tools/autotest/param_metadata/xmlemit.py | 2 ++ 8 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Tools/autotest/param_metadata/ednemit.py b/Tools/autotest/param_metadata/ednemit.py index d024e13a5dbae..2989381c839ef 100644 --- a/Tools/autotest/param_metadata/ednemit.py +++ b/Tools/autotest/param_metadata/ednemit.py @@ -49,6 +49,9 @@ def emit(self, g): # remove any keys we don't really care to share for key in self.remove_keys: output_dict.pop(key, None) + for key in list(output_dict.keys()): + if not self.should_emit_field(param, key): + output_dict.pop(key, None) # rearrange bitmasks to be a vector with nil's if the bit doesn't have meaning if "bitmask" in output_dict: diff --git a/Tools/autotest/param_metadata/emit.py b/Tools/autotest/param_metadata/emit.py index 6bffd455d4816..daad4bbfc5a49 100644 --- a/Tools/autotest/param_metadata/emit.py +++ b/Tools/autotest/param_metadata/emit.py @@ -19,3 +19,6 @@ def start_libraries(self): def emit(self, g): pass + + def should_emit_field(self, param, field): + return field not in ['Legacy'] diff --git a/Tools/autotest/param_metadata/htmlemit.py b/Tools/autotest/param_metadata/htmlemit.py index 201a13ef9a85b..1f3a26bb290d4 100644 --- a/Tools/autotest/param_metadata/htmlemit.py +++ b/Tools/autotest/param_metadata/htmlemit.py @@ -65,6 +65,8 @@ def emit(self, g): t += "