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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
o
6ÖiùÂã@sdZddlmZmZmZmZmZmZddlZdd„Z    Gdd„dƒZ
e dkr‡ddl Z ddgd    dgd
dggZ e
e ƒZe d d ¡ed ƒD]FZe ¡ZeeeƒeddejZejeddejdZejdeeeƒdZejdeeeƒdZe eefe¡qBdSdS)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ÚacosNcCs@|tkr|dt8}|tks|t kr|dt7}|t ks|S)Né)r)Úa©r
ú=D:\Users\zhyin\PycharmProjects\Lowanlower\mower_controller.pyÚ
wrap_angles ÿ
 
ÿr c@steZdZddd„Zddd„Zddd„Zdd    „Zd
d „Zd d „Zdd„Z    dd„Z
dd „Zdd„Z    dd„Z ddd„Z dS)ÚMowerControllerNcCsvdd„|Dƒ}t|ƒdkrtdƒ‚||_|pi}| dd¡}g}tt|ƒdƒD]Q}||\}}    ||d\}
} | ||    f¡|
|} | |    } t| | ƒ}||kry|dkryt||ƒ}td|dƒD]}||d}| || ||    | |f¡qaq(| |d    ¡||_t|jƒ|_    g|_
d
g|_ t|j    dƒD],}|j|\}}|j|d\}}t||||ƒ}|j
 |¡|j  |j d    |¡q˜|j rÍ|j d    nd
|_ d
|_ |pÖi}| d d¡|_| d d ¡|_| dtd¡|_| dd ¡|_d
|_d
|_| dd¡|_| dd¡|_| dd¡|_| dd ¡|_| dd¡|_| dd¡|_| dd¡|_| dd¡|_| d d!¡|_| d"d¡|_| d#d$¡|_| d%d&¡|_ | d'd&¡|_!| d(d¡|_"| d)d¡|_#d
|_$| d*d+¡|_%d
|_&d|_'d
|_(d
|_)d
|_*d|_+| d,d-¡|_,| d.d-¡|_-d|_.| d/d¡|_/d0|_0d|_1d|_2d1|_3d|_4d|_5d2|_6d3|_7|j6|_8| d4d5¡|_9| d6d-¡|_:| d7d¡|_;| d8d¡|_<| d9d¡|_=| d:td;¡|_>| d<d=¡|_?d>|_@| d?d¡|_A| d@d$¡|_B| dAdB¡|_Cd|_Dd|_Ed>|_FdC|_Gd>|_Hd>|_Id|_J| dDd5¡|_K| dEd$¡|_L| dFdG¡|_MtNƒ|_OtPdHdIƒ|_Q|jQ RdJ¡dS)KNcSsg|]}t|ƒ‘qSr
)Útuple)Ú.0Úpr
r
r Ú
<listcomp>'sz,MowerController.__init__.<locals>.<listcomp>rzpath_points cannot be emptyZmax_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_timeç@Ú 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é
)rrZ
goto_startZ 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š™™™™™á?ÚrotateÚwaypoint_turn_toleranceÚwaypoint_approach_distÚwaypoint_turn_heading_tol皙™™™™¹?zcontroller_log.csvÚwzgt,x,y,heading,target_x,target_y,target_dist,target_idx,xte,heading_err,forward,turn,speed,stage,status
)SÚlenÚ
ValueErrorÚ original_pathÚgetÚrangeÚappendrÚintÚpathÚnZsegment_lengthsZ cum_lengthsZ total_lengthZ last_progressrrrrrZcurrent_speed_targetÚ current_speedrrrr!r"r$r&r'r)r+r,r.r0r1r2Úyawrate_filterr3Úlast_heading_errÚ    last_timeZ    last_curvÚheading_err_sumÚxte_sumÚmax_sumr4r5Úconsecutive_large_errr6Úmax_large_err_countÚposÚheadingÚvelÚ    imu_accelÚimu_gyroÚSTAGE_GOTO_STARTÚSTAGE_FOLLOW_PATHÚstager8r9r:r;r<r=r?Ú in_recoveryr@rArBÚcurrent_target_idxÚnearest_path_idxÚfinishedÚ goto_substageÚwaypoint_approach_modeÚwaypoint_turn_modeÚwaypoint_turn_target_idxrDrErFÚsetÚwaypoint_turnedÚopenÚlog_fileÚwrite)ÚselfZ path_pointsÚparamsrKZp_paramsZ max_seg_lenZ    densifiedÚiÚx1Úy1Úx2Úy2ÚdxÚdyZseg_lenÚstepsÚkÚratioÚaxÚayÚbxÚbyÚLrr
r
r Ú__init__$sÈ   
   €   zMowerController.__init__cCs.t|ƒ|_t|ƒ|_|durt|ƒ|_dSdS)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)rr[Úfloatr\r])rpZpos_xyr\Zvel_xyÚ    timestampr
