yincheng.zhong
2025-11-24 346cc7d685283df529aadbcf9c156de040ce44f9
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
o
*#i.ã @sŠdZddlmZddlZddlZddlmZddlmZmZddl m
Z
m Z m Z eddd   ej d
Zdtdd„Zdudd„Zdvdwdd„Zdxdd„Zdddddddd d!d"d#d$œ dyd;d<„ZdzdAdB„Zd{d|dJdK„Zd}dOdP„Zd~dSdT„ZeGdUdV„dVƒƒZeGdWdX„dXƒƒZeGdYdZ„dZƒƒZeGd[d\„d\ƒƒZeGd]d^„d^ƒƒZeGd_d`„d`ƒƒZGdadb„dbƒZddedf„Zd€didj„Z ddldm„Z!d‚dodp„Z"dƒdrds„Z#dS)„u€
与 STM32H7 äº¤äº’的协议封装:
- æž„造 $GPRMI / $GPIMU å¥å­
- è§£æž PythonLink æŽ§åˆ¶å¸§
- è§£æž ASCII çŠ¶æ€æŠ¥æ–‡
é)Ú annotationsN)Ú    dataclass)ÚdatetimeÚtimezone)ÚCallableÚOptionalÚTuplei¼éé©ÚtzinfoÚdtrÚreturncCs$|jdur |jtjdS| tj¡S)Nr )r ÚreplacerÚutcZ
astimezone)r ©rú1E:\GIT\Lawnmower_STM32H7\python\hitl\protocols.pyÚ _ensure_utcs
 rÚ timestampúTuple[int, float]cCs8t|ƒ}|t}| ¡}t|dƒ}||d}||fS)Ni€:    )rÚ   GPS_EPOCHÚ total_secondsÚint)rr ÚdeltarÚweekÚtowrrrÚgps_week_and_tows   réÚdecimalsrÚstrcCsDt|ƒ}| d¡}|jd}|d|›d› d¡d}|›d|›S)Nz%H%M%Sg€„.AÚ.Úfr   )rÚstrftimeZ microsecondÚsplit)rrr ÚbaseÚfracZfrac_strrrrÚ format_hhmmss"s
 
 
r&Úsentence_without_starcCs*d}|dd…D]}|t|ƒN}q|d›S)Nrr  Z02X)Úord)r'ZcsÚchrrrÚ nmea_checksum*sr*gü©ñÒMb€?g{®Gáz”?gš™™™™™¹?çð?ééé) Úlat_stdÚlon_stdÚalt_stdÚvel_stdÚ heading_stdÚ   pitch_stdÚroll_stdÚ
baseline_mÚ sat_countÚambiguity_countÚqualityÚlat_degÚfloatÚlon_degÚalt_mÚeast_velÚ  north_velÚup_velÚ heading_degÚ pitch_degÚroll_degr/r0r1r2r3r4r5r6r7r8r9Úbytesc
Csæt|ƒ}t|dd}t|ƒ\}}|t|ƒ|d›|d›|d›|d›|
d›| d›| d›|d›|d›|d›| d›|d›|d›|   d›|d›|d›|d›|d›tt|ƒƒtt|ƒƒtt|ƒƒg}dd |¡}t|ƒ}|›d|›d}| d   ¡S)
Né©rz.3fz.9fz$GPFMI,ú,Ú*ú
Úascii)rr&rrrÚjoinr*Úencode)rr:r<r=r>r?r@rArBrCr/r0r1r2r3r4r5r6r7r8r9Úutc_strrrÚfieldsÚbodyÚchecksumÚsentencerrrÚbuild_gprmi_sentence1s>  
 
 
é
rRÚaccel_gúTuple[float, float, float]Ú
gyro_deg_sÚ temperature_cc   CsŒt|ƒ}t|dd}||dd›|dd›|dd›|dd›|dd›|dd›|d›g}dd  |¡}t|ƒ}|›d
|›d }| d ¡S) NrrFrz+.4fr   rEz.2fz$GPIMU,rGrHrIrJ)rr&rKr*rL)  rrSrUrVrMrNrOrPrQrrrÚbuild_gpimu_sentencems 
 
 
 
 
 
ø 
rWéÜéôçø?ÚvalueÚcenterÚspanÚ max_speedcCst|||ddƒ}||S)Ngð¿r+)Ú_clamp)r[r\r]r^ZratiorrrÚ_pwm_to_velocity‡sr`ÚvalÚmin_valÚmax_valcCst|t||ƒƒS©N)ÚmaxÚmin)rarbrcrrrr_Œsr_ÚpayloadúTuple[float, float]cCstt|ƒdkrt d|¡\}}||fSt|ƒdkr1t d|¡\}}t|ƒ}t t|dd¡}||fStdt|ƒ›ƒ‚)Néz<ffr.z<HHg€V@)r^u ä¸æ”¯æŒçš„æŽ§åˆ¶è´Ÿè½½é•¿åº¦: )ÚlenÚstructÚunpackr`ÚmathÚradiansÚ
ValueError)rgÚforwardÚturnÚ steering_pwmÚ throttle_pwmrrrÚ_decode_payloads  rtc@seZdZUded<ded<dS)ÚPythonLinkFramer;rprqN©Ú__name__Ú
__module__Ú __qualname__Ú__annotations__rrrrruó
 ruc@seZdZUded<ded<dS)ÚPythonAsciiMessagerÚtagz list[str]rNNrvrrrrr|£r{r|c@s~eZdZUded<ded<ded<ded<ded<ded    <ded
<ded <ded <ded <ded<ded<ded<ded<dS)Ú ControlStatusr;Ú forward_mpsÚ  turn_rateÚfreq_hzrrrrsrÚstageÚ timestamp_msÚeastÚnorthÚuprAÚtarget_heading_degÚ target_eastÚ target_northNrvrrrrr~©s
 r~c@sVeZdZUded<ded<ded<ded<ded<ded<ded<ded <ded
<d S) Ú
PoseStatusr;r„r…r†rArBrCrˆr‰rƒNrvrrrrrŠ»s
 rŠc@s.eZdZUded<ded<ded<ded<dS)Ú StateStatusrr‚r;Úcross_track_errorÚheading_error_degrƒNrvrrrrr‹Ès
 
 r‹c@s&eZdZUded<ded<ded<dS)Ú StackStatusrÚ task_namerÚstack_high_waterÚheap_free_bytesNrvrrrrrŽÐs
 rŽc@sNeZdZdZdZdZdZddd„Zdd d „Zddd„Z ddd„Z
ddd„Z dS)ÚPythonLinkDecoderu>
    è§£æž PythonLink æŽ§åˆ¶å¸§ (0xAA 0x55 ... 0D 0A)。
    sªUs
éÚon_frameú!Callable[[PythonLinkFrame], None]cCstƒ|_||_dSrd)Ú  bytearrayÚ_bufferÚ _on_frame)Úselfr”rrrÚ__init__às
zPythonLinkDecoder.__init__ÚdatarDcCsÌ|sdS|j |¡  | ¡}|dkr|j ¡dS|dkr$|jd|…=t|jƒdkr-dS| ¡}|dus<t|jƒ|kr>dSt|jd|…ƒ}|jd|…=z| |¡}|rZ| |¡Wn  t ydYq
wq )NTré  )
r—ÚextendÚ _find_headerÚclearrjÚ_expected_frame_lengthrDÚ _parse_framer˜Ú    Exception)r™r›ÚstartZ   frame_lenÚframeÚparsedrrrÚfeedäs4 
 
 
€ þîzPythonLinkDecoder.feedrrcCst|jƒ}| |j¡}|Srd)rDr—ÚfindÚ FRAME_HEADER)r™r›Úidxrrrržþs
 zPythonLinkDecoder._find_headerú Optional[int]cCs8t|jƒdkr dSt |jdd…d¡}d|ddS)NérÚlittlerE)rjr—rÚ
from_bytes)r™Ú payload_lenrrrr sz(PythonLinkDecoder._expected_frame_lengthr¤úOptional[PythonLinkFrame]c Cs²| |j¡r | |j¡sdS|d}||jkrdSt |dd…d¡}d}||}|||…}t |||d…d¡}t|d|…ƒd@}||krMtdƒ‚t  |ƒ\} }
t
|   |
dS)NrErr«r¬iÿÿu校验和不匹配)rprq) Ú
startswithr¨ÚendswithÚ FRAME_FOOTERÚ TYPE_CONTROLrr­Úsumrortru) r™r¤Z
frame_typer®Z payload_startZ payload_endrgZchecksum_receivedZ checksum_calcrprqrrrr¡    s
   zPythonLinkDecoder._parse_frameN)r”r•)r›rD)rr)rrª)r¤rDrr¯) rwrxryÚ__doc__r¨r²r³ršr¦ržr r¡rrrrr’×s
 
 
 
r’ÚlineúOptional[PythonAsciiMessage]c Csà|sdS| ¡}| d¡sdSd}t|ƒ}| d¡}|dkr*|}||d|d…}|d|…}d}|D]}|t|ƒN}q4|rWzt|dƒ}Wn
tyPYdSw||krWdS| d   ¡}|s`dS|d} |dd…}
t| |
d
S) Nú$ÚrHéÿÿÿÿr rrr“rG)r}rN)    Ústripr°rjr§r(rror#r|) r¶Z checksum_strZdata_endZstar_idxrgZcalcr)ZprovidedÚpartsr}rNrrrÚparse_ascii_messages:
 
  ÿ
  r½ÚmsgúOptional[ControlStatus]cCs&|j ¡dkst|jƒdkrdSzft|jdƒ}t|jdƒ}t|jdƒ}tt|jdƒƒ}tt|jdƒƒ}|jd}t|jd   ƒ}t|jd
ƒ}t|jd ƒ} t|jd ƒ}
t|jd ƒ} t|jdƒ} t|jdƒ} t|jdƒ}Wn
ty€YdSwt||||||||| |
| | | |dS)NZCTRLérr  rErr.r«r
érirœé
é é é )rr€rrrrsr‚rƒr„r…r†rAr‡rˆr‰)r}ÚupperrjrNr;rror~)r¾rprqZfreqZsteeringZthrottler‚rr„r…r†ÚheadingZtarget_headingÚtarget_eÚtarget_nrrrÚdecode_control_status:sH
 ÿòrÊúOptional[PoseStatus]c
Csä|j ¡dkst|jƒdkrdSzJt|jdƒ}t|jdƒ}t|jdƒ}t|jdƒ}t|jdƒ}t|jdƒ}t|jd   ƒ}t|jd
ƒ}t|jƒdkrWt|jdƒnd }   Wn
tydYdSwt||||||||| d  S) NZPOSErirr  rErr.r«r
rÁç)  r„r…r†rArBrCrˆr‰rƒ)r}rÆrjrNr;rorŠ)
r¾r„r…r†rÇZpitchZrollrÈrÉrrrrÚdecode_pose_status`s4$ ÿ÷rÍúOptional[StateStatus]cCs|j ¡dkst|jƒdkrdS|jd}z t|jdƒ}t|jdƒ}t|jƒdkr2t|jdƒnd}Wn
ty?YdSwt||||dS)NZSTATErrr   rErÌ)r‚rŒrrƒ)r}rÆrjrNr;ror‹)r¾r‚ZxteZ heading_errrrrrÚdecode_state_status|s 
$ ÿürÏúOptional[StackStatus]cCsv|j ¡dkst|jƒdkrdS|jd}ztt|jdƒƒ}tt|jdƒƒ}Wn
ty3YdSwt|||dS)NZSTACKrrr rE)rrr‘)r}rÆrjrNrr;rorŽ)r¾ZtaskZstack_hwZ heap_freerrrÚdecode_stack_statusŽs
 ÿþrÑ)r rrr)rrrr)r)rrrrrr)r'rrr),rrr:r;r<r;r=r;r>r;r?r;r@r;rAr;rBr;rCr;r/r;r0r;r1r;r2r;r3r;r4r;r5r;r6r;r7rr8rr9rrrD)
rrrSrTrUrTrVr;rrD)rXrYrZ)
r[rr\rr]rr^r;rr;)rar;rbr;rcr;rr;)rgrDrrh)r¶rrr·)r¾r|rr¿)r¾r|rrË)r¾r|rrÎ)r¾r|rrÐ)$rµÚ
__future__rrmrkZ dataclassesrrrÚtypingrrrrrrrr&r*rRrWr`r_rtrur|r~rŠr‹rŽr’r½rÊrÍrÏrÑrrrrÚ<module>s\  
 
   
ê
< 
 
 
D
 
&