yincheng.zhong
3 天以前 30303d366d1a0d857357c90bed876686f2d1e603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
ó
M»iqŽãó•SrSSKJrJrJrJrJrJr SSKrSr    "SS5r
\ S:XaÜSSK r SS/SS/S    S//r \
"\ 5r\RS
S 5 \"S 5H¦r\R%5r\"\\5 \S S- \R*-r\R.\SS- \R0-S--r\R4S\\"\5-S--r\R4S\\"\5-S--r\R\\4\5 M¨  gg)u
MowerController
 
控制器假设与契约:
- åæ ‡ç³»ï¼šXY å¹³é¢å•位为米(RTK æä¾›ï¼‰ï¼ŒZ å¿½ç•¥ç”¨äºŽå¹³é¢è·Ÿè¸ªã€‚
- èˆªå‘(heading):弧度,范围任意,控制器会处理环绕。
- GPS é¢‘率(位置/速度/heading/attitude)约 10Hz;IMU(加速度、角速度)100Hz。
- æŽ§åˆ¶è¾“出频率:74Hz,返回两个信号:forward(-100..100,对应 -1..+1 m/s)和 turn(-100..100,对应 -pi/2..+pi/2 rad/s,正为左转)。
- è·¯å¾„文件:JSON åˆ—表 [[x,y],[x,y],...]
 
设计说明:
- ä½¿ç”¨çº¯è¿½è¸ªï¼ˆpure pursuit)方法选取前视点,并基于角度误差使用 P æŽ§åˆ¶è®¡ç®—期望偏航速率(rad/s)。
- å‰è¿›é€Ÿåº¦ä¸Žåèˆªè¯¯å·®è€¦åˆï¼šåèˆªè¯¯å·®å¤§æ—¶é™ä½Žå‰è¿›é€Ÿåº¦ä»¥ä¿è¯å¯è½¬å¼¯èƒ½åŠ›ã€‚
 
接口:
- controller = MowerController(path_points, params)
- controller.update_gps(pos_xy, heading, vel_xy, timestamp)
- controller.update_imu(accel3, gyro3, timestamp)
- controller.compute_control(timestamp) -> {'forward': int, 'turn': int, 'info': {...}}
 
é)Úatan2ÚhypotÚsinÚcosÚpiÚacosNcó’•U[:¼aUS[--nU[:¼aMU[*:aUS[-- nU[*:aMU$)Né)r)Úas Ú=d:\Users\zhyin\PycharmProjects\Lowanlower\mower_controller.pyÚ
wrap_angler sEۈ
Œr‹'Ø    ˆQ”‰V‰ ˆð Œr'à
Œrˆc‹'Ø    ˆQ”‰V‰ ˆð Œrˆc'à €HócóN•\rSrSrS SjrS SjrS SjrSrSrSr    S S    jr
S
r g) ÚMowerControlleré#Ncó •UVs/sHn[U5PM  nn[U5S:Xa [S5eU=(d 0nURSS5n/n[    [U5S-
5HŽnXHupšXHS-up¼UR Xš45 X¹-
n XÊ-
n[ XÞ5nXö:”dM>US:”dMF[Xö-5n[    SUS-5H(nUUS-- nUR XU--X®U--45 M*  M  UR US5 Xpl[UR5Ul    /Ul
S/Ul [    URS-
5H‚nURUunnURUS-unn[ UU-
UU-
5nURR U5 URR URSU-5 M„  UR(aURSOSUl SUl U=(d 0nURS    S5UlURS
S 5UlURS [ S - 5UlURSS 5UlSUlSUlURSS5UlURSS5UlURSS5UlURSS 5UlURSS5UlURSS5UlURSS5UlURSS5UlURSS5UlURS S5UlURS!S"5UlURS#S$5Ul URS%S$5Ul!URS&S5Ul"URS'S5Ul#SUl$URS(S)5Ul%SUl&SUl'SUl(SUl)SUl*SUl+URS*S+5Ul,URS,S+5Ul-SUl.URS-S5Ul/S.Ul0SUl1SUl2S/Ul3SUl4SUl5S0Ul6S1Ul7URlUl8URS2S35Ul9URS4S+5Ul:URS5S5Ul;URS6S5Ul<URS7S5Ul=URS8[ S9- 5Ul>URS:S;5Ul?S<Ul@URS=S5UlAURS>S"5UlBURS?S@5UlCSUlDSUlES<UlFSAUlG[‘SBSC5UlIUR’R•SD5 gs snf)ENrzpath_points cannot be emptyÚmax_segment_lengthç333333ã?éçíµ ÷ư>éÿÿÿÿçÚmax_forward_mpsÚmax_reverse_mps皙™™™™É?Ú max_yawrateéÚaccelÚ    k_headinggÍÌÌÌÌÌü?Ú k_heading_dgÐ?Úk_xteç333333ó?Úk_curvÚ
base_speedçà?Úlookahead_timeg@Ú lookahead_mingffffffÖ?Ú lookahead_maxçø?Úgoal_toleranceç333333Ó?Ú    slow_zoneÚfinal_approach_dist皙™™™™é?Úmax_xteçð?Úxte_gain_scaleÚcurv_gain_scaleÚheading_err_gain_scaleÚ yawrate_alphagÍÌÌÌÌÌì?Ú k_heading_ig{®Gáz„?Úk_xte_iÚlarge_err_thresholdé
)rrÚ
goto_startÚ follow_pathÚstart_toleranceg¸…ëQ¸¾?Ústart_heading_toleranceÚstart_approach_distÚstart_slow_speedÚstart_min_speedÚstart_turn_first_headingé2Úmin_follow_speedg{®Gáz´?FÚ recovery_distÚrecovery_exit_distÚrecovery_speedgš™™™™™á?Úrotatezcontroller_log.csvÚwzgt,x,y,heading,target_x,target_y,target_dist,target_idx,xte,heading_err,forward,turn,speed,stage,status
)KÚtupleÚlenÚ
ValueErrorÚgetÚrangeÚappendrÚintÚpathÚnÚsegment_lengthsÚ cum_lengthsÚ total_lengthÚ last_progressrrrrrÚcurrent_speed_targetÚ current_speedrr r!r#r$r&r'r(r*r,r-r/r1r2r3Úyawrate_filterr4Úlast_heading_errÚ    last_timeÚ    last_curvÚheading_err_sumÚxte_sumÚmax_sumr5r6Úconsecutive_large_errr7Úmax_large_err_countÚposÚheadingÚvelÚ    imu_accelÚimu_gyroÚSTAGE_GOTO_STARTÚSTAGE_FOLLOW_PATHÚstager;r<r=r>r?r@rBÚ in_recoveryrCrDrEÚcurrent_target_idxÚnearest_path_idxÚfinishedÚ goto_substageÚopenÚlog_fileÚwrite)ÚselfÚ path_pointsÚparamsÚpÚ original_pathÚp_paramsÚ max_seg_lenÚ    densifiedÚiÚx1Úy1Úx2Úy2ÚdxÚdyÚseg_lenÚstepsÚkÚratioÚaxÚayÚbxÚbyÚLs                        r Ú__init__ÚMowerController.__init__$s‚€ñ,7Ó7©; aœ˜qž©;ˆ Ð7Ü ˆ}Ó  Ó "ÜÐ:Ó;Ð ;à—<˜RˆØ—l‘lÐ#7¸Ó=ˆ ؈    Ü”s˜=Ó)¨AÑ-Ö.ˆAØ"Ñ%‰FˆBØ" q¡5Ñ)‰FˆBØ × Ñ ˜b˜XÔ &Ø‘ˆBØ‘ˆBܘB“mˆGØÕ$¨°4­ä˜GÑ2Ó3ä˜q %¨!¡)Ö,AØ ¨¡™OEØ×$Ñ$ b°©:¡o°rÀ¹J±Ð%GÖHó-ñ/ð    ×ј rÑ*Ô+ØŒ    ÜT—Y‘Y“ˆŒà!ˆÔؘ5ˆÔܐt—v‘v ‘zÖ"ˆAØ—Y‘Y˜q‘\‰FˆBØ—Y‘Y˜q ™s‘^‰FˆBÜb˜‘e˜R ™UÓ#ˆAØ ×  Ñ  × 'Ñ '¨Ô *Ø × Ñ × #Ñ # D×$4Ñ$4°RÑ$8¸1Ñ$<Ö =ñ #ð 59×4D×4D˜D×,Ñ,¨RÒ0È#ˆÔà ˆÔð LbˆØ Ÿu™uÐ%6¸Ó<ˆÔØ Ÿu™uÐ%6¸Ó<ˆÔØŸ5™5 ´°1±Ó5ˆÔð—U‘U˜7 CÓ(ˆŒ
Ø$'ˆÔ!Ø ˆÔ🙘{¨CÓ0ˆŒØŸ5™5 °Ó5ˆÔØ—U‘U˜7 CÓ(ˆŒ
Ø—e‘e˜H cÓ*ˆŒ ØŸ%™%  ¨cÓ2ˆŒð Ÿe™eÐ$4°cÓ:ˆÔàŸU™U ?°DÓ9ˆÔØŸU™U ?°CÓ8ˆÔØŸe™eÐ$4°cÓ:ˆÔØŸ™˜{¨CÓ0ˆŒØ#$§5¡5Ð)>ÀÓ#DˆÔ ð—u‘u˜Y¨Ó,ˆŒ ØŸe™eÐ$4°cÓ:ˆÔð !Ÿu™uÐ%6¸Ó<ˆÔØ&'§e¡eÐ,DÀcÓ&JˆÔ#ð"ˆÔØŸU™U ?°DÓ9ˆÔØ #ˆÔ؈ŒØˆŒð #ˆÔ؈Œ ؈Œ ØŸ5™5 °Ó5ˆÔØ—u‘u˜Y¨Ó-ˆŒ ð&'ˆÔ"Ø#$§5¡5Ð)>ÀÓ#DˆÔ Ø#%ˆÔ ð
ˆŒØˆŒ ؈ŒØˆŒØˆŒ ð!-ˆÔØ!.ˆÔØ×*Ñ*ˆŒ
ð !Ÿu™uÐ%6¸Ó=ˆÔØ'(§u¡uÐ-FÈÓ'MˆÔ$Ø#$§5¡5Ð)>ÀÓ#DˆÔ Ø !§¡Ð&8¸$Ó ?ˆÔØ Ÿu™uÐ%6¸Ó=ˆÔà()¯©Ð.HÌ"ÈRÉ%Ó(PˆÔ%à !§¡Ð&8¸$Ó ?ˆÔà ˆÔØŸU™U ?°CÓ8ˆÔØ"#§%¡%Ð(<¸cÓ"BˆÔØŸe™eÐ$4°dÓ;ˆÔð#$ˆÔØ !ˆÔ؈Œ à%ˆÔäÐ1°3Ó7ˆŒ à  ‰ ×ÑðGõ    HùòG8s…W;cól•[U5Ul[U5UlUb[U5Ulgg)z„Update GPS-like measurements at ~10Hz.
 
pos_xy: (x,y) in meters
heading: radians
vel_xy: (vx, vy) in m/s in global frame (optional)
N)rHr`Úfloatrarb)rpÚpos_xyraÚvel_xyÚ    timestamps     r Ú
update_gpsÚMowerController.update_gps¬s0€ô˜“=ˆŒÜ˜W“~ˆŒ Ø Ñ Ü˜V“}ˆDHð rcóD•[U5Ul[U5Ulg)z:Update IMU (100Hz). accel3 and gyro3 are 3-element tuples.N)rHrcrd)rpÚaccel3Úgyro3rŽs    r Ú
update_imuÚMowerController.update_imu¸s€ä˜v›ˆŒÜ˜e› ˆ rcóX•UupEUupgUup‰X†-
n
X—-
n Xª-X»--n U S:Xa[XF-
XW-
5$XF-
U
-XW-
U --U - n U S:a[XF-
XW-
5$U S:”a[XH-
XY-
5$XmU
--nX}U --n[XN-
X_-
5nXN-
U -X_-
U
--
S:”aSOSnUU-$)zDCalculate cross track error (perpendicular distance to line segment)rrr)r)rpÚp1Úp2r`ÚxÚyryrzr{r|r}r~Úl2ÚtÚpxÚpyÚxteÚsigns                  r Ú    _calc_xteÚMowerController._calc_xte½sè€à‰ˆØ‰ˆØ‰ˆð‰WˆØ ‰WˆØ ‰UR‘U‰]ˆà ‹7ܘ™ ¡Ó(Ð (ð‰fb‰[˜A™F B™;Ñ &¨"Ñ ,ˆà ˆq‹5ܘ™ ¡Ó(Ð (Ø ‹Uܘ™ ¡Ó(Ð (à˜‘d‘ˆBؘ‘d‘ˆBܘ™ ¡Ó'ˆCà™ ™  q¡v¨r¡kÑ1°AÓ5‘1¸2ˆDؘ#‘:Ð rc    óP•URcURSSSS4$URup#URURupE[XB-
XS-
5nUS:”aSn[    UR5nOE[ SURS-
5n[ [    UR5URS-5nURn    [S5n
[Xx5H/n URU upE[XB-
XS-
5n XÊ:dM+U n
U n    M1  XlU    n [U    [    UR55H-n URU upE[XB-
XS-
5n XÁ:¼dM+U n  O  [    UR5S-
n SnSU    s=::a[    UR5S-
:aïO OìURU    S-
nURU    nURU    S-nUSUS-
USUS-
4nUSUS-
USUS-
4n[USUS5n[USUS5nUS:”acUS:”a]USUS-USUS--n[ S    [ SUUU-- 55n[[[U5-
5nU[ US5- nURU XíU    4$)
简化的Pure Pursuit前视点查找 - åªä½¿ç”¨ç‚¹ç´¢å¼•
 
从nearest_path_idx开始向前搜索,找到第一个距离>=lookahead_dist的点
 
Returns: (lookahead_xy, curvature, lookahead_idx, nearest_idx)
rrr0ééÚinfrrçð¿) r`rOrjrrIÚmaxÚminr‹rLÚabsrr)rpÚlookahead_distr™ršrržÚcurrent_nearest_distÚ search_startÚ
search_endÚ nearest_idxÚ nearest_distrxÚdÚ lookahead_idxÚ    curvaturer—r˜Úp3Úv1Úv2Úl1r›ÚdotÚ    cos_angleÚ angle_changes                         r Ú_find_lookahead_pointÚ%MowerController._find_lookahead_pointÚsª€ð 8‰8Ñ Ø—9‘9˜Q‘<  a¨Ð*Ð *àx‰x‰ˆð—‘˜4×0Ñ0Ñ1‰ˆÜ$ R¡V¨R©VÓ4Ðð   #Ó %؈LܘTŸY™Y›‰Jô˜q $×"7Ñ"7¸!Ñ";Ó<ˆLÜœS §¡›^¨T×-BÑ-BÀRÑ-GÓHˆJà×+Ñ+ˆ ܘU“|ˆ ä|Ö0ˆAØ—Y‘Y˜q‘\‰FˆBܐb‘f˜b™fÓ%ˆAØÕØ  Ø’ ñ 1ð!,Ôð$ˆ ܐ{¤C¨¯    ©    £NÖ3ˆAØ—Y‘Y˜q‘\‰FˆBܐb‘f˜b™fÓ%ˆAØÕ"Ø ! Ùñ 4ô  §    ¡    ›N¨QÑ.ˆMðˆ    Ø  Õ 0œc $§)¡)›n¨qÑ0Ö 0Ø—‘˜;¨™?Ñ+ˆBØ—‘˜;Ñ'ˆBØ—‘˜;¨™?Ñ+ˆBàQ‘%˜"˜Q™%‘-  A¡¨¨A©¡Ð/ˆBؐQ‘%˜"˜Q™%‘-  A¡¨¨A©¡Ð/ˆBär˜!‘u˜b ™eÓ$ˆBܐr˜!‘u˜b ™eÓ$ˆBàD‹y˜R $›Yؘ‘e˜B˜q™E‘k B q¡E¨"¨Q©%¡KÑ/Ü ¤c¨#¨s°b¸2±g©Ó&?Ó@    Ü"¤2¬¨Y«Ñ#7Ó8 Ø(¬3¨r°4«=Ñ8    ày‰y˜Ñ'¨À;ÐNÐNrcóÀ•Uup#URnURUupVU[UR5S-
:aŽURUS-upxXu-
n    X†-
n
X™-Xª--n U S:”acX%-
U    -X6-
U
--U - n [S[    SU 55n X\U    --n XlU
--nX--
nX>-
n[ UU5nXú-UU    --
nUS:”aUOU*nUXÞ4$[ X%-
X6-
5nUXV4$)uO
简化的横向误差计算 - åŸºäºŽæœ€è¿‘点
 
Returns: (xte, proj_x, proj_y)
rg•Ö&è .>rr0r)rjrOrIr¨r©r)rpr`r™ršr¯rržÚnxÚnyr}r~Úseg_len2rœÚproj_xÚproj_yÚ    xte_vec_xÚ    xte_vec_yÚxte_magÚcrossrŸs                    r Ú_compute_xte_simpleÚ#MowerController._compute_xte_simple"s€ð ‰ˆØ×+Ñ+ˆ 𗑘;Ñ'‰ˆð œ˜TŸY™Y›¨!Ñ+Ó +Ø—Y‘Y˜{¨Q™Ñ/‰FˆBð‘ˆBØ‘ˆBØ‘u˜r™u‘}ˆHà˜$‹à‘f˜b‘[ A¡F¨B¡;Ñ.°(Ñ:Ü˜œS  a›[Ó)à "™f™Ø "™f™ð™J    Ø™J    Ü     ¨9Ó5ð"™¨°R©Ñ7Ø!&¨£‘g°°à˜FÐ*Ð*ôA‘F˜A™FÓ#ˆØBˆ{Ðrc óä)•UR(aSSSS0S.$URb URcSSSS0S.$Uc[R"5nURcSnOU(aXR-
OSnU(aUO!UR(aURU-OSUlURup4UR
UR :XGa¤URSnUSU-
nUS    U-
n[Xg5n[Xv5n    [XR-
5n
[US
5(a URcS Ul URS :XGa [U
5UR::aS Ul OìURU
-S -n [![#X°R$- S-55n ['S[)SU 55n Sn Uupï[Xã-
Xô-
5nSnUR*R-USSUSSUSSURSSUSSUSSUSSUSU
SSU SU SUR
S35 UR*R/5 XÜSUR
U
US.S.$URS :XGaU    n[UUR-
5nX€R0:a    SUl GOäX€R2:a@X€R2- nSSU--nUR4UR6UR4-
U--nOSn[)UR6S-S5n[U5[8- nSSSU-
--n['UR:S-UU-U-5n['UUR:S-5nURU-n [![#UUR<- S-55n ['S[)SU 55n [![#X°R$- S-55n ['S[)SU 55n Uupï[Xã-
Xô-
5nSnUR*R-USSUSSUSSURSSUSSUSSUSSUSUSSU SU SUSSUR
S35 UR*R/5 XÜSUR
UUS .S.$URS:XGaÝ[?UR5S    :”aWURS    SURSS-
nURS    S    URSS    -
n[UU5nOSn[UUR-
5nX€R0:Ga9[U5UR@:GaURBUlSUl SUl"UR:Ul#[![#UR:UR<- S-55nURSupï[Xã-
Xô-
5nSnUR*R-USSUSSUSSURSSUSSUSSUSSUSUSSUS!UR:SSUR
S"35 UR*R/5 USS#UR
URDS$.S.$US:¼aS    OS%nU[)UR$S-['S&[U5S-55-n [![#X°R$- S-55n ['S[)SU 55n Uupï[Xã-
Xô-
5nSnUR*R-USSUSSUSSURSSUSSUSSUSSUSUSS!U SSSSUR
S'35 UR*R/5 SU S(US).S.$URcSnOU(aXR-
OSnU(aUO!UR(aURU-OSUlURup4URIUR5un n!n"[URS%SU-
URS%S    U-
5n#[URF5n$[U 5n%URJURLU$--S*[)U%S5--
n&['URJ[)URNU&55n'[U 5n(URP(dU(URR:”a€S+Ul(UR*R-USSUSSUSSURSSU!SSU"SSU(SSURTSU SS,UR
S-35 UR*R/5 URP(aU(URV:a€S.Ul(UR*R-USSUSSUSSURSSU!SSU"SSU(SSURTSU SS,UR
S/35 UR*R/5 URYU'5uun)n*n+n,n-U,Ul"[U*U-
U)U-
5n.['S0[)SU URZ- 55n/UR\*U/-UR^-n0[U.U0-5n[UUR-
5nUS:”aUUR`-
U- OSn1UUl0U=RbUU-- sl1U=RdU U-- sl2['URf*[)URfURb55Ul1['URf*[)URfURd55Ul2URU-URhU1--URjURb--URlURd--n SS[U+5URn--- n2[U5n3SSU3URp--- n[U 5n4SSU4UR^--- n5U2U-U5-S1-n6[)U2UU55n7SU6-S2U7--n8UR6U8-nURrU -S    URr-
URt--Ul:UR$n9['U9*[)U9URt55n URP(a“[U"U-
U!U-
5n.['S0[)SU URZ- 55n/UR\*U/-UR^-n0[U.U0-5n[UUR-
5nURU-n URvnU#URx:n:U#URz:n;[U 5UR|S-:”d[U5[8S3- :”aEU=R~S    - sl?UR~UR€:”aSUl?SUl1SUl2OSUl?URP(dˆU:(aK['S*[)SU#URx- 55n<U;(aU<['SU#URz- 5-n<UU<-nU;(a/US-n[U 5S4:”d[U5[8S5- :”aUS6-nUR
URB:XaÞURP(dÍU:(a UR‚OUR‚S-n=[U5S7:aœUU=:a–U)U*pþ[Xã-
Xô-
5nUR*R-USSUSSUSSURSSUSSUSSUSSURDSU SSUSS8U=SSUR
S935 UR*R/5 U=nUR„U:(aSOS-n>UURF-
n?U>U-n@U=RF['U@*[)U@U?55- sl#UR
UR :Xa%[U5S::”aUR†*S-Ul#O[[U5S::”a&URP(dUR†*S-Ul#URFS:a[U5S3:aSUl#U#URˆ:aS+UlSSSS0S.$U#URˆS-:aJURDURŠS;-
:¼a-[U5S*:a[U 5S2:aS+UlSSSS0S.$UbUO[R"5nAURFnBU)U*pþ[Xã-
Xô-
5nUR<S:wa$[![#WBUR<- S-55OSnC['S[)SUC55nCUR$S:wa#[![#X°R$- S-55OSnD['S[)SUD55nDUR*R-WASSUSSUSSURSSUSSUSSUSSURDSU SSUSSWCSUDSWBSSUR
S<35 UR*R/5 UR<S:wa.[![#URFUR<- S-55OSn ['S[)SU 55n U S:XGa@UR(Gd.[U5S7:GaUR<S:wa.[![#UR‚UR<- S-55OSnEUES:waØU)U*pþ[Xã-
Xô-
5nUR*R-WASSUSSUSSURSSUSSUSSUSSURDSU SSUSSWES[![#X°R$- S-55SUR‚SSUR
S=35 UR*R/5 UEn UR‚Ul#UR$S:wa#[![#X°R$- S-55OSn ['S[)SU 55n UR(aSOS>nFUFX44URUUURFU U)U*4U+U#S?.
nGWAnHU)U*pþ[Xã-
Xô-
5nUR*R-UHSSUSSUSSURSSUSSUSSUSSURDSU SSUSSU SU SURFSSUR
SUFS@35 UR*R/5 XÜUGS.$)AztCompute forward and turn outputs mapped to [-100,100].
 
Returns dict with keys: forward(int), turn(int), info(dict)
rÚstatusrk)ÚforwardÚturnÚinfoNÚno_stategyé&1¬Œ?rrrlrFÚmovegÍÌÌÌÌÌô?édiœÿÿÿz.3fÚ,z,0.000,z,rotate_to_start
Úrotate_to_start)rÊrgÚ heading_errÚ dist_to_startÚaligngš™™™™™Ù?rr0r.r%r)r"z,moving_to_start
Úmoving_to_start)rÊrgrÔrÓz,0,z,reached_start
Ú reached_start)rÊrgÚ advanced_idxrgš™™™™™©?z,align_at_start
Úalign_at_start)rÊrÓr+Tz,0.000,0,0,0.000,z,enter_recovery
Fz,exit_recovery
r§gUUUUUUÕ?rg@g333333Ã?r8gffffffæ?g@z,0,0,z,enforce_min_speed
g333333@r
z    ,pre_map
z,force_min_forward
Úrunning)
rÊr`raÚdesired_headingrÓrVÚ yawrate_cmdÚ    target_xyÚpath_curvatureÚ
final_distÚ
)Frkr`raÚtimerYrgrerOrrr Úhasattrrlrªr@rrNÚroundrr¨r©rnroÚflushr;r=r>r$rr?rrIr<rfrirVrÇr'r&r(rhrCrjrDr»r/r!r1rXr[r\r]r r5r6r2r3r4rWrEr,r-r7r^r_rBrrr*rP)IrprŽÚdtr™ršÚ start_pointr}r~rÔÚdesired_heading_to_startÚheading_err_to_startrÜÚ turn_signalÚforward_signalÚtarget_xÚtarget_yÚ target_distÚ
target_idxrÛrÓÚ
dist_ratioÚ speed_scaleÚbase_target_speedÚ heading_ratioÚ    err_scaleÚ target_speedÚpath_dxÚpath_dyÚdesired_start_headingÚheading_err_finalÚf_sigr rŸrÁrÂrßÚ actual_speedrÅÚbase_lookaheadÚ    lookaheadÚ dist_to_pathÚlxÚlyrÞr²r¯Ú path_headingÚxte_normalizedÚxte_correctionÚ heading_err_dÚ
curv_scaleÚheading_err_absÚxte_absÚ    xte_scaleÚ
geom_scaleÚ    min_scaleÚ blend_scalerÚ in_slow_zoneÚin_final_approachÚ
dist_scaleÚ dynamic_minrÚ speed_changeÚ
max_changeÚlog_tÚ pre_map_speedÚpre_map_forwardÚ pre_map_turnÚ forced_signalrÊrÍrœsI                                                                         r Úcompute_controlÚMowerController.compute_controlNsë€ð
==Ø ¨!°hÀ
Ð5KÑLÐ Là 8‰8Ñ ˜tŸ|™|Ñ3Ø ¨!°hÀ
Ð5KÑLÐ Lð Ñ ÜŸ    š    › ˆIð >‰>Ñ !؉Bæ/8Ÿ^™^Ò+¸eˆBÞ&/™ÈTÏ^Ï^°d·n±nÀrÒ6IÐadˆŒàx‰x‰ˆð :‰:˜×.Ñ.Ô .ØŸ)™) A™,ˆKؘQ‘ !Ñ#ˆBؘQ‘ !Ñ#ˆBÜ! "›MˆMô(-¨R£}Ð $Ü#-Ð.FÏÉÑ.UÓ#VÐ  ô˜4 ×1Ñ1°T×5GÑ5GÑ5OØ%-Ô"ð×!Ñ! XÔ-äÐ+Ó,°×0MÑ0MÓMØ)/DÕ&à"&§.¡.Ð3GÑ"GÈ#Ñ"MKÜ"%¤e¨[×;KÑ;KÑ-KÈsÑ,RÓ&SÓ"TKÜ"% d¬C°°[Ó,AÓ"BKØ%&Nà)4Ñ&HÜ"'¨© °h±lÓ"CKØ!"JØ—M‘M×'Ñ'¨9°S¨/¸¸1¸S¸'ÀÀ1ÀSÀ'ÈÈ4Ï<É<ÐX[ÐJ\Ð\]Ø+3°C¨.¸¸(À3¸ÀqÈÐUXÐHYÐYZÐ[eÐZfðg1Ø1EÀcÐ0JÈ!ÈNÐK[Ð[\Ð]hÐ\iÐipÐqu×q{Ñq{Ðp|ð}Oð)PôQð—M‘M×'Ñ'Ô)Ø'5Ø"3¸d¿j¹jÐYmØ)6ñUñðð
×!Ñ! VÔ+à":Ü(¨¸4¿<¹<Ñ)GÓH ð!×#7Ñ#7Ó7Ø)0DÖ&ð%×'?Ñ'?Ó?Ø%2×5MÑ5MÑ%M˜
Ø&)¨C°*Ñ,<Ñ&<˜ Ø,0×,AÑ,AÀTÇ_Á_ÐW[×WlÑWlÑElÐpzÑDzÑ,zÑ)à&)˜ Ü,/°·±À#Ñ0EÀsÓ,KÐ)ô%(¨ Ó$4´rÑ$9MØ # c¨S°=Ñ-@Ñ&AÑ AIÜ#& t×';Ñ';¸cÑ'AÐCTÐWbÑCbÐenÑCnÓ#oLÜ#& |°T×5IÑ5IÈCÑ5OÓ#PLà"&§.¡.°;Ñ">KÜ%(¬° ¸t×?SÑ?SÑ0SÐWZÑ/ZÓ)[Ó%\NÜ%(¨¬s°3¸Ó/GÓ%HNÜ"%¤e¨[×;KÑ;KÑ-KÈsÑ,RÓ&SÓ"TKÜ"% d¬C°°[Ó,AÓ"BKà)4Ñ&HÜ"'¨© °h±lÓ"CKØ!"JØ—M‘M×'Ñ'¨9°S¨/¸¸1¸S¸'ÀÀ1ÀSÀ'ÈÈ4Ï<É<ÐX[ÐJ\Ð\]Ø)1°#¨°a¸À°~ÀQÀ{ÐSVÐFWÐWXÐYcÐXdðe/Ø/:¸3Ð.?¸qÀÐ@PÐPQÐR]ÐQ^Ð^_Ð`lÐmpÐ_qÐqrÐsw×s}Ñs}Ðr~ðQð)RôSð—M‘M×'Ñ'Ô)à'5Ø"3¸d¿j¹jÐ[hØ'2ñUñðð ×!Ñ! WÔ,ܐt—y‘y“> AÓ%Ø"Ÿi™i¨™l¨1™o°·    ±    ¸!± ¸Q±Ñ?GØ"Ÿi™i¨™l¨1™o°·    ±    ¸!± ¸Q±Ñ?GÜ,1°'¸7Ó,CÑ)à,/Ð)Ü$.Ð/DÀtÇ|Á|Ñ/SÓ$TÐ!ð"×$8Ñ$8Ô8¼sÐCTÓ?UÐX\×XtÑXtÔ?tØ!%×!7Ñ!7D”JØ)-DÔ&à./DÔ+à)-×)=Ñ)=DÔ&䤠t×';Ñ';¸d×>RÑ>RÑ'RÐVYÑ&YÓ ZÓ[EØ)-¯©°1©Ñ&HÜ"'¨© °h±lÓ"CKØ!"JØ—M‘M×'Ñ'¨9°S¨/¸¸1¸S¸'ÀÀ1ÀSÀ'ÈÈ4Ï<É<ÐX[ÐJ\Ð\]Ø+3°C¨.¸¸(À3¸ÀqÈÐUXÐHYÐYZÐ[eÐZfðg1Ø1BÀ3Ð0GÀqÈÈÈsÐSW×SgÑSgÐhkÐRlÐlmÐnr×nxÑnxÐmyðzJð)KôLð—M‘M×'Ñ'Ô)Ø',°aÈOÐfj×fpÑfpðCG÷CZñCZñB[ñ\ð\ð!2°QÓ 6™1¸BDØ"&¬¨T×-=Ñ-=ÀÑ-CÄSÈÌsÐSdÓOeÐhkÑOkÓElÓ)mÑ"mKÜ"%¤e¨[×;KÑ;KÑ-KÈsÑ,RÓ&SÓ"TKÜ"% d¬C°°[Ó,AÓ"BKØ)4Ñ&HÜ"'¨© °h±lÓ"CKØ!"JØ—M‘M×'Ñ'¨9°S¨/¸¸1¸S¸'ÀÀ1ÀSÀ'ÈÈ4Ï<É<ÐX[ÐJ\Ð\]Ø+3°C¨.¸¸(À3¸ÀqÈÐUXÐHYÐYZÐ[eÐZfðg1Ø1BÀ3Ð0GÀsÈ;È-ÐWXÐY^Ð_bÐXcÐcdÐei×eoÑeoÐdpðqBð)CôDð—M‘M×'Ñ'Ô)Ø'(°+ÐRbðtEñHFñGðGð >‰>Ñ !؉Bæ/8Ÿ^™^Ò+¸eˆBÞ&/™ÈTÏ^Ï^°d·n±nÀrÒ6IÐadˆŒðx‰x‰ˆØ"×6Ñ6°t·x±xÓ@шˆVVô˜4Ÿ9™9 R™=¨Ñ+¨aÑ/°·±¸2±¸qÑ1AÀAÑ1EÓFˆ
ô˜4×-Ñ-Ó.ˆ ܐc“(ˆð×+Ñ+¨d×.AÑ.AÀLÑ.PÑPÐSVÔY\Ð]dÐfiÓYjÑSjÑjˆÜ˜×*Ñ*¬C°×0BÑ0BÀNÓ,SÓTˆ    ô˜3“xˆ Ø×× L°4×3EÑ3EÓ$EØ#ˆDÔ Ø M‰M× Ñ  9¨S /°°1°S°'¸¸1¸S¸'ÀÀ4Ç<Á<ÐPSÐBTÐTUØ#)¨# ,¨a°°s¨|¸1¸\È#Ð<NÈaÐPT×PeÑPeÐOfÐfgØ#& s )Ð+<¸T¿Z¹Z¸LÐHYð![ô \ð M‰M× Ñ Ô !à × ×   ¨t×/FÑ/FÓ FØ$ˆDÔ Ø M‰M× Ñ  9¨S /°°1°S°'¸¸1¸S¸'ÀÀ4Ç<Á<ÐPSÐBTÐTUØ#)¨# ,¨a°°s¨|¸1¸\È#Ð<NÈaÐPT×PeÑPeÐOfÐfgØ#& s )Ð+<¸T¿Z¹Z¸LÐHXð!Zô [ð M‰M× Ñ Ô !ð@D×?YÑ?YÐZcÓ?dÑ<‰ˆˆR. -°Ø"/ˆÔô˜R !™V R¨!¡VÓ,ˆ ô˜T¤3 s¨C°$·,±,Ñ,>Ó#?Ó@ˆØŸ*™*˜ ~Ñ5¸×8KÑ8KÑKˆô% \°NÑ%BÓCˆÜ  °4·<±<Ñ!?Ó@ˆ ðGIÈ1Ãf˜ t×'<Ñ'<Ñ<ÀÒBÐRSˆ Ø +ˆÔð     ×Ò  ¨bÑ 0Ñ0ÕØ  Š ˜˜b™Ñ  Ü" D§L¡L =´#°d·l±lÀD×DXÑDXÓ2YÓZˆÔܘDŸL™L˜=¬#¨d¯l©l¸D¿L¹LÓ*IÓJˆŒ ð—~‘~¨ Ñ3Ø×&Ñ&¨Ñ6ñ7à×&Ñ&¨×)=Ñ)=Ñ=ñ>ð—l‘l T§\¡\Ñ1ñ2ˆ ð˜C¤# nÓ"5¸×8LÑ8LÑ"LÑLÑMˆ
ô˜kÓ*ˆØ˜3 °4×3NÑ3NÑ!NÑNÑOˆ    ôc“(ˆØ˜3 ¨4×+>Ñ+>Ñ!>Ñ>Ñ?ˆ    ð! 9Ñ,¨yÑ8¸gÑFˆ
ܘ
 I¨yÓ9ˆ    Ø˜JÑ&¨¨y©Ñ8ˆ à—‘¨Ñ4ˆ ð $×1Ñ1°KÑ?Ø  ×!3Ñ!3Ñ3°t×7JÑ7JÑJñ KˆÔà×&Ñ&ˆ ܘ;˜,¬¨K¸×9LÑ9LÓ(MÓNˆ ð × × ä  ¨!¡¨V°a©ZÓ8ˆLÜ  ¤s¨3°°d·l±lÑ0BÓ'CÓDˆNØ"Ÿj™j˜[¨>Ñ9¸D×<OÑ<OÑOˆNÜ(¨¸Ñ)FÓGˆOÜ$ _°t·|±|Ñ%CÓDˆKØŸ.™.¨;Ñ6ˆKØ×.Ñ.ˆLà! D§N¡NÑ2ˆ Ø&¨×)AÑ)AÑAÐô ˆs‹8d×.Ñ.°Ñ4Ó 4¼¸KÓ8HÌ2ÈcÉ6Ó8QØ × &Ò &¨!Ñ +Õ &Ø×)Ñ)¨D×,DÑ,DÓDà-.Ô*Ø'(Ô$Ø ” øà)*ˆDÔ &ð××ÞÜ  ¤c¨#¨z¸D¿N¹NÑ/JÓ&KÓL
Þ$ؤ# c¨:¸×8PÑ8PÑ+PÓ"QÑQJØ 
Ñ* ö!Ø Ñ# ܐs“8˜d“?¤c¨+Ó&6¼¸B¹Ó&>Ø  CÑ'Lð :‰:˜×/Ñ/Ó /¸×8H×8HÞ3?˜$×/Ò/ÀT×EZÑEZÐ]`ÑE`ˆKܐ;Ó #Ó%¨,¸Ó*DØ%'¨˜(Ü# H¡L°(±,Ó? Ø— ‘ ×#Ñ# y° o°Q°q¸°g¸Q¸qÀ¸gÀQÀtÇ|Á|ÐTWÐFXÐXYØ'/° n°A°h¸s°^À1À[ÐQTÐDUÐUVÐW[×WnÑWnÐVoÐopØ'*¨3 i¨q°¸SÐ0AÀØ'2°3Ð&7°q¸¿¹¸ ÐDXð%Zô[ð— ‘ ×#Ñ#Ô%Ø* ð—
‘
¦\™c°sÑ;ˆØ# d×&8Ñ&8Ñ8ˆ ؘR‘Zˆ
Ø ×Òœc : +¬s°:¸|Ó/LÓMÑMÕð :‰:˜×.Ñ.Ó .ܐ;Ó #Ó%Ø&*×&:Ñ&:Ð%:¸SÑ%@Ô"øä;Ó #Ó%¨d×.>×.>Ø&*×&:Ñ&:Ð%:¸SÑ%@Ô"Ø×!Ñ! AÓ%¬#¨kÓ*:¸SÓ*@Ø%(Ô"ð ˜×+Ñ+Ó +Ø ˆDŒMØ ¨!°hÀ
Ð5KÑLÐ Lð ˜×,Ñ,¨sÑ2Ó 2Ø × #Ñ # t§v¡v°¡zÓ 1Ü  Ó ˜sÓ "¤s¨3£x°#£~Ø ˆDŒMØ ¨!°hÀ
Ð5KÑLÐ Lð'Ñ2‘    ¼¿    º    » ˆØ×*Ñ*ˆ ࠐ(ܘH™L¨(©,Ó7ˆ ØVZ×VjÑVjÐnoÓVoœ#œe ]°T×5IÑ5IÑ%IÈSÑ$PÓQÔRÐuvˆÜ˜d¤C¨¨_Ó$=Ó>ˆØMQ×M]ÑM]ÐabÓMb”sœ5 +×0@Ñ0@Ñ"@ÀCÑ!GÓHÔIÐhiˆ ܘ4¤ S¨,Ó!7Ó8ˆ Ø  ‰ ×јu S˜k¨¨1¨S¨'°°1°S°'¸¸4¿<¹<ÈÐ:LÈAØ'¨˜n¨A¨h°s¨^¸1¸[ÈÐ<MÈQÈt×OfÑOfÐNgÐghØ" 3˜i q¨°SÐ(9¸¸?Ð:KÈ1È\ÈNÐZ[Ð\iÐjmÐ[nÐnoØ#Ÿz™z˜l¨*ð6ô    7ð      ‰ ×ÑÔàZ^×ZnÑZnÐrsÓZsœœU D×$6Ñ$6¸×9MÑ9MÑ$MÐQTÑ#TÓUÔVÐyzˆÜ˜T¤3 s¨NÓ#;Ó<ˆð ˜QÔ  t§}§} }¼¸[Ó9IÈCÔ9OØ`d×`tÑ`tÐxyÓ`yœC¤ t×'<Ñ'<¸t×?SÑ?SÑ'SÐWZÑ&ZÓ [Ô\ð@AˆMØ Ó!Ø%'¨˜(Ü# H¡L°(±,Ó? Ø— ‘ ×#Ñ# u¨S k°°1°S°'¸¸1¸S¸'ÀÀ4Ç<Á<ÐPSÐBTÐTUØ'/° n°A°h¸s°^À1À[ÐQTÐDUÐUVÐW[×WnÑWnÐVoÐopØ'*¨3 i¨q°¸SÐ0AÀÀ=À/ÐQRÔSVÔW\Ð^i×l|Ñl|Ñ^|ðADñ^DóXEóTFðSGðGHØ'+×'<Ñ'<¸SÐ&AÀÀ4Ç:Á:À,ÐNbð%dôeð— ‘ ×#Ñ#Ô%Ø!.Ø%)×%:Ñ%:Ô"àLP×L\ÑL\Ð`aÓLa”cœ% ×/?Ñ/?Ñ!?À3Ñ FÓGÔHÐghˆ ܘ$¤ C¨Ó 5Ó6ˆ à#Ÿ}Ÿ}‘°)ˆàؐ6Ø—|‘|Ø.Ø&Ø!×/Ñ/Ø&ؘb˜Ø,Ø$ñ 
ˆð ˆØ (ܘH™L¨(©,Ó7ˆ Ø  ‰ ×јq ˜g Q q¨ g¨Q¨q°¨g°Q°t·|±|ÀCÐ6HÈØ'¨˜n¨A¨h°s¨^¸1¸[ÈÐ<MÈQÈt×OfÑOfÐNgÐghØ" 3˜i q¨°SÐ(9¸¸>Ð:JÈ!ÈKÈ=ÐXYÐZ^×ZlÑZlÐmpÐYqÐqrØ#Ÿz™z˜l¨!¨F¨8°2ð7ô    8ð      ‰ ×ÑÔà)ÈÑMÐMr)@rfrerr$r^rRrVrUrir2r-rkr*rlrar3r[rcrdrhr#rr r5r!r6r7rZrXrTrYrnr(r'r&rr_rr]r/rrBrPrjrOr`rCrDrErQr,rgr=r<r?r>r;r@rSrbr1r\r4rW)N)NN) Ú__name__Ú
__module__Ú __qualname__Ú__firstlineno__rˆrr”r¡r»rÇrÚ__static_attributes__©rr rr#s.†ôFHôP
%ô%ò
ò:FOòP*÷X@NrrÚ__main__r¤r8)rr§rérËgY@rÌgš™™™™™¹?r)Ú__doc__Úmathrrrrrrrár rrÚjsonrOÚcrrLrxrÚoutÚprintrÚfrarÚhdr`rržrrr Ú<module>r(sðñ÷*2×1Û ò ÷k
Nñk
Nð\ ˆzÓãØ ˆqˆE1Q%˜˜A˜Ð €DÙ˜Ó€A؇LL˜CÔ Ù 2ŽYˆØ×ÑÓ!ˆÙ ˆaŒ à     ‰N˜UÑ " Q×%6Ñ%6Ñ 6ˆØ Y‰Y˜#˜f™+¨Ñ-°·±Ñ>ÀÑDÑ DˆØ U‰U1‰X˜™C ›G™  cÑ)Ñ )ˆØ U‰U1‰X˜™C ›G™  cÑ)Ñ )ˆØ     ‰ b˜W˜bÖ!òð r