r
r Ú
update_gps¹s
 
 
ÿzMowerController.update_gpscCst|ƒ|_t|ƒ|_dS)z:Update IMU (100Hz). accel3 and gyro3 are 3-element tuples.N)rr^r_)rpZaccel3Zgyro3rƒr
r
r Ú
update_imuÅs
zMowerController.update_imucCsø|\}}|\}}|\}}    ||}
|    |} |
|
| | } | dkr)t||||ƒS|||
||| | } | dkrDt||||ƒS| dkrQt||||    ƒS|| |
}|| | }t||||ƒ}||| |||
dkrvdnd}||S)zDCalculate cross track error (perpendicular distance to line segment)rrr)r)rpÚp1Úp2r[ÚxÚyrsrtrurvrwrxÚl2ÚtÚpxÚpyÚxteÚsignr
r
r Ú    _calc_xteÊs$  $zMowerController._calc_xtec Cs´|dks |t|jƒdkrdS|j|d}|j|}|j|d}|d|d}|d|d}|d|d}|d|d}t||ƒ}    t||ƒ}
tt|
|    ƒƒ} | tdkS)u•
        æ£€æµ‹è·¯å¾„点idx是否是拐点(需要原地转向)
        
        æ‹ç‚¹å®šä¹‰ï¼šå‰åŽä¸¤æ®µè·¯å¾„方向变化超过45度
        rrFr)rIrPrÚabsr r) rpÚidxÚp_prevÚp_currÚp_nextÚdx1Údy1Údx2Údy2Úheading1Úheading2Ú
angle_diffr
r
r Ú_is_waypoint_turn_neededçs
 
 
 z(MowerController._is_waypoint_turn_neededcCs|jdurdS|j\}}d}tdƒ}tdt|jƒdƒD]b}|j|d}|j|}|j|d}|d|d}    |d|d}
|d|d} |d|d} t|
|    ƒ} t| | ƒ}tt|| ƒƒ}|tdkr~t    |d||d|ƒ}||kr~|}|}q||fS)uŒ
        åœ¨åŽŸå§‹è·¯å¾„ä¸­æ‰¾åˆ°æœ€æŽ¥è¿‘å½“å‰ä½ç½®çš„æ‹ç‚¹
        
        Returns: (waypoint_idx, distance) æˆ– (None, None)
        N©NNÚinfrrr)
r[r‚rMrIrKrr‘r rr)rprˆr‰Znearest_waypoint_idxÚ nearest_distrrr“r”r•r–r—r˜r™ršr›rœÚdistr
r
r Ú_find_nearest_original_waypoints.
 
 
 
 
 €z/MowerController._find_nearest_original_waypointcCs²|t|jƒdkr4|dkr2|j|d|j|dd}|j|d|j|dd}t||ƒSdS|j|dd|j|d}|j|dd|j|d}t||ƒS)uB获取原始路径点idx处的目标航向(下一段的方向)rrr©rIrKr)rpr’rwrxr
r
r Ú_get_target_heading_at_waypoint*s  
  
z/MowerController._get_target_heading_at_waypointcCs`|jdur|jddddfS|j\}}|j|j\}}t||||ƒ}|dkr0d}t|jƒ}ntd|jdƒ}tt|jƒ|jdƒ}|j}    tdƒ}
t||ƒD]} |j| \}}t||||ƒ} | |
kri| }
| }    qO|    |_|    } t|    t|jƒƒD]} |j| \}}t||||ƒ} | |kr‘| } nqwt|jƒd} d}d|    kr«t|jƒdkr'nnz|j|    d}|j|    }|j|    d}|d|d|d|df}|d|d|d|df}t|d|dƒ}t|d|dƒ}|d    kr'|d    kr'|d|d|d|d}td
td|||ƒƒ}t    t
t |ƒƒ}|t|d    ƒ}|j| || |    fS) u
        ç®€åŒ–çš„Pure Pursuit前视点查找 - åªä½¿ç”¨ç‚¹ç´¢å¼•
        
        ä»Žnearest_path_idx开始向前搜索,找到第一个距离>=lookahead_dist的点
        
        Returns: (lookahead_xy, curvature, lookahead_idx, nearest_idx)
        Nrrr/éérŸrrçð¿) r[rPrerrIÚmaxÚminr‚rMr‘rr)rpZlookahead_distrˆr‰rŒrZcurrent_nearest_distZ search_startZ
search_endÚ nearest_idxr rrÚdÚ lookahead_idxZ    curvaturer†r‡Zp3Úv1Úv2Úl1rŠÚdotÚ    cos_angleÚ angle_changer
r
r Ú_find_lookahead_point9sX
 
 €þ$
   z%MowerController._find_lookahead_pointcCst|dƒr t|jƒdkrdtdƒfS|j\}}tdt|jƒdƒD]f}||jvr)q!|j|d}|j|}|j|d}|d|d}|d|d}|d|d}    |d|d}
t||ƒ} t|
|    ƒ} tt    | | ƒƒ} | t
dkr‡t |d||d|ƒ}||fSq!dtdƒfS)uÈ
        åœ¨åŽŸå§‹è·¯å¾„ä¸­æŸ¥æ‰¾ä¸‹ä¸€ä¸ªæœªåˆ°è¾¾çš„æ‹ç‚¹
        æŒ‰ç…§è·¯å¾„顺序查找,不跳过
        
        Returns: (waypoint_idx, distance) æˆ– (None, inf) å¦‚果没有找到
        rKéNrŸrrr) ÚhasattrrIrKr‚r[rMrlrr‘r rr)rprˆr‰rrÚprev_ptÚcurr_ptÚnext_ptr–r—r˜r™Zangle1Zangle2r²r¡r
r
r r¢s* 
 
 
 
 
  ý cCs¦|durdS|t|jƒdkr2|dkr0|j|d}|j|}t|d|d|d|dƒSdS|j|}|j|d}|d|d}|d|d}t||ƒS)uÔ
        èŽ·å–æ‹ç‚¹å¤„çš„ç›®æ ‡èˆªå‘ï¼ˆä¸‹ä¸€æ®µè·¯å¾„çš„æ–¹å‘ï¼‰
        
        Args:
            waypoint_idx: æ‹ç‚¹åœ¨åŽŸå§‹è·¯å¾„ä¸­çš„ç´¢å¼•
        
        Returns: ç›®æ ‡èˆªå‘(弧度)
        Nrrrr£)rpÚ waypoint_idxr¶r·r¸rwrxr
r
r r¤«s    
"
 
cCs|\}}|j}|j|\}}|t|jƒdkry|j|d\}}||}    ||}
|    |    |
|
} | dkry|||    |||
| } tdtd| ƒƒ} || |    } || |
}|| }||}t||ƒ}||
||    }|dkrq|n| }|| |fSt||||ƒ}|||fS)uo
        ç®€åŒ–的横向误差计算 - åŸºäºŽæœ€è¿‘点
        
        Returns: (xte, proj_x, proj_y)
        rg•Ö&è .>rr/r)rerPrIr¨r©r)rpr[rˆr‰rªrŒrÚnxÚnyrwrxZseg_len2r‹Úproj_xÚproj_yZ    xte_vec_xZ    xte_vec_yÚxte_magÚcrossrŽr
r
r Ú_compute_xte_simpleÈs*  
 
 
z#MowerController._compute_xte_simplecQ CsR|jr ddddidœS|jdus|jdurddddidœS|dur%t ¡}|jdur-d}n    |r4||jnd}|r:|n    |jrB|j|nd|_|j\}}|j|jkr|jd}|d|}|d    |}t||ƒ}t    ||ƒ}    t
|    |jƒ}
t |d
ƒr}|j dur€d |_ |j d krt |
ƒ|jkr‘d |_ np|j|
d } tt| |jdƒƒ} tdtd| ƒƒ} d} |\}}t||||ƒ}d}|j |d›d|d›d|d›d|jd›d|d›d|d›d|d›d|›d|
d›d| ›d| ›d|j›d¡|j ¡| | d|j|
|dœdœS|j d kræ|    }t
||jƒ}||jkrd|_ nÌ||jkr7||j}dd|}|j|j|j|}n
d}t|jddƒ}t |ƒt}ddd|}t|jd|||ƒ}t||jdƒ}|j|} tt||jdƒƒ} tdtd| ƒƒ} tt| |jdƒƒ} tdtd| ƒƒ} |\}}t||||ƒ}d}|j |d›d|d›d|d›d|jd›d|d›d|d›d|d›d|›d|d›d| ›d| ›d|d›d|j›d¡|j ¡| | d|j||d œdœS|j dkrt|jƒd    kr|jd    d|jdd}|jd    d    |jdd    }t    ||ƒ}nd}t
||jƒ}||jkr t |ƒ|j kr |j!|_d|_ d|_"|j|_#tt|j|jdƒƒ}|jd\}}t||||ƒ}d}|j |d›d|d›d|d›d|jd›d|d›d|d›d|d›d|›d|d›d|›d!|jd›d|j›d"¡|j ¡|dd#|j|j"d$œdœS|dkr§d    nd%}|t|jdtd&t |ƒdƒƒ} tt| |jdƒƒ} tdtd| ƒƒ} |\}}t||||ƒ}d}|j |d›d|d›d|d›d|jd›d|d›d|d›d|d›d|›d|d›d!| ›ddd›d|j›d'¡|j ¡d| d(|d)œdœS|jdur(d}n
|r0||jnd}|r7|n
|jr@|j|nd|_|j\}}| $|j¡\} }!}"t|jd%d||jd%d    |ƒ}#|j%sÅ|j&sÅ| '¡\}$}%|$durÅ|%d*krÅ|$|j(vrÅd+|_%|$|_)|j |d›d|d›d|d›d|jd›d|j*|$dd›d|j*|$d    d›d|%d›d|$›d| d›d,|j›d-¡|j ¡|j%r×|j*|j)\}&}'|&|}|'|}t||ƒ}%|%|j+krd.|_%d+|_&|j |d›d|d›d|d›d|jd›d|&d›d|'d›d|%d›d|j)›d| d›d,|j›d/¡|j ¡n¸t    ||ƒ}(t
|(|jƒ})|%dkr>|%d}*|jdd|*}n|jd0}t |)ƒt}ddd|}||}t|jd|ƒ}|j|)d } tt||jdƒƒ} tdtd| ƒƒ} tt| |jdƒƒ} tdtd| ƒƒ} |j |d›d|d›d|d›d|jd›d|&d›d|'d›d|%d›d|j)›d| d›d|)d›d| ›d| ›d|d›d|j›d1¡|j ¡| | d2|%|)|d3œdœS|j&r¢| ,|j)¡}+t
|+|jƒ}t |ƒ|j-kr;|j( .|j)¡d.|_&|j |d›d|d›d|d›d|jd›d|j*|j)dd›d|j*|j)d    d›d|j)›d| d›d|d›d4|j›d5¡|j ¡ng|j|d} tt| |jdƒƒ} tdtd| ƒƒ} |j |d›d|d›d|d›d|jd›d|j*|j)dd›d|j*|j)d    d›d|j)›d| d›d|d›d!| ›d|j›d6¡|j ¡d| d7||+d8œdœSt |j#ƒ},t | ƒ}-|j/|j0|,d9t|-dƒ}.t|j/t|j1|.ƒƒ}/t | ƒ}0|j2s    |0|j3kr    d+|_2|j |d›d|d›d|d›d|jd›d|!d›d|"d›d|0d›d|j4›d| d›d,|j›d:¡|j ¡|j2rJ|0|j5krJd.|_2|j |d›d|d›d|d›d|jd›d|!d›d|"d›d|0d›d|j4›d| d›d,|j›d;¡|j ¡| 6|/¡\\}1}2}3}4}5|4|_"t    |2||1|ƒ}6td<td| |j7ƒƒ}7|j8 |7|j9}8t
|6|8ƒ}t
||jƒ}|dkrŽ||j:|nd}9||_:|j;||7_;|j<| |7_<t|j= t|j=|j;ƒƒ|_;t|j= t|j=|j<ƒƒ|_<|j||j>|9|j?|j;|j@|j<} ddt |3ƒ|jA}:t |ƒ};dd|;|jB}t | ƒ}<dd|<|j9}=|:||=d=}>t|:||=ƒ}?d|>d>|?}@|j|@}|jC| d    |jC|jD|_D|j}At|A t|A|jDƒƒ} |j2rft    |"||!|ƒ}6td<td| |j7ƒƒ}7|j8 |7|j9}8t
|6|8ƒ}t
||jƒ}|j|} |jE}|#|jFk}B|#|jGk}Ct | ƒ|jHdksƒt |ƒtd?kr›|jId    7_I|jI|jJkršd|_Id|_;d|_<nd|_I|j2sÜ|BrÁtd9td|#|jFƒƒ}D|Cr½|Dtd|#|jGƒ9}D||D9}|CrÜ|d9}t | ƒd@ksØt |ƒtdAkrÜ|d09}|j|j!krJ|j2sJ|Brí|jKn|jKd}Et |ƒdBkrJ||EkrJ|1|2}}t||||ƒ}|j |d›d|d›d|d›d|jd›d|d›d|d›d|d›d|j"›d| d›d|d›dC|Ed›d|j›dD¡|j ¡|E}|jL|BrQdnd}F||j#}G|F|}H|j#t|H t|H|Gƒƒ7_#|j|jkrt |ƒdEkr€|jM d|_#n"t |ƒdEkr“|j2s“|jM d|_#|j#dkr£t |ƒd?kr£d|_#|#|jNkr´d+|_ddddidœS|#|jNdkrÞ|j"|jOdFkrÞt |ƒd9krÞt | ƒd>krÞd+|_ddddidœS|durå|nt ¡}I|j#}J|1|2}}t||||ƒ}|jdk    r tt|J|jdƒƒnd}Ktdtd|Kƒƒ}K|jdk    r&tt| |jdƒƒnd}Ltdtd|Lƒƒ}L|j |Id›d|d›d|d›d|jd›d|d›d|d›d|d›d|j"›d| d›d|d›d|K›d|L›d|Jd›d|j›dG¡|j ¡|jdk    r„tt|j#|jdƒƒnd} tdtd| ƒƒ} | dk
r|j
st |ƒdBk
r|jdk    r°tt|jK|jdƒƒnd}M|Mdk
r|1|2}}t||||ƒ}|j |Id›d|d›d|d›d|jd›d|d›d|d›d|d›d|j"›d| d›d|d›d|M›dtt| |jdƒƒ›d|jKd›d|j›dH¡|j ¡|M} |jK|_#|jdk
r(tt| |jdƒƒnd} tdtd| ƒƒ} |j
r8dndI}N|N||f|j|||j#| |1|2f|3|#dJœ
}O|I}P|1|2}}t||||ƒ}|j |Pd›d|d›d|d›d|jd›d|d›d|d›d|d›d|j"›d| d›d|d›d| ›d| ›d|j#d›d|j›d|N›dK¡|j ¡| | |OdœS)LzŒCompute forward and turn outputs mapped to [-100,100].
        
        Returns dict with keys: forward(int), turn(int), info(dict)
        rÚstatusrf)ÚforwardÚturnÚinfoNZno_stategyé&1¬Œ?rrrgrCÚmovegÍÌÌÌÌÌô?édiœÿÿÿz.3fú,z,0.000,z,rotate_to_start
Zrotate_to_start)rÁrbÚ heading_errÚ dist_to_startÚaligngš™™™™™Ù?rr/r-r#r(r z,moving_to_start
Zmoving_to_start)rÁrbrÉrÈz,0,z,reached_start
Z reached_start)rÁrbZ advanced_idxrgš™™™™™©?z,align_at_start
Zalign_at_start)rÁrÈr%Tz,0.000,0,0,0.000,z,enter_waypoint_approach
Fz,reached_waypoint
gffffffæ?z,approaching_waypoint
Zapproaching_waypoint)rÁÚ waypoint_distrÈÚ target_speedz ,0,0,0.000,z,exit_waypoint_turn
z,waypoint_turning
Zwaypoint_turning)rÁrÈÚtarget_headingr*z,enter_recovery
z,exit_recovery
r§gUUUUUUÕ?rg@g333333Ã?r7g@z,0,0,z,enforce_min_speed
g333333@rz    ,pre_map
z,force_min_forward
Zrunning)
rÁr[r\Údesired_headingrÈrRÚ yawrate_cmdZ    target_xyÚpath_curvatureÚ
final_distÚ
)Prfr[r\ÚtimerUrbr`rPrrr rµrgr‘r=rrOÚroundrr¨r©rnroÚflushr8r:r;r"rr<rrIr9rardrRrÀrhrir¢rlrjrKrDr¤rFÚaddr&r$r'rcr@rerAr³r.rr0rTrVrWrXrr4r5r1r2r3rSrBr+r,r6rYrZr?rrr)rQ)QrprƒÚdtrˆr‰Z start_pointrwrxrÉZdesired_heading_to_startZheading_err_to_startrÏZ turn_signalZforward_signalZtarget_xZtarget_yZ target_distZ
target_idxrÎrÈZ
dist_ratioZ speed_scaleZbase_target_speedZ heading_ratioZ    err_scalerÌZpath_dxZpath_dyZdesired_start_headingZheading_err_finalÚf_sigrrŽr¼r½rÑr¹rËZ
waypoint_xZ
waypoint_yZdesired_heading_to_waypointZheading_err_to_waypointZ speed_ratiorÍZ actual_speedr¾Zbase_lookaheadZ    lookaheadZ dist_to_pathÚlxÚlyrÐr¬rªZ path_headingZxte_normalizedZxte_correctionZ heading_err_dZ
curv_scaleZheading_err_absZxte_absZ    xte_scaleZ
geom_scaleZ    min_scaleZ blend_scalerZ in_slow_zoneZin_final_approachZ
dist_scaleZ dynamic_minrZ speed_changeZ
max_changeZlog_tZ pre_map_speedZpre_map_forwardZ pre_map_turnZ forced_signalrÁrÄr‹r
r
r Úcompute_controlôs>
 
 
 
 
 (ÿÿÿÿþþþ
þ
 
þ   
 
(ÿÿÿÿþþþþ
þ
 
þ  (ÿÿÿÿþþþ
þ
"(ÿÿÿÿþþþ
þ
 "
& 
 
 (ÿþýýü
ü
 
 (ÿÿþþý
ý 
 
 
 (ÿÿþþýýýýý
ý
 
ü (ÿþýüü
ü (ÿþýüüü
ü
 
ý
(ÿÿÿÿþ
þ
(ÿÿÿÿþ
þ
 ÿ
þ
ý 
ÿ 
 
 
&€ 
(ÿÿÿÿþþý
ý
 
€ 
&&(ÿÿÿÿþþþþþ
ý
( (
 
(ÿÿÿÿþþþþý
ý
&ö
(ÿÿÿÿþþþþþý
ý
 zMowerController.compute_control)Nrž) Ú__name__Ú
__module__Ú __qualname__rr„r…rrr¢r¤r³rÀrÛr
r
r
r r #s

 
&H*,r Ú__main__r¥r7)rr§rérÂgY@rÃrGr)Ú__doc__ÚmathrrrrrrrÓr r rÜÚjsonrPÚcr„rMrrrÛÚoutÚprintrÚfr\rZhdr[rŒrr
r
r
r Ú<module>s6     K  
ò