From c37bd480c07bcd3743656154d759b68b4070d8ef Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 19 Dec 2024 12:57:45 +0000 Subject: [PATCH] Deployed 6469e62 to latest with MkDocs 1.4.3 and mike 2.2.0.dev0 --- .../control_data_collecting_tool/index.html | 125 +++++++++++++++++- .../resource/boundary.png | Bin 0 -> 23723 bytes .../resource/boundary_counter_clockwise.png | Bin 0 -> 26226 bytes .../resource/circumscribing_circle.png | Bin 0 -> 41673 bytes ...ircumscribing_circle_counter_clockwise.png | Bin 0 -> 43624 bytes .../resource/common_tangent.png | Bin 0 -> 47572 bytes .../common_tangent_counter_clockwise.png | Bin 0 -> 49721 bytes .../resource/looking_ahead.png | Bin 0 -> 17543 bytes .../resource/whole_trajectory.png | Bin 0 -> 39916 bytes latest/search/search_index.json | 2 +- latest/sitemap.xml.gz | Bin 933 -> 933 bytes 11 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 latest/control_data_collecting_tool/resource/boundary.png create mode 100644 latest/control_data_collecting_tool/resource/boundary_counter_clockwise.png create mode 100644 latest/control_data_collecting_tool/resource/circumscribing_circle.png create mode 100644 latest/control_data_collecting_tool/resource/circumscribing_circle_counter_clockwise.png create mode 100644 latest/control_data_collecting_tool/resource/common_tangent.png create mode 100644 latest/control_data_collecting_tool/resource/common_tangent_counter_clockwise.png create mode 100644 latest/control_data_collecting_tool/resource/looking_ahead.png create mode 100644 latest/control_data_collecting_tool/resource/whole_trajectory.png diff --git a/latest/control_data_collecting_tool/index.html b/latest/control_data_collecting_tool/index.html index 90a46190..270ea9cc 100644 --- a/latest/control_data_collecting_tool/index.html +++ b/latest/control_data_collecting_tool/index.html @@ -3104,6 +3104,33 @@ Specify data collection range + + +
  • + + Trajectory generation and data collection logic + + + +
  • @@ -3324,6 +3351,100 @@

    Specify data collection range

  • +

    Trajectory generation and data collection logic#

    + + + +

    Parameter#

    There are parameters that are common to all trajectories and parameters that are specific to each trajectory.

    Common Parameters#

    @@ -3420,7 +3541,7 @@

    Common Parametersmax_lateral_accel double Max lateral acceleration limit [m/s^2] -2.00 +2.70 ABS_STEER_RATE_MIN @@ -3777,7 +3898,7 @@

    Course-Specific Parameterslook_ahead_distance double The distance referenced ahead of the vehicle for collecting steering angle data [m] -15.0 +35.0 diff --git a/latest/control_data_collecting_tool/resource/boundary.png b/latest/control_data_collecting_tool/resource/boundary.png new file mode 100644 index 0000000000000000000000000000000000000000..8cc3b88ea9d6a5280afaca7c5b216077449ee9ca GIT binary patch literal 23723 zcmdqJhdb8q|2}@JG*FU6Wz=0F$v26E=i_{w=M|uRle4Y8 zow(2eAyL5{Hdn4VI3E-izWo3Ff{?wFwQ!U9L?J$8orBsbX9|Vcocv4oNHN2fLNVr0 zS3YFmmN@*&)y?2U*QfE()S0Ba8#Qe7=nn;!-1w>zzhlL#8!0Kzf}UI+&S&74JV|f7 zaUX5{J}QG+#GV~0N_Vv%UB7j=jV~^4etwsj;>t&ncV#OJlKU#NYicYfv|Y}(B|4AF zY$+9CQpP`Jm)&Byl*oS)h-OHk;h%)#bemaNSRBO#e5v@y?kK%3`MuglltBD6cPpC` ze##>Ca0Nep+GS-xQNfQ}ga4oVV=XE3532;XFxuMMTB+vQoPBrYzGjS&RryAiJpTXR z(v+!i_#HAgzuzpXT(+L9QMI)9g7nSR>#4hU-}?Mn_h>N3`+>%cd!e$N8}{fVX+1o8 zXYB7^-aUK#!gi^KM@Aa-x^LRFDR*(YrQUrhJL96^)6=&={rbYUz>h)f$&>Pdfq}C>ikChf_+fm+#)cmo z^xD2X>3Q+ezr=I zGfT~(ddl6*?r{i+?%)KwcLDd0_&e3h&%C(!Lnz7P&t8|&w%Sj3wvSIw_wp>yuCXut zy9J;8(6rc_Q^x65Mv_P1iN_~jUL8F7;K2i-fq8|w?uaWxO<}HW?*561oZQ!jME}i< z)+fnd8=IP1W!6;|pp_^cCVK9Zh})Q12#;djS=V2;f7xZ2m-^N9y*mB${Q2`^W2MZj zJUlv%j-u5u!q%Tt4%H;dCt&5G=h`Ow>aB-=zL8s;YApNoX%j2!5q0%-%yMItH5)in z4&7W`cdp%M*~`hv2_f1&v6V{Qvt7}vvu-T z-r;bu3*VlYWGU2$Mo<;Ch@lQ6*uPo!rDZ3;j zzE)IJ@H_ixYlpCKa$ainSzfdpv2REX`10oBkM>0qDwSPBzl7Q)=Euxq(mVb6{*m#C z35%Yps3*pGn>rFRf4#lj(va(T?&K3A$IAAZPuuMUo%7u%dnugq9-DpFZ@{m>Z^qoCDw{vo&MvLZ!u1ycg^flT2ddI@eZPHuR(P1`{ z`+EZdLw;g%l5TcsezdvpniO_7zx&5ts*@j%cW!V~Q0xfB+s^aZyBO)gFL&{c6xp7}fYBg1vHttM9VW?SL4Y_s<( z_Gl;e%kdpo?sl?SrK@cGDelWNafSII@k^51Ne(!ZW2a>M{@>Hu1gUK6dhU0wqay{v zJ9l2^l68rcv0GkR>@#k@cK=!a$ian$g}TZd??sP3iSeylg6Mg8lEpp>@$&W*7}71r z&5sr*<8MUp0&?>5d4tdLh4vQHDw-vbSB1{C6}Y>(yMM{H*6BM@vj6mJv;NQbXJ=;} zW`4O&7B4R{;~$Tik>LV{T&vo6x!I1Jb$xlmZ(BG-EmmQxdwLV>d;7mU)Jl?z>+kQ^ ztYYKluEXlrq^d{cPS(k86+6GSJe0@!!>x6FT68mmKSB{dqAo*5ecwLRE6fWzIy!Pn zJ9IoKvd7V|ZAe|W&+ys#G8#)+S(&k(H%nM{CdqTLQuf@ed$i1YYvPOqw~&+lHB*0l ze4LK_FJB)UhPt+U#cUO~+PH07)q1Jc5=P+y-Cnt(Gxmj15qvrm2wahC)0g58T>MlM zCmtv5*u`sotvAkkEfZ7s-yf!ZH<=Yujz2tFF#c(K!NNqfWk~+-5LvZj$9j;+%)UQ4 z_4VnQm~tMU#MIPO&3{Wr{5M$Qb>7V$QLc*mD8f`aw2?}6^2SO0WbyKa`=nL&Lz)`f z0~Qo7_K1jxQsLr-4>|4L)jEocWrn6+mM*(lGA&3gGp_mm^vuA|H~YfE!h(4eldi8^ z6VIitoW*gBF6h7dw}0iX|2qqxiPaj^rf>}n4K;1;^xWLoe}4yMN0YHjI0oH4Jz+61 zsyJoH_nX<+SlHM;M()*5EZ0tuypx)`8!?D9Y7Rax2CR16F@fBEud_wL=u z@+(m`uV-ZR^%PxU39BaC=IAb&aA$FTCfm8MPR#WF{ri_%-qyOeA~n~I{K~JNn^#a! zKy8c8dwy+ZMB>6%T1v`}8#ivO-LPQ~KmS^!h8s6;R&&Zab*sI*GH|2T%GoFLwkZr{GmDeDr9!xQB$h{}x;bI@LKqGH!>US3iw`wWq})-f{|cPB^DDsF#X zi=-4;Q&S^G-;Y2(KhTh7^z^%P$Q>GOhrIkR_xZFK6RNm)#I^$$bhE9F^(`M&RXz98 zNMN@Qb^wSXH7(8Y-;`}bLxc3yKbr#r0&s$?>JkU!-l|9J8EVe%OYD1O_?(;T;1#pF zL>ac|Gs>+&M=2_05`N})V`D3DXcA4Eo15`5QF|3mK8`9WQF>PN?~j=2ooxpMCOt#t zr;SvKZ#l18vxb$EQ|sQrt4mW&%S$uG_-Ox?Yc@z1W8c)Yw028KysoJ?!_i)~YSriT zW7~hey{y@oer$ZAL9vtSWJ{6}n;nvo=XA66lT+D#-QC?{q3&*OcM}t}w6vHgSnH4F z<^F&uVtw-`PQ=Brw5^biUqFC>pz!cbeU3{@OA9^1KKBiun@kNf`U6EI zu$@vC*aNyyEk-`7T#RTI1^O$u<^w%{$k< zcXq|=sswF$Y1_C*^77BJ=>2CZDk~ioya8|~kT+!QljZLSQJp05$$Jg`%n5cWTKadf zw?4TZze_QCdugk@#}vg3`}xG^9+2kTKtRqb%W9)n=hq$aV=_l& zpl}|%Lc?Kde0TLCFq6u2lR}#x&+bL1vxJEuWuzK&DtN{M<4xl0BVuFw3)(GSelGI5 zX5!XKf6#U0lEvYfvGH=Am{TzucL)dszQ4If{8E$1!K;6|x9AU0C&~#v32(Y2>E!Hu zPyddr%TNm5kAh%s0PI`6fm01tCG+Id__*W0>H=8#jNV<@s~Ih54nP5fB+WBFlwHpu zcAge6pj^fV1X`gYrNuzwdubM9b zQiSI@_q{q_xoLW|UB}F92ZewGe`X%5rWfWC7r)nZr&9I8$OG#1^z@9+^(Bj6{4VG{ z+qtH15pboq4{t zNd3CPN|tcK&Ck1&f`R&7R4vH0)r@AqqXQqfTS zyRDSEsnJ50YF8n`RJ6Qw4R!q(@}&Fn;>^qDOU6Ene?8}ib5J77hiF}gJ*J1$L%HQe zm~Pq^&G`YpIWGSFk?lF>B;mJ1PsVnYZrS>+eun`3nhM;-xw*MpJtu4BkjC(OpN4F@ zK1`4NszxGEY;*793JeOO>;Lwc9jpD_CPj_+A=0dr8OLe>Ygd!Xi!Y64XNs3=3uoG@ zmlo&e5M>5S-8w*AG~|AV{?9u{@<$asy}WF{JWz?7$PlFut2(sHmwKW#>%?QXh4J#{ zT*qDYipz33a^ts}!%_oLl|KFW5ksS`rJQ_jQu{Dep=x&g_rS0GoTKzA#<56mS&x!^ zmg0cJ8sA(r#CoeKDfv3vvWHD@4+L)Fpy=kQ=-z|2EUFL&?RGtvJrG@eT*>qT?6^(1L0Hf}6ItRiDG;(T{j zgzd6YWev-=VK7P!+$wpABiZ}kUP?}@6C*0w1MkIudonh;hR4TO-CD;=0>n|8leADD z7=_0=ZZgMn9aHvBV^IpzNKZ*gsR@{N$^YfnTWjOHLh5h0u1gX7^Yq9d?+0AM?IvFos+#MTpIDF(t^V`eYXIh<^k0nT2 z0_s?)ZkF*k=MX&eHke!9qoecq!QK}*vL8xIZCl|4QEn z52$S(gZtBuCHR$g?vRj(MCD{cQzZ7p%%RIm*Vb z*y3pJl7H{(R|AwLjq2pi4*xfgIb@u6Cwoq;+u(omj9uPs`D@dU7Sz+s-kcuz@^B5s zxwqy%ik2sK{IsHO>J1WuD);37#9Vb^j~h%jYiu)aGopL>@}=C;>~FyO5~LJ%dvq49 z&h_$_+Kae+0kOoKd$laiovU5Hr)v+gjdAcVJ3e$6DBumUOlvrk{T;_H3x-%sJQ@3z z`JO57Dii8S*~gEazki>zvkBAG)zkYBBwSRHU9X^tCJ^l}5Th`DA&%=-m7P<<}X7$gVF*}zzD9t8+E1xx5!Ru~bJVqv4&~vrA)x)2FXr zzYa>o#+5m96Tld$g3{6){J*U1(8Mha+xs*|J5ddN(NR_6$I@Q^BtD+<-|4>hw(6FM zNYD7y#YqfTchn~TlPU`0O}TQqrnK~CMTOdml`D^F?RVrHXaTO>F1(y?yVOdf{uHdr|fR{p!`5czB*q z@STV^=Xia&WsAK%(n#<2({C?T0#nq4@amnU3Wm=PDJuC2X+GX3Gow5RBeJug+< zjCSl@IU(O=Bi-*cHrDVcIXCT|tg9GOEK24bEFYKx&QQ4tn)4xBmb@!S`fN3JInIDN zU?((2`41jj3T0-s*;n}aT(!B4L1S{tp!IbhLF}ZmipqeoqN65KISC5S*-n4T6uOd` zcAsP%h=_;)1G|3*G*VZvv9UQ$bXP75`)oa9{`>5zpCRUNuDz6>zwqpsZ^}s>vvo9J z^BWhwWo0e|v@oENSe$9^dz#bs0eR@2jn?09^K_JNVtdQm%cT}C9cmB!ph&wiAK$q-&kb*8*woxN z&z5niyMN}l?Z$KTB__kq-6Y-D%6ZYP-7v)`Cw96|CSW1phpEp!WGS>KP=bT$h~&wlEXoE zy2mU^!LoTH5*>hCCh{}$dxSnaN*ezB*?TxIgr8npq36g1ksVqQWD;i)-2W-{d zeO^QR^7Y7`1*eWx-%2&B+wU9j2MiAi`q0tQ89X;R+oRJ>eFJt0$?3~0OHDm}eUeL2 zvczSh)zVT{@axqvFfyvEtMC0)FZF7@OTBLVH;TPZlOt!=iRUVRU6?5ww`@6j<#pW* zYn}mC$GSHD0KtUFS*w}3YtWS-4!b6%GI!~P;FV>r{xKN%7BFow+jB}zT#_<2xz05H zn{P>UsQLKRo`VPDU%U`G`<~w^4#{E`33jerap}4_$L7tOW4YAJdImU^!koe*B90(4 zQdHarjHKibKl&}==63jDIYqX6q&&OwCi>cr!NH4mW?=%KM3|xlPaOutn+l4mNJdHD zy9TKCytVbpyD=`YH78v4#cTZ5^AwzxXJ+|vuVKmQEI7S;E4?q4Oj8 zp?yi$LUMDZvwzcaH=}VhP7e+aZkVu^uJ|eA|KZKU%&k_tvMC!>TMbVy`TCA+EBpTF z@dTgVA;98tKy=&oB6OigTN}1lR*SgEhtjKQ-Hv@EawETWKO^47qX#)=VP^F||2va6DE&TD^DB~^qlJ^ok50(%5 zf2N`7WBitNqO`ugzWX)R={}l^j}2*>Xa~)K5J92T52;bvK)`o1Bb@KX$1_ZCdX=-x z+%j%YW4iHhAZeAWdkpQuo0mp{2w|IUoz(Ek%F0e00_*wd;jhn4ldleb$5Nbg5e#Fv zzk+{4_Q}b80Ja=)vK5O1Dihh-o3=CXiM`KQ+^+n?W~~xBI-K!68Ej#iVQBCWg3?ai zYcKzN-3hje4~Tonh-#QvN4Hrf6iuD>J?UF7=T8LJ&V)suKE0&fcOz{?&3Y~&jlDeV(+bAwhSj~sK0ldWmRjx^>M}32RrK-P9A>L zHX%s?i}>bikQ&?P7v@Kb7N^fFEH0iZa1%vaDlQvd!IrVtEUX>)7mOg@hGX@@6y^Ld zrNrE~{KSmX@R_yD%zWTjTVGK1o{_)qt-Du^&J~>d0ojlWwlu85b~NDNL+I|#F7Ey# zb23t4W5cQm=2BCIUAtc$1a{byjsZxX9Kg`r2^W{Q*$Z543-_}ZER}yT>`%HLFU7KP z+YvXn+&EE{)D>tLx!t>2(0lI#!(_~|jczj?vLBMxW=f{N_indQ*4g=z^oVb^@?9(C zrL9W0M#6!MTh4t7-YFt-_s({yhS#?G*}DQF_pvECUgPEE-Ob1M z+d;ZQ=a=fzyKA&{eubG!yIZHWdM_PvyLOFr`}UxWjErVSJO!FZ5<94uI+#2F`e)b8 zM+vCtmvnvS+^{AyGZT+Flpz&SQ1E&o?feZUc_Mi!PsYHBomLYdZR!Q=+lUsu`DyP*pWA@q=y>ZZI)Sks*IZ%$WAzgXqXxiT)T zhq=Q*Qetpghk}%Eu%vuTcC;V@|FW8znu>{u)r9QQ69RK#SKjI1Fww1k>HFc}A$g;> z@@qdm@0*@Iij98%qdvK*$>{9(J}L!dnB!Q-A;2Fim(5{L_gR!2WkE4xNyo-4maAgk zJD4TT>FgYN?&jtJYV7F*A5|N(7t1PB7Z=HGieXh+^t!DYCMMiKFBDGWdBtsh+~sy9 z-peicn~n2^n1!GKi%C7ANyOlR*OMOdzceD6Ic{w{+FZ5#RnWijrM}X=*HXT^4Au-`n+cNcr^riEX5Cju(dI9^6l%1qL=~^H81M|M~W~eBbke6(#72 z30Zecd$*IL0VPdCoayH4*Ag$RN_1veN3U+wVH}bhsQxC;vr6N~e51P$)#>F((YzgD z3UJbMez|PNnII8iCg7`=*3;dsoA{DhGW2$$*X+FSFW-Zg{a2>VdmU9)j!o247T6W^ z@k9P-k*1rQG&slyDJdo7k+s;bt3{nayHI(r-E7E>;ga=YX{)2qZ22a3cK_$kpUcpx zq-sceO!4Dy8f41!G69FPQpNR)j~X!!J+*Q;I3vZp`umDyBXnsemXy0+eS3B`Uu!PA zWq40IOP&ZGjJKz^H`?UyU}t5~iALH6zhKXbNt%Df;Mnx^9znsHp;)TkZSXb@gHLlN zl9w0CQ7C*gTDa7r&gHaJR#mOoalnyl{o>n|4o!VWpB46clz=nRXgq*)_WikOeQTaG z8NW@p*po3C7Gv)0Ho8awK5=nY|I+K7FZ5pz%gD)_U321pYUf6wo@UX@4@&n|Np1Z* z+!CYU^^bH)ipz64!)$^=Wcwn4x+W$jD6^L1*)l+G-5;;l4;zFb_BHS03&2?hOw{-6#n6 zv6&euFg*rWK^v?h6cacCx#fjPt8x|@VK$}AO^NK@o0D$rpV5=b;_wY`@^w|Hsv zx+9xrK=bvbq-)<}C;@}0cKmo)-gV`=BaDYMqX_J&%Um35T&a8I&oWQH9FOPWb&QOS zuY{?3=1ip>Xb~(xcwr7oP8KJ2aR9SBZO+!n6eo--(4%$dnoT;_;`4#um*uC+?M+*ToTc%R8&JVW%(1LQ;;@Q7GIeBs5 zgv+;UFGn53z8&6~O}Vj9xZ|}b(h2z2SnyG;O}=z1`+q#=$+oH$lMSRrFr*k<0RE&H zO^QDSwM}JIR4%)MUVN2VL#q0_9m>X-(HWdpQBkS$(V7vy7Om@Z zll4@Raijf;ubj$et#2?sirucK+}ifbwfz_%w~S-gDl~uT&5p_xJX=}a&`d&{N9@0% z7CJS?{B=CV6hZE!TdGGB*tM0r4U3A3#zPU-kxbEH(V zcO%h&$!JCQXvI=WG=&S5QFZgKmkno9G}3-^F7A`2lTH3m&Z;4|!nVnLH)ZF}oo*f; z@i^qEPslV0nDY4Jllw6Rv~}ThbdKK@p~1IrA7fy)`Cw@W|5?Lo*>~&R+&VftQE4i8 z6tB~0>oD#(RpcpyL6@7G&4Nlznrn)I0Ggi%3zuf++7s2Z=a$z{PXk&n*-q&w8=vs> zEC6;~Rmhm8S6Nqe>ukM#Vo}hT=?~Yo7^d0si})RZJBaCYon&o0yJyYE%Z}MH7zx|~ z;$e6dz9U_H&CF1m`gwu!#`|_m8#g}xqR5gd;W5?!9`phQ{AOaMZ5bDc6M;LJlaJl` z!2Kocf_Da;+M6GrTFQBXOe2pjE2lPa9JsKV0vJ@<=@6TEv^5M{z<{(~P#{N{eiEmC zKIPC+1&OU=+l=LtQq0cI?W0DOgWW=${{~Gfc=~n4kaU+HHbJkVwiY8YCjXnCpM0cn zUNsK#FNA5qp#2Uqy%O^6D2E| z$<~>h@ANYV4bw{d_*qul*a$QapLU{em!OgBz9z=^va6mgZzG8ZW1iaem{ZLA#w>>E;0ax=wDt_>f6w!`h;Kt^o{)sB4hNfYf2=NAuayV?Iyj%j0OTj56k zyRR=J%~UzHs=w*wE{dto;sFeH_GGZQqLUV?>~zqzd2{&Jan6HDei>_ar+et;c(aae zpb{`nqf&d)p}3H+YmG%3FIt$;#M*C1s}~cQoNW4T(%*dJ@mE~F1)qhCP8ZR5U+)CE z?_Ir_Wv?nA7D)Q_zCeua-4b0Ju*I)NKt^w zBBD|4L!%rG<^^A(S@Kuw&yfsW>i`Ea}Vid_o_Aq9P+#O;dvp z+mkpP&UGJr&JLtqVK!T- zqoZ?dIgr-U-;yH?BG6crd?W&C=QH+G)37{=d(U*qlSJbWEF{s^|FUYvvIgOSD;nXWxAt zlGdZglW6h_34Q8xpmZeUaQR*u{nWvAi}&s0Ek0XVavs{6<%N?d*t}&+^wN8i!-X_K z%HcmtY!raVVe$x23K+k(VFAJ2Eur_VU;l*hjckh5a7nqvnq-GRZ}|87#xJq4xPEeINe=CV`)n~{c(BGH+-b`KBNLS=M?F7dzK zsZpjn`Ip9_iS!0Ve+f!SV*M;HaIzL?HIrqep84v!#nJ3$-PI49hwZL=U!1IbOb5c)Fp%d!&wtqYqd+EzFG<(YASSTZqvr40UfE`^}v74Wsl0?e&YT+O#-`gdH47iEf9mN;n+0J#&-{)-diRsGi_0QSjN_z1O`_2TPUqO&iHTt+^Cx)^vU4in zoip)b@4F67S2jc>=yb2@JpNGl>sIu#)WZX(A3Z(&W`)Fh!5&q5T`hn}OpPdCL-@}! ze3E+SK5)}yiBx{JW6EV|{c=is?SHOQ*7|Ks*|zpI_o^ND-GwQho}RBMS+t7hb_L@{ zQN8;cGeWU6fiE}?J~Yq@kBU+`d2&lrkeTIZgRHDK!;&bODsSCtdqIJPB`gbCC5w3R z$3LxkmbfX~i#piXrwo|l2m27DTKal=@5Y>~Lh9+7k}usf&G0&b9jMYccFgi)AR8nm zB{(AVc)h($rHG%8r;M^gDY`}z%Rvek>1sFN}YJZIywIdcU9bhGu*WoZTG zc2i-Mi79@0u5Z=VjLgi12UL{3A4A?o0ex29y<3m1U;m`mabshqw};jK1=3O)<_~*4 zH52}d8du@|h@#=Hhkb~Qj4Y|Vy}7%Gh0EB(RBNrS!{NT=09s;s+=^Ui8~V0oQDZdl z8pkd6-+IkcIhD7~cglF})Xc3LyTKyS5>+8T8=slUfYzeapE-d`RX_%DaJ$w{sd_oQ z@6;OK*DLI8CRZEDk-)1f1(EN!e*22})zQ_+hv_exhs|E<=6eh**el=Z-Du2XaqxFf z+WHI1%5@nKzL312;MJgU+gX|u?K@?Gb1Oyphv2W3O{JwIfi%7fpyj?oK5oR67{lcA zSfFlH_YX2LzH}Ayf919;OH=MF1<)3*Lva_+btr4?F*?oL^TXdR(r@*rRJh(+0V0M< zWjjQ#E0CB?`T2C#BYI>_;&G#QQ$ZL`RE%byev0G~8LIHF0{c`s(0EcH@t5729iyKu zZU~yWDqZnhiM*-Y9cuLSB?C_`L` z*pbyV)zApUSrF65FInfb+?S3hc)dvJK6QQQ7a5CG@DM`l)29_s8C-JOmRUpIs(IK& z?Nr_KeeZS6=wJEJkriFiGBzH_T8FQy2D!ynXP5oH@?%|#3NI0Eb*})Ps=5h`#9u1n zaDJFRh%c!vt?%XL?Fx5&HU|}gCo1Iq_?Ju3I}r**-9nG6I0uiQt3*juME{SWpp-*8 z<-#gmA%BI-X@^1Dug#*r-2Onjut9$R;DLPZpG5)wyV|?2P<=)qaC>d{D;^UWan}*! z4cu}S+wBY9qsg`ble=~6Rx8y=fsvZcFOE`roNQ{>XX^Ty`&tiFBp3Tox{sW%?cHdw zh8cOTF<>F@+Grs=>9mB-{wdg&ee&t)*O!{ZvAW}w?l+S)i$>`2f|H*-j>AD(;(a^P{gpR3{s7Cv|3h;l=TUj~% zn;Kxy-a~bAoC?^-_9ut_g@_`nZ$yT(Z^PfG$^zNqyL>!^tD_>5lIn=O3POsS5NcE` zw&78`_MJKR=%r?15l+Zwa*Lp-fF!1=@Y;+!PkX+raA#*H20jN^1D2A5}gu};DOR|AIa;}(h?f!(4rF*5D-IAutJk~KT*FVL#o5Q_t(sz zq{FrYEQTWXZE~dgK|hw$=CKdz6<%lqp{}DNqNcZ(nh!&Lk=qk}hNye+c2f8aOUz`@ zFvc!0q-NnnOqhwjHo0z)GBk8aOh2^r51rD$6$g*&Qej@jJ0+-on1?y93_OznS=Y@q z%nH_9W5kOSJ%Lb|wnmo8Ehm6EOMf51dRVIkSfSP9!r(7L&y{o83H8U=m} zjn&G!v*GL$j%_r?&~A z^AKnBzd@Z&Ybz4qY*&yl4b+*l4<<0LR|V$=i_7}5H=lfFTv;t#4BqE*tcdxIX2;a< z1{wS<^artAhtP~R=h*XL68WK}rG?}Vw7dAgO)}X$Z{G4EAG0Wl9<#8Zo_Tv|r;tzx zm`7Acw0>&p>U29KCBLIW$B|IXw)sLuP5gxUA8;F0&lahhB<ugqTpDK#qmXsov`7;*8|R@kDwrF9n83; zf-(izh20+?`z#$|ysgl=Oo9yRRaIARqem0Vfv^c)SUXC8m(2bs+# zd`Ik`8jH`Mqak>ROFXJvc9l!cZDal~Z3hPtXsv+BHMD_hdIkqI4oAPL0k|U%YkD?fCfQgSN5NIyUGmn@jZO7 zi=2geuNxB30#MY**#d|#EdT)2Pv!1<_iNV@06-{b=>^j@Ax=d-!^yjgAv_d5&0+ZN zs<_Y#_vZO}RCf7Vyu;*_G_%ku1tljZgE>+*u0zWmaOY0X_cQhf(1Wp@UVGa31CCow z$PQ}PD=?!v7cK~3=1ji&Fvf0Fs*oLEKIKaP=l2M<6NoG04>;Iv@Hs%h(RG{MMC89s zJdRjO4^k@QB_cmO7bGP|OiYrVIkB?LodEDfRidP(r*Gooy6i;FWRRd26uOVG=B?Ye zfi7!c%D}Eetna-ru1eV^VUse!*Motb@r{ob_fcCYo{({&nP+k2ieHM_2dHIy6a!Jx zDu%UZoyy(=g=Yumby9ezok$SIpNKFSb^T6pvEr#yrwDY1`dB$tqX8u|7<3WwIlyi* znaGYw)m|UcIAV(U>)q8-XdKW1fdQb!j)3q%PKe_=lC=ZlXJ}&7cM1w>o%s+zqe!(n ztb~`M57LMqk`8*$2$E7Z*2QUo;s8hvwL=BcCvdzcXz9KmEdhM8ci}Uw0NL^5|7|Ss z)+gZk$xYNzn7aiz)npl~PAr#-a+yTC_xyf}*ZlNHi(s-S+l%gjao)6XqmqZmJE7nR zrwj~dWT4WyGSEQpi`bWnfs;Q}^Air9vB1eiW|NBw=$h262RC)-KNv}(s8wkBFcyusJ110|+YESf% zNkjnGKu$j`Xm<8@C{$#K%tPpD`LRB>kg38o)8_VjJy{=PM;^~HItm6J36<)pSvb(S zuOZmbeRy;|wi;4vJ_Us~3^S;PWsoP@e0e|*?K5VDtSl_%F1s^7{Ks{nOd(8>6CnhZ zM5I@+Ia^IVhgAnj?jvC(@^Mh<+^{&{2uOtP^}#M7UvU6E8ZhCh+<`Cl$jK!_6aA9x z90DscAE**yA$3eg{%aE*|MNUmPfkt}s|=;!@AotR^I1@G6WJn^u^d3NgqHfOvO{k# z(I4+Q7T+;2P>Igvswmc@!V+lEfB~bibd*6Lz?b&z3jcjs0>mNC&>3c*qa{EFVXzHh zZ1DKxdQbvnnIajH(!e8R0P`BT9I}zFN+;zkBf`k%2KvDx{z>qg>;8D<0R$he= z#7g9{07RsrPlkRr2(B$>lbw2_VS%*&o4;R{3of1Q49a|lHq^Z2jN&bE*h zk2#Ng2ip|`gdX_RC#N=K>Y^HH@Iqp@di^%DoEG=Fo*0r6oGNixSC`z~d4!1n2)9dw z6b(<$NCB0Ss6&`xo=vMz!CT$Oq1(*Pp6&SiC=}QiU3NQ)lTXcnK9mR@LGJaO87xMmr83Q5dLY_)v{H*ur$H7WE!5o*1M zUs#8}iWC&`3&j`FNg%Q6JvWiZZdnrMp3GgI0(%2zI)mNAGn^++=?wMFWP_$Kod_Ix zsNk3%j-Y@E6vC;&3TMm9bLENq27_q1;Yje|(5->^nrmravcexfUCDo<6vI<;c-O95 z*NMc4lAnP5vWj0`B@F^v6x}gcxkS%bY{cxHjQjjpb{+i;WfQDpvC@tYNc~A9cn>@a zIc!qxp4nt*g4JhpvI;drFHUkMP<(C3Zt4nO2rhYfZ)510z@@T^#P&{r{4}&PO~WqS zUQ@?OY)eB!j|q_`7GA&-iniIgx#LiH!7qkSF1z#eY<{$Lve(JStTfFDFchJxHWKgRMyo=Vz!hE#&k1LWmAYyJxbA0J$^;BK&4%d_?3QLA_s?&5Dvn3sLy4` zVWmDp0{p2(But}sdgHzVgx34!0cM<--?N{Sv(%_^(0}?2ESIAbS5B-~+8^2M-Smi$0E8RslpfqBfs* zz_azda5^4qni>dN?1^b{8)A=L1rz%ZfShq+mJId<<9^M@@$)!2cQI&-x?%p4kPWP$ zN7_Yl;>CH~4rC01c^nHa3S|VM#F)s&TlNYHcH=yJGkH&SIt7g*(aFN3LX4BJkD!Ki z->}_jnlhbW%=?`#$KJC$v992CY|`}Su(1uES) z*tTrJRFE}s2-B0b`c@t$2UJrh-w$f zE)B*9GT;~dkD2l*vC1a>HySJzD3zOX9Uqb}#P(B*MSYe$myojKxsE6sR}f(Vrb=rW z7`h%mFVdTf5IDqmC}`nNU$T!C8gJN=0Cb`DCa^hns8L6;C(6)-t^?BchhWI&|j_?COBJr%Syx=^%ncB7bb#8Vpqt}Cg zL{)fuVikP=02Bz|SWMcj_jjw`dw{!oto`5i0t0vQW)SuK=ZUo{-x$U)hFm%h5VCR% z>(=n>tZW2pfU(SfzgE282NPs+PRb;xPHCQ)+t*FZ{CWI5Ye78`0RN=a; zLvN0=pBNwSM8`@z6(mtTHWc=r>tToBtb&(e?OHM*}Z~#0c`B-k0Bra?^hT$Y_P(UytetW;_){PE30%ofA03Hr=dS&

    AP$Kmk-T4gUKpLG8MBFCIYE|2VoTtJk>Mt^8=o`v`QVDML0Ox- z14j%26HsE3(G(_5`g5!~*de_QC>4j0dn+p{Qee-5X@DSt74T)to&X~JBWf;^P<936GM!z80)^=rOi99!AMBx+ zdi`a?hD%6A(h?k`VTjHRLsx~`S(Zke=&4!bQ&Z=mm_q4$1s^BuF_)3(b6`KngCUeS zhUO5Txqu@`ab2(QHqR(17|@Zc;)yV$rhshH)zwXLzN`Gq7g9EOwD){}b~Xq@7BZny z-Q;MC&a0c@p#BmCk~5z#u!EuXyl6oU%Od>D2~ z9VRA%({3}eBkQMXKuWUm$5~e{a_Eq}o}9@E!O|x{_u2#GZ9o*VpaMUbE={llWAwKd zD+(9QQs1rC>~0_mUJOp*zQ~>ad68IXkX8=-C#-(#yU!Qy_|(+0A&#yUI8%hjBJWQJ zD9%j8_mI-Z{4KyMLmm;WsvM@#1JYO)@;{=e2X_EsA+u!2(AIRo2$> z?%K7If>9|f7{c>1r5`@f?%YBDW<2d2keh|TB=$^*Lv{aYMnUe^HbZ4sH>5K?WL;(Y zKa$aZYc#4V>g)SJ3L+COzS{EW0MpGIH&)y)2Q2;YHDWata~Pm!B235(Zhd=c_?S1kGdsp zRg(h3A0-oydKeG_?07>|ch?rC(h@Svh2Rox6%5o=*tB<}HN;5bM3B&mFpc5pGj{iN zk`=7V%`ji@dAmC9qs30#JOPyst_M)Y>)`+h9lxUT3`b=1(s-!PXH)}jp9Mz>V2>tR zons(T50K{N00hx}9%fd7At6hpjNU?)+kUjSCqu7JZf8KVl{nLKNpg4x^@N`}hbOo& z3EPHSbCZ3Oz;I!4akkiH0Udf>A{eWT;3KjiOsZiVqc`;&zdbn)kYoPR$mpd7J<=K| zEnhs|3%I<*>WL$tOhl8Dd9d1GPWxSp`vCYkP*1?_p+txPtpY{#crKvYr(gW>jEpBY zZTbLIfvkAO*Ez$NPb;ub1YOOtDP3e&SQd~tmSFyiW!tC@B{r3P`YSt!eSVcm{^1Vx)q*$%A!=-HZaWtVvKXINfuSp&zdG&zkB94wkzyA3v#ss+^vnK9%LSv)Oq56A$QH+5@ z7gpX6sLZn%G}(O1VuRDR16)X*^Gcm0xdAzAjnr2!nlIHP%0!??d4;{j1H^%fS6rIi z1w=1}3HUXU?m#FeBw#AKjNT?`l4C62)a&2WUgt|nN+qM**I;;zk&zS-_>*`}=qRYV zPDq7-Sc+;Ep`;dFn$9WSiXg;Ukf59cM5!xh7c#b?)cyDgOYXVZvCiUouM0n(UDk>d zBliTrO`8dR-4^cenz>nsIhjhDUfV{PbNG?lISNpw`n;aOI=CHCQ`ds2kQ79U!H{Y7 zc@eME7aSOJ{|6smIRu`P1fcc(261;3RDvV8zh%2#td-yKf6L?O$Q&x`UjotW+P%9B zwlD!_Elh)g0T8yMP#=)AZ@YxMF`Aq5oHN2AA}0MuWmpWIhMGi)KY$X9Lb4U!VA4Fa zd{Noa^%^8HnvS|t7w%*Jj7X2p8_g+BOK$cMJa8Zi0-Tp#^DdyPpE3SRBDoKKd?3U| zcTzx3sS)$&eQs>y6lzyjYwdY z+JemM*QbGq_KBUeFlpRs9XfKh#+kr5=;`le2WcUtfQ9&-_4pZ7{5P>$xaFe^VSz7f zv`NW*g4;dNyR27&{?Hwk^6|;Z-$~a--dAh#s8HFCEq{yKAuK%V$|HO2dZYNq9?!Zq zp&>}vVxk7M+`;m7%4iDx=kZ@`+1n(}xG{Nd-uf+X{zgCZL|3}s?QM$S2MD0tB4k|A z^)YCxqPHCJEyB;+=$v!DGCvxxH~VB1k}}_rN{J=@akSCn0yg3ECNp ze6{Wz@-NykyurHl>w5sB6BWGTKYTd6|L#5^J{WvJYh1^j5m7zWF^$OO6mIWXbIfsa zrS7e?xlvM5(!L1WQhvv|dZEpIvb`2ag{x3oLERh$BVFye=yGeMUc$aD5qde}u^Bm+ zAr5eQu5CHk&{x^nwyn7@CyO3Gdl!gwbr(=j48Y&2KFO<7ct{Fc^CW!Iom#8>CpFZV zs!oS7m}8t_?imMzK(-1g)DEz7E{Y*Vntsh1;+LI-%~j00juUBw*iuoA$dv@_3v$?9 zYg|)A(g0+rBn<$_d$ygsHr0O!kKA+c1E&yJlR;3v_|v}1k|D+JHN00lBUT{j`bEnBT__;kYtZHa1VWBBv_NI zNDPWF`D226DC+ zhg){^$}2T@>$(mezmiMXkg`OpcAB=T%&f)F2 zCWt8W!3328@?kD>K;}LzF%*N_VR)bJ;7WmT+){z>gHA9<;DO}+`7&H1{HJg`q3udbC!gX#Zm)o zlDnTQg`PdqK;uv5hse>);NbQ-|LuW;oLK$|vArj-FwzvEaP<}h zw$;~%;v$|=xqtl+0eOFQ-=aE+q7Cf&^ykNO9e54^2F{~z18NJxoekm9(N-=Jj-uew zEm49l{d~O+fQo!RkWLwb7G8q?F2j(TMly8IsG6qcIlxo$F@PR%Tsm479IH{= z1haD&5MY@mg$L{9CYeAJ^n%iG99glO8Wjo+O#&m_uV51R(1UbD=qPmly!c$++K}b( zw<^?|V_JLJcJlH0!^r;`eiTexPFnpc0*Z3%u3*7UUzv=j1J#s`F$JVi()dQ(ovQbf zTbqazu$;>kS5BbgLPqHWd1M8F`%m*!223=FY=WR7jK_(Q5iQR;97<<}M;|R@tP@mN zG7Da_zo10|>Gi|q7B^2AF|=sN7397nxU~tpMy{bEaqoOXBabLzfeao_x*&t)q7-ih z!v^*Do;|E#`_wVzo5%oNwLFd+t|lQ9-nexuu`ZHc3fEwzVyyvdW4VqCl^~tCq1;pl zcesFi0V6@a1s7<&$1`q){JJVxjV;5{?AgZsEA_KLAP{v75kL>|pD_Z1J2i7eP zW-Z*6kPdE=Tw7CD-VTdB2}q>l#QY;PcOv{j2CaihqdCu+kAhn|I-mP2?xO(zLEuk3 zrdC=knPvzz=SXW?XgEyrlB7}(+bUp2g7HBa2Aa4fp%?K`SB}me^@^3Q6DK7fg0;+Bg=GXNEWJFYfBU@#MqjsFp)ErI=QpcDFW@bxn9*61Q{ zBZX_@ND`KRv<*zIyFa=Hk`_TISX)@IIMRc_|AhX(4rMA%^71xZdWGf+hut4^Fj_u{ zjkci@l7x)UL0U)wOhLl>f-~i;(2);g57i7^rW*!gAg?*3wz~n z3`_aYAmBYQtW~kH>UGb)cPiu3-#_1opBG)J~B>>3H5&lf%6h_L+DmM;ogXqkx9}U#=sU$Acc`m>BEN)Y8o03 z(8p=TORR$&7i7p0d^f2An8O_$oot7Yi`>9RUI9x#2~ye-*H4g=i~&#y2n=F?#mo2N zAxo>PgK&_cf2vQ|5BoGGi=Q)ec#!8@+HhYUn2&054<8yXP}L6JqcYCDW1&6^H_^Oc zng}r)xsL}NT;Gkipi8O1Ll^;>{Lwi>2n4bx@J{1>S0lQuFk+kP|5EB+12lGTe$yIk zH2@PSml(j}Mm%1$a8@5()xnUXfgw|T7Z;bfa@hK+5@&2*8pX=FJE^E{4%1Mke?e_# z>=0*F`0Cet-LQk6YumPMfw=tziguzDeBnB3LP>J(-HHr9ASWp%7LL|T+FmDKA^^24 zke+c1A|cl~NfyP2RHw+u?$(2Ua3@?ZEMn)tg%e*3xh@SkX%ZnOyKDm7a?eLWc6$j4 zd*BI}SPnv6gjp4?AW$cl8Isva-|e-qSS$7&!9{?6gf1lofkIliok#p0c}DJn#Q@_h zRrKstt;vAY*tk>qF8k3U5bA(eGg_Kw`G1=w3Q)?23vU{r6e}pm>Qy`gb001q0T^h; zWiCiEA25UfvrI`#8$rZkDhBU>Dwrz96-W(~Ks%Zhi&{CD5Fs@5y%SH>U%FgIAfsIE)Jdx*s?}f8vkGIX73! zZw*XeSzWzr@7_w8ZSF4KWMC5k>LdtLnMm9fLhv@kjzWLttJ4O+WZL@*7usT`CAQs?pr{T5u3g1H^q;0&>rV7fY%oc0kphx?Er>o3){ zu8GWB9$L_SS3E!l3qW9m&|9}|9du>`55z0dCdbB7@YulctujuDVPVI6yLRHvD_CMc zQR7OJd!V>t+(Sr{IF6aNB{5^eS&QCVdRYn+bv!l>b)9?h|7qv^e`1c~IG!(~X}-mw zEo;Q2CY&!D#e6B2RbnJczBI>LzU15PnD0(0OG3maUlw-B!cIw9vQewE(`Iz12$gpE za=zRMr#xQakFfdSerdb*+50~4*X#BC@_NSPgO}C%1YR!*EP>@el9^e~h(yD*02!? zUX;{MM8ho7d~P)sBv{>1&Ew-+>^svZ{Kg<-5?|eOGe1Et!gOO&2X6qS2#4b3)t+>9 z2v?32Ab3duB6Mf#`#PI*G6|kppSoY$Y@0t|bgZ-F;aa0r zxwBggoZ^6yf7ic%V_h48AaO>kc;pm&?&>qT12h``pe%!j5tPM|(QLCWn~v5QE&& z^z<^=9xc~QlyT%&u*3l&u?9M}2@Z^j@r1wL5~~b7zNo%*hpqOeT?e{16^qUo=%}9A z`1*AQc|>$t0(yY1FPoYcYA(0RZ;fzgu3#U5K*(YADTBeF&dEf{^x{*0T(?KocB1bt z9rCnC{sMViS{&4dI-tt#>*I5dV}EdJLMq3THMlv$Hf4n5s=7@#sa6y$p)I*lkbRAZ zQvH})l|WsFgx4|`%AAEvfyofFyh(K(*Wau(&k%~XN1*naHPOr|$H}z7UH*U`yf9@I z7QvvZeN#U+rVJu8^X!@4YYGVj+uUtGVaeWqLnBpXexcr>^XEBY`ymZo?5x!*ivzB( zlMF}gZ@yh~Blu);veP5Gi&hUW?oK`mOt%Zot*P|qG1p^hPE|+#!2up2v9{$9V@F*4w|9ft!Isp{&)`QrD+Y zR`^mVG~M*8@GrYRw)f-zc%$kzM`kgs_BXv3;nwp(Q;qs+xw2t9tjsUFYTlvVo?y`Ibc=ekql5likDT9SkmVsC)h z)km#|RQ{@)nkKbMsDIdmwG?5wWp+C<@_JZUSnCm;ch8^i^z`z=xADC?_woG*J)dPn zs;@?1RhC61m$)hA>eZ{XbaWEVKMu37vL?(ZY+5IHDDlAG`QMXMQ`nAcJ*9q5i?fqz zVNS^+8AXSh6Jx){DP7sqpt7vUzT?C;aq-(@9dENQbrq_exxlq5Qs_{sQOTK+4xmRq{G zrY1_$m2UpYZ*-oi3g>@f^6t&_A3Q~t!Onu;Ur!x~mAuKl z`+WEK_#s?tqm13oUzc(HtJ68M(+;x}W=Y+tfiN8VX4 zy&_~|w#V=D-*PVaWn_pw)C_sk-)ueJ`L5l4Fd<6p46m4&*wYg)K1}qKR@c?N`_Wt% zCli*ICXCfzLrkL-CmQ-NiKCe}A9EUdPE?av7WM3sW)A zGWgN-_)v1j#c!`fayvbqP5Gt z-)d&X3CexXsWr?>zt(##{29QF7tHnsJvYveP+4A#%*@Q(;nC^PSMjmX>x%Nih}5U1 zCig$B*7-xJaV^=_%qO0)`v$NINjmhZj}bbmgZOynq#kSW+ z3O(Hio69OHBynsK-M?=z@%ekXy#~1Hh-GJid;h>d z&%nUt&WyO-7dZCaV(O{bc$$ZteRk4ytX&&{^~5+| za^oJ`EjxDxS5;{#Dk>VhaTa-TDtDFX(5FYUv$L7!zih{9O-@W~*}C;=f`aQ*@k(an zi7SbU?vkv62fA-^nj~3NhV~B*X1k7?=pQ|rurSj3F3x52+mW2}$2+|jE^a@TR{TIC z$gMwozm|@UISzXCulc|zn_K?IcP9HPH~LP__JwhNTl(F627mu@^2~-Se?}xI7PT=F zH~-B2o#|Rz%q3$N?{q5X{Fh)Vzh?ZjA|6>1q1|8b&b*vqrMSn;*y(dc^*!mA5eVHiToB5!)MPaiojjqmT92 zza=In+R@U|a)l|+pGzLaWu)IY4>^_$&cEH~w{F9UXJ5D^&sNdRXlrXrczSx)yRQx9 zRXXqH?!MvrYGxO^g@s|)3V$kp@cA!KH6^$;+gc%4 zX}0@%#hiDrT}x&OB{;Xs`)%VNtlkEsfeNVx#iPQUraMo)9=X;vc++|G+ZXzE>-Mm) zu!!b0#LiR)vhQFj6=!K#%1(p!Rfay7yE`D-`~^T-X47X*@+FeCYP73 z{)~5xw~vo6^UnVny&!$5bMZljF0x$6hdVnq+Su6Ke68}UaUT|SMsD1YdNM`CG@K7B za$7C;QqfG5YS^?hDQ9j`8R@%s4q;4+A`?&$^<6>A;#qzldI$c}8^IM%N( zKJD63jw7|#%1V$@6D?*vGuEMq8;V}^+GY5X_HBpvM`|f{?RG+fSN*WjBOP`;s>kt+ z3-^`1;`!6;$ArUx4;&9lUDpltWVO+Qq-$sm2<>qxwm<32UDAK!9@EeC2od@%p= z^mx1X!srb@zcW+KqiwliC^(Wxt7`lqC=2Z#!!K;x^TMA$e_rFgxIxOQ@vZA6%`o0N zBuc;BT-W4M7{`?wCWZU*S zM8cvX^V~;1E$~PXzA$*%E@h*T^=gQK8}cRU%n%JGTk`2%{q19Wp*}AeAwR^&%w4m*7ck0utVFA zKP@|X#;g3++KtFoQYbBaLPCS_87f^fD<_bZoaTSo6fVtQpmh2ydu>0NexS(vujt%@ zywl=Y00yzVu-J^@^0LZG3$9fIHPMx&r4Jh`QLP#bC4Z=8^p&Tiq?qQmiOtW)H>kX` zTIY8?Dk=&Kbg6J|)#lBcu|Of^=5m8eDCCiGaWx25!C>!ykdjW%%)54esiF9rku<$iP~{8)UM-=Ty(Owo?eAj_GIUk@r3Db_}z_3$3$DV z>3?=+O46bR1O+|Rf2332wkIy6zyB-(cW@_bR#w*FqM8!&Uvl4a!Mk@2SA4zn^*^!m z2)TXF@9XWYkDD7|-BLLJbI1A5X(c$4r+!4w-ds1U(k15Mi~DSPc2Z1vwtJ<=@1Nxb z?$a@{4(7?!93Mxk&qK45eaD{Y4-_oK|9!L6F=x{J>eVZ!KW{lKkxiL`%HQAHeWCtJ ze0x{!=^vL1Vj3F{KR+=nCq(@l>Els{qes7HO^JDy@z*||zrUMFRdoLOIiNg<6R=}i zZ6^0(8wXCrUD4AYfGmc-zSzhSbQ6m(`KRqtw)?ad($9PtU1LW_f>5H{HS*u*&&SAb z=Q;HKXw4R?4CUe9wvG1Lmk*g{rJ}MP#@KP)`9$>(lB8^hOFcYo?THf9V!H=*VI;nD z;pejqhEZ~5RE&MOb{+9;Pfupl{~2v#9L@DvUUI4*d3UV&jE_=hXXjx5DMW`{Q!Gai z-JwGbYB#ruijEan(=12s-|Q8IGb3eQM*sZ8j+u6+21~EMD4YIY&JR2cQ-0H}eB{Ux zl$H4DH@qs|@rb1R({IMQii!@$9@Nvb0w#>UGi=Mr%|6nWD|XAwzPD@*u-@hR{iu-X zvvLg+lat9v*Pcij(Z|h)zdYOjNas!r%H1t9*<5QYt0|xx`39!K_DbfpYb{a2NE#A7 z{U%#Y-$9TXa22k> zhz;Vzc~u%8UY_}Q8p)5UisXlbg?u&i@uA=J&Taq<2f(1dp`q$`Go3Y8#^3qH#ch1& z@!K(x&KTK<*JsgTu#aiup5Wwtev($TTz2n%p8%?O-(MXmHY}Twee=eRiO)w5O=24) zJ${|Ddpo)(lt-cB#v0c8*cD?~4X5w5W~hnv**DL)53uv`^UDF+St?x$<5fD>lDQSB z*YrnYGUtwI zyHIs?^?`U<>ZMELYSvfQ;XcDumSS+PjyQ|ASHxU9E_0%nNJcfAotvX>+(^#2&8L)VjRxm;$Bw2R0P3(y0(1%HQMijA zv2NbnfHF2YUUrxl2f`z_;3z@(4f$B?#{bzKFfe=p=AFk z59|6BO9-#vIJ-C16Eib1D^{!sRv0g6@(&Ah9kb4D3(<}g+;DmL>u#W^;LJ>M3v5RP z;3|VsVrh>!S{~ca&kdU<{`}d4kha`;rf~6^HH{A<`DWo#t>JUvRk2?&mkK6t9YMU5 zHZ?V!`}XR|Bp_b=Ol^xymuFKN`V0U(OT={X?60On30-}yl)jSHn+twiAV3s_->%(l zO-BEm7w%tk`0I! zVcI~-s#cs^`kW~mtBnNy6#o6w#+XRAh%H!%&sZG{tfp{j@cVb}hx^0!ye}CmA=4}q2{P$Wa*<2RLx*DEp32H*EtYCYHX`UP68iwL9*9d9m6eSLAtwKdG= zk72QOktk_b$PX9ihcoI&+g@LkqCC_~kiVJOm(y$_Md=F=N|YU(TlVIdXuDK&5oo%e zo{`b%dp^N@rGCtu^KW8exGX-W9nnPQU}9!w=2ui~Ki8a|Ku(^?H^v?M6^2ZG&*do8 zaK6u|)lM7~4k~rphQUBR@R)~(yn^f4*`>v~#mUOei`WCJ{Vde*BCrqPe816Wp!eWJ z-Kj)r$RD_Ss=l?-F4rlm+E2CJY((yOICc|VlL#^xt?@txE=TFj?Ef+Xwxk?xMd z<)6;==GEzE(Z}N)PCi&DD=T9&dcR-2-w`B+R#qD#iLROB#D@?~u(pJ;J&b2QqB)0tK8k)w+RZG=e9jL`gon4o&1}9>gu8g_eS?G6E=*KvxbA}$!jJAD zivW^aRc=vKTzoJyI5^nX({tp24ZcAXyQc4N#&sZ3F&6c`x36zswpHD1kKg9_nGEB6 z7LnSvmWQ@Q^pyU#lL^oFfsL` ztP3eCce*dXzS#ByHHU_VhIZ8|$BxU*S(Y^%-R&aXU~wAJXIjhf=gOzhmVprtZ1H`_|uUV-X;e!x=@1GjmL(-FHvf zl{7SjA@7@Iw{l5YF}b!otln`loz}GK_ErKr@m=(QN60Q>^7mXOy7zi7%~^kMxPM4T zhXFWH0oYYAafiEy!Ui!NUPzZ(7 zVWdR@0VTn79c%j%WXfQn*t=i)K=jXya<-2bOovYY!GhM|iyPivvbPsUv2^GhYkJI# zMhWLD9!2N<`}g$B%#VRq!6*2kew*hQW&AnCNzLEB-B%E0tEk)S-IW>9V+=S6qHY4= z$enV!ENsDQ0s;c;-v%AO&ehk}p8XIdf&vu}YKe0G>+@<9>^W3wM)u-nlPh)ZS4LX0 zehoGGA#Ed~-A8kpxunmnXBEiRT6-fJ|CiT44DYeNiZaP)%Ytd(U1)kk345 zIQev82i%+4fMQ*LGf-A^mlMDEP^(9n=4PXqZb+*@T=*JdDalzA*$Wm{X@ zT&J7`7$xVi_6>1$-xsSI8ie@y`{GqJ!Mc)m@5jf7o0L3WHF|;YWZJCU?!JH~`#VYj zwxV+GNQQ}$nwnbrYz_-GpKZHu@2e{_c4&q1sr|{LNQj8Z2aT^&55~!>garrF621lX z=jG+$6F6>(x*qjPSNPTz0AHsLKjP;N>FeAwf=!x=2U$>ozOLM@6xbR`JgE`t1Dtr#F``e0ycH5Akd7+8kz2&6k`XGP_nICpvC4dPN!ds|-vv zDg?*9v3JJUG0WDMmhG3DPe=cXM`9jm$+Dr zIT$+_`sLY4){Pra{ZN*XkpXER;O|c{o$9X!*?0#aIXeGY0y+Q6Uh{05`zENjo(ewVM;&iRl;7HrME3SaBA8v2m z7bAc9>GZbS$RVV>gu$8 zm0^{2b)yfCUW}erV*fJC!p>g4E4Tf9igqN91uuZr*^+B??T$6O1`miupREkrY>n*y z?@%ue&;K5tLovE~t#A6<>x;T*Du-IK_|e$jOr2O({&4audbxNfu3L~EfI%(MC1Lpk zu-LZ~6A24sfEM)G$qcKp_Wb(4%gQ05d{eI5ef6t$WE803-p~T9@>|ElCo3C+b(OSh z&(rk|u1`>yM&+AEM>m0BX5r$}!uK}3CHe+%=XVt7RFsgs{QSubpT9w9$(V&>SPr45 zM#chdqY$kpx1b(av)l3m+gQ=EH%LBRQ`0RCiqlNE&JO24zrXwo36KnQj2siFw^HXn z3uEh_98O-rqu`R_IX4ykyPzCB1i0Pu_I#%~6x{^fKc5kIAaGXN55LGoTX_IiLpxBX zapsDMEbT)O2lYoTVUO`Er1K8q*wu^McNx3#qjBr`=JbQeJcO-4YD+-}VdST;&XC0w z?Q}2A_$8`~xw$z?{VnhOJN6*Yk3BsWfWjR2cD%4{MD}Fu$c*uU158jFl${3acR4=@ zEH~c@-AAU=t?#97wsE0hwiUb4-BpC!zPfU?BxpE!aDU%ZKWX$&J)xNJTP;i8Wn2JY zXnE@@1}S7K;864#@7Oy#PO|Xu95gV9X`M_ra3~tI-LvuWq5Cd+yY0FPJMy20Km)K?7fTprsQ~bVlwG{vCyVr7vhbDccrt%@FS6Pxrsq z=>POXbv-pdjo=;-km87ouj!|Q2)%J-=DXi!ZvtVq`#h>@9cU0|!iOtSDuVs|R-;ww zZ?(Sv$Z_C9@FuxW?o*-uQ3vO%ck$g!dGx4fe0~h zrS+r8n?&%z5{ChkK3%-Cck9-z!MsZMa0bDKtpc?CP|B<_QlKI)Pf)AL?=QF1Q~D3n zusJv=xQv*V`BTv#UMC0wkV6VY&){G7?Z>)7VKnZxIqi!xhvG#L=gqq#bAS)A(l#u+ zFMRDsXj_#BvM;;MsZ&K-p)woaHsc~d%H*BL$5%E-3m2z!5lq0e=I9~8=9G^3>t91O zT*vtUvs$z`#fWbF5xSS1r{5gYIGhso$*{QDzkbEtUKhD>xl(cT#=D^7Rn*mmAhF#c zup0<~^Qe(X$e*ze!aG%3-}ll)7e&FDI*X*qy_G}663f(l42m#Oy=p^yrht!;H3X%k zScPMLURjzObe||$-CE?M(&aUi@ZtXAL*%$=FbnoLro8U`)PjP7b6=kuCQm(2`BG?}tg(G3{~A2jO8_l!9aZodv*t&u9T!A@C7#N66hK-Uz+|y+6k4Lo1qvO$L)KpHJ6IFBIvSDX-QgZQmLx>wzteovs*=Nx*8iB`F8kd z4AuTRZiwD!4={~JwCL$sWW&kdzb}i9^69goY$psbo1!R_OpCJA`1;~0un?9wdHE3k zMb7qDg+DjS3B-xy3@X2d4FvsFY@S89cd#)xaiTALecsbua{bqEbJ)~CO&`QtKvlyx z&Nj)F3kz)aSW%KJ0d?M^tH6!CL|Chx$+qi|N5gUhYAs@nR5}pf(^d-EJInE4=bBR2 znwXfNDU);=X;Bl%L82n6h2mrx>y4W?f&7?p$~3wPy%?2p>#T?*0jc?g)|uvBXP^es z0wJNyj^=jRySiE0acXY%$YL;SYvky@_XeOtfhUnYIk@- z!bK=?Z2+cA%OUIh%=)d_mi8jRgeDibSO=!C={lBq!@WmEu$cou3<>Zv~oQv1Ok( z)%68~yl&kzE5#{&p$cQ-pdUm856xr77 zZiVGupUyU^;*RkMm$eKG@0*%fv9ypcDQxj`t0$&v#G0^QgN2Yo9-_3=w`CO0Z&&&I zi*@>YT^~FK@`G8-yoy!G$a3C`vT!cYc0YNX*o%r~fp)N9X?~cH28hZ@6l?jS^dk>7 z>l>C6*D`z+ey0D3fz&ZnUmQHAsebK5uRn&Q+a4UqK$)xq`^snukj9H-q&MhwFDWuiZsm@VM-Mc5g87$ z2l>w(qYOlV1bx~#iu5a}7hknFH%%xdNGBsBwh$LQIy07`!=V`ks^s{V7#F7t){fHh z=JJl*4wp8|fp5^~3FcWR3%*uq!-fr{i$%;Q%BZjz5A;SJQtpYhPQ;cJS;C zDSkT;InfC<;=xY!d!(0K9T!^LmJ>Id0u>P^8bF&A1gxwcAeX4ZK8NhK(RfAoh}l`U zq;95eDFLIDZD?28-TFf6+whRV+`9vbAP9j&@Zdf5xv7DJ2ZVd?9is$AmOEA-&9a*M z^{dP-ce&3S`NRxa=ht}GX5rZq@2u(-uY0>icbC1nAuVsfWSZ>^mJ znaIdqf}WFg{rZWp<`=t8rf%yAJQ+fNixm`c!Tt_b3*ApaEpCUN zu(-4^PRI#i;ea4cF)J`%uWXubAu)chPY8PZc7ZM%cp?B`IMb#{5L90UIYS+;U3H9N z1@_uqmk_4`!NDnT0@X(z)!_>&SJTv7g#!%!lY5UXy1m=2S?cLpxNhq!8&>R&B>J#L z0Bh;DUN4Fcr<9+-T0a&W#C>_T^-Kbu90s! z&l)8~1p-QYx{*ML#0b*EVY*Hxj^_!HxBz|Dp?4Z+=U`)V))4yOA9WV3CMnipuNIHm z+U^9k`6=h7Mmm*UHD3_Dv=&r*;?3cbwNGkws2{HVHAyfo7LFn0Rctl5Zir@ZGTlI! zi->3!(LSnGSh&}NMjA4Q)Y+=_$Zms*ZKu@(^{Qt>ge>dPbE$cFylIsXeTup+kZxdk z_Uw8%X6)=l58J=^g0)QG5fLpHXF{`F`u-*((PcoB&~}z*xV9jDyx7O59_SlNQ=kcf$oHCnrt{a- z#RM}h!i%u6^&6MX-A^}~Is_`+ciCq=Ac`HqbY(2x52wN`%K$X?s(PR5{nUJEqtz4K zfgvFRyLaCKa|?~~_dXrpYXjC;0N7JXkP6{GGydY>4U-4l|?hh+zQV zv+y{0!e%9ZR;^zW&#~{8*?LaS{pZg=Z9S551J){V^YRT-YuBvVDlVR>#jAi;6v+Pv z^IC^B&*95E5;UmAVE54Jz2T9s-i@W z65ml^f0mM>Vy4jxjVS}ZN5qSe2goAp&`S$(MJW1#Hdh3 z;Nfc^|JZ$Xb-a*9Kvg+(pnmQu*hE0VFAkqsmQ)DzuMuaut`WpRvP}Y$z!WpUwtg9` zP(x^JLBsTb=8#qh^{>e^*hxO(c(*7xn2F#%TifT=)#^ID?2wb$umM2O25((Qm1&0V9>O5&1kU#a|6yp#xIRKiWE>xiRC83%! zOx_W18yZ>Cjv&{!k;lBo0Fwmj$7*y2+u#sHlw_W*W&sMYblFLb=G?eZ7rH<3-2uFu zB_Diosu>?lJxartuY(PJhz>C&H5D+M751r=nyi4REr3-dZ=q{BlB`CDmUJ&feB6ln zc0ARyvs|mfl>Tr*88$=112azykGA@fpoBy?;lq)Ba1Ukh7-an9Zs&WHKyDCF2FfpZ za0?eUYQAqu$~J6%8JZmp;H7S7;!~TfccH((MV~rp*`F$NstRTVXz(hP;Cu!&a(r0 zT2-=y?|@145LsN%GN7lLV;6e$(bb6_!I?t(ISb%U3Ms1Vu_wP+IbyuAxa(UHT_`0p)A&A%&$0zz zFcuD6gj8uwP0ffbUvm_W2pzFqe9ky?AIRsQ0+^y@BfGC(5shIfU;{){9%9`?sIy6d z@&SaeLtB2+6L-_x+#G4Mknv*?4uP%kb(LU)Z{EMZxoCMwA%uIk zq(X#N_$MryAu67KV4yk3)K}-f1cFc|Z34no#0pRqy}(P)IY&Yt0GU7%lf+_&f5hjO z!HKZ|W$8iaUk3aK0h z74b`*ibxpeAT~-IfefXxG|LZ*U~PgzG?C(QHZ|Zer>&~4HbaG{c>ex!@*n0FVhN8( zLVMzgewtDMRcoh7K})|np9b&>Ewq0tAVygHf@xN+is9L>u5%kbpcJ@!bV~@2D8y*s z4ZRiAXe%yYiSiLHKK=It{r&3^7=0BXb)kIv+rXbbQi3xTB&!r8IS4Q~6nu}=jf}Vv zN%Jf9b#@)3397lL;-gG#7jUCkfLyn#q=xJFqOw1RFXSKbAk2620Nr8ZPtf%@$T@DK zfMF2^t0g0I+dqmM4w*r;UW!vy{F~$)%Mbx4)sGhUI*zy~;G|n3`4I&T==sO{aX!at z{4+TYIQbAqViDLq-%}^qL{9$-WsjbQuKp5w9&}E^njT+L?|*6V;sl{WK%^UhAXuJj z@Tm>m=GcnFDQXGghA1ouAYxZTT;WH2k3J)b)&hZr0V?_|%?S~Q0^(Mni9RVW3ONG$ zzEIP9x+xOz3Yx)A7YI22B|oK{c&Rvjs1)1D^*HU=_r zVPgZk$ZkY|x_bKiaQ^*iIA&jIqx3bP_kM?Q)GmL312JZeq$F}3ZO)0b#nw?5)+T>r zZtx4!MC?SN*dSp}`{c|gJk_`uCI$%**4F)O+7!{{Ae@h5OC)Sc{6>-==kbx)k4!TBiXg*{TmIK~HVr7Q> z{Bbrg>MS=+l;j0e3p6PVD2t#R_G0Vt@O+lW&d$;}SA3A`i6Dm4_60FK_=u`15($f` z+f=m>jT_JvwkPFZa{!iMl`j@O9+f_lH6Z>zLsFD>m(Q{i)F8M+U}QruI-1;DaaZyJXizBFpTNXqKg5Iv;fsfG__1`BNOG{5#PMjStS6Hh;d}^p zViO19_vy>t6m@+(h$R3vI1&H@Gpso^oJF@1i_v2*3zm=zEuR$*D%P1w!=Skm1jEUx zsVP_xdQ(;iTUHR26xtuA9g-1@|9&g!Op!N%3@Bkp{AJp7hdyVBP|@c!&iVi6(qXuf4keM9}mOs;oz1Hp~r#@wLMjsJBU-(^h{;Etq_&}Vcwv-7 z6n%2Ha+R<w(oEuKk09Kil4n z(W5)8^MW+%c&v|b8jx-CkJ>)Zs;=`0Sc-`LMz7A50EUx{<7lXNU%75!yok6DkeNh3 zkQ{%~94a1c>-zbQmZ*PLE}N*~HJ_l^?78@jws;@2(pg7t2Mq+Oex+5m1X@c6ocOnf@4Z9B#)10rSPMA$iJldLrvbK>}kOGG*IgamUk~2V6B4( z(GYkO#~6+a=R-vEaZsD!pJ}_ZDtV92v4-ncLsJ5bUhRt>^4>;G;|NX4qhp4ESs1t= zeieZJ^_w=?;uMDOaQyY-2=wlN4m<0GKcmt%pUSXMYGjjiQ1O9^`r)lOMy~n-sELV7 zoFXjCaX3X5C_;xPu8vSp*f9xU!m8tjMczvI3R7$;sSa=Mg|lt^H-;3+b*lu6o@Si? zvh_$=`8fsy9lBC+A|9Z}L!#i*s4&k;TMQ66h8rb#kccD5+Qfv@=kL#!4+13G@~BK#PcIe1DU#w#G_*#! zb|mq@wS0O&<1 zjfhLmq!q#f_sqBmAwwayJtMxo>L0ej2Lob-G7Hx1pdNp^Dstb0(e`}E9QV2h21rkW zVud}U<_m&sB7QuItmkazv{U#6u*>=nb{V~*_eFVsx)`7pdjg{baO1Bi#)-P<$SpFA z9U}~W=18j6 z#?Q~dmQDc&ckiS27X4mWy$)wv9fV`n!NCDJk0kgMgM`0Mp!33S-(H{1uf2i9wnP2S zrFKlp+)<%AXoEe2&a(dx=XL!*&KnyEeqiz1*inm zalN1F*^0qxpjE@hScZg>!8wtuC?ii!<%&Xs8$g5jIgnmI>6D(Cz4r7=wd)@L+n^=mcZ| z>m_y17hy+}@TI;CNo>2Y{8UIPm|>wLfnEQ83s18bBRLde5HiZ!7Z`}=rw1t|ASC1m zfgUj1nj|HbhbTmOZ{Ml34-(f7AQVZhA`Z@*lGt{iUW0H+xp4|35U~6txsG?@G0I0|^;i9G01=REsJFLw z7W_}^>x*&!;>#EfS&SVjG~vhoiJFL2ffG0zi0HoJt1HR6sL~xi;QD<^)4JY~l^X5@ zD{CmUqG=eoNc2(IRV6xN1x%5b%^cxGjCh8Spn!s|?BAx(fiEAbXH$jY+ut|_izSdi zw=-4VYhD^>j{*%&PKA>i{+@`eC^bO0XRWMy$HwejwuzMEgr&-R&Wcl#lase&B{+|~ zFxm|(UR6yEzo1|R9_<4r5}qKIu%L1G_Nk|&IN^`Uj?+!Wjyb@n$H+>7`|gA6BZGvf z6>zf1+Y3*Vp7@`T69C!!9_V+dF?l6IbGJfhl==UrHy^JLc%r;CYeD?ius7izNL8dd ztl_3%J4&~DHCzuB>8Ibq29r$ElFloXC(tAs=H`6xM4Y7U&XIY}v7c5il^4RomuKwr{z#_1CQJX9^2|9;*cC>FMq77Ut#2MmA~LAbq6D zf!L%VSa#z`X$_&RN`oX$fr2IYIQ$bJ^nu8Th!v_J#}DWsFg?(gtw4Qy1}kQ&_Q8X6 z40<3p!ga~{Wgs^tMJK*(TUq-SzG%1xEZV(hIxx>eg%nIc6g=`ej*c%|KbFzOi};eu zBwwbKOA~iB;>1bM+CS=_Hvlp>(v9SmKel9Q0ZZXV`0zaYt(chjeDAK~!GyWkCs5J2 zjaF%@_e;XB9R$tgCFFQDUHh`~a^kDF#k{#5e*LrNY9hn0?K(c7@@pVJ!@G!FpAw~y z#E`EJN`epiIc#4cn7SK_Uw~|5Led@Z5qNRIZTKZ=_$d#7RqUF8+DqIn01n0xD_5^G zFR#x-KTlW96sSu{v7u*@QL^gm6AJ^b;xUU~+anT>a@p&W?p_W5^Z;oCv#y}jygCz034LZA26=QQsjZ4B-3U< zgO3pPF`6~SS~f?~CF5E|4AF9NaY87o7yD3}$sg6@N4JLpA(8jy@c>qF!31k)ZdrQ_mzfd@&;ec*s-dUtI@t(3|> zjdUaxwjHJ7;!Gsa@MqI0BCQe6KzdV38RXh`0N-*_5L1(lbV%m^Wt z#pROoUV`Z-Gp0*R7L&D6V_@mwKwVkuFWBo0z=OEE6&)R|lVmJ`b|dReOV*M3Q|h&6 zbKBg(?>8(cD`t-ZOzn{7*=c@Dit#o);6DdbjU{%i{B-Pz7AJ@nz-9S?90PGD|?Mdq54pMBej_oE6EFTZWI ziCl_cKYIG-<>QzC9+!xFd!?j>*et*lkW;2ZcQ~-?$-&H_rRAb`X0j=EQet8B>o;sL zOj!sp-T}H#wdBYB$B!RZ+oZfgsWrFEGT5?{!Et$6-%u|0@s<$}q`)UIf2fjCCb#&f z=nH^x!4DJ{&d?tAs_4HeKqG#DYrUP;ecg3n2^yvQ6D+K-f=lzuH@3*f!{7#29NyHSHEek`K zXgW(Vs`Bs1g<=Dar%`Sl^DR4f&6Bb77Lqn~jsR*4c&gmo+`t{_{0lWlC#UNpw3(J1 zo|KevzZL;m$``vQA3pPv1TKpZmCGK^e{bzDJT}hURwWxJ=75hfA0^lrR6q z>&Vg+&|;>JEFyLP-M!~aceZBoN@N*Q%2HeKx4ird+y?6Xo6pf64n)0WQ+W1;A$-}f z^UoyZ8uto40=0^G?V;(>e7c#NjI4?u9zI)|{e7Z{-K>Xp1*#1908!X7Dza7R1cB7NW`yGcm_{+y?vwZRlWf-gNKDvW=l7Z@mgOab}t(8H923!McNtH=Pk7V?=~*vhiU<|RJahgO)%j>uEh)%#Z< z#jaIFQ;y0;$k~|p9pdcjjbA+8R19=Lq`iN&{ogM&ZG0UnaB*3T zV!#v2^|q6?;qV~$NqGO3(WCo^hOPqeg?thyqNu2p{PW_CHwndds<)X_tXCEuCxKSa zFE7uHmQ_{N_bVmp8L7dT0PywKbDKZ8W$O#mQ@u9D3K0bbibu2IELXQq^#L~P#4UPG_o{(`$l741F{D>`^ zdWfeGhJ))d>>nVET5xlkxH%hef(*(I+2(7X9-SB(`s=Gn*5nsjuOgpnuh@V^7rH zx{Ut7C=ni-DT|BSoElkPSs9rS{vp6U_lQWh^iXSelNAf^K-+paJjtsns9^Fwuwmne zK#`XG)F|I$QB{9kb+atnyVa_dGQC7zSB#`_N_K1Q;!EES zbsCdr*%n$GKq;k8L)JIX@+}Vu{4Kw-G4lZr#jiAZz*N1=QVA*-dNzp*Uw4uj83Oxo z-s@}L&wb5*VQTT=L?&lEB?4|7eM!s_0b;{AqyxefJ%$W`D&AP4&j-Sp&6DNuYQ<~C zi6Q)#6_9H9(rsY*MYpd1P!sU!oGDO{1&*rv#P8p`X3KgtZM~0EUT4fQ`L@Sz8gY4R z_)%T`fP~MICk46qsC`VZ7L_!eC8eb+;qRqH1mC0FaH2?t7H4hV%^=K2G*zPNv$3g$ zKfnnSxCKFA+rW7x!$Adsa1J z*!!_h?w&#BsGAzcVf#%)Pibf3O4eA^6X;c$h$QpE?#gi6Res4KLp*=L+ zgLDS%5PC3}zPy}ujSrFo2rm)19?;c_D+ERzdBYYTB@8a*tU%@M*S4~IJKbA&Zf}|p z<9m=;4nhZ$4%z(J!YB_=jV$HO&77VeSU-=@gbG~$vNm+nx3#J$a;aAl0)glfqlD{4 zIzPxnYHXqW=99d7?b)>--!OaimC)$K!+=(ZG*jZF%f(>g8T+r7J_)wW?=-!t=TyS4 ziVUZpngCM>nM$&kMFvYnvthMALQ)4*MX&6Bn$mB+*7T;T@45f|?rTuku%YZl#2#Df zzel!Va74;0H4tc!5F+f!h(&rohY}WC{NOZk>ky#b@7@+TN5+9kXlB z@(L)pWT)eNTh_;ZEGqO`VBzLIPnZ)DK~ukfm)E`M9*y1HzRH*0V&k7(ht$40NJ>f7 z1q<=%ryw?AoZa;E!O$6zbtF20i55Kz%w|q~-W9FqqI`_$mXd_FX-zkDHLLxg!zIxq z;0+HPWH{#EMAd#{vgig&SN9$sU8gAJ>eTPkysEx>^^_D;@#cHJeEL=(x}^}T=sn?Q zfI6CoPF5rfX~LfQDb3nMzF8lkRWj*J+G~U;(g;^P25Yx^`fmKvM+{^nsh!*|{j;)~ zZQ_sbNdG$uPSww|>!~8Yu`lHinZQwqLY~o)hBS{CpM2)or)n=pc{(dly3BF?YlJwT z{ymWQV{e8JGY*A_HiTV`F2)1~(#0-c$7Gn5-1T zkBuK=ytHWycG;Vk9-{y?#lmau>M(DhIz?Kprf*qldW%Pn#aG`UJ>O0?k zDP@(#;g`sXf23n(kNF-sbS3gf6ObB&)8-sYwvz-?-@1 zr>)C~hOu@ehL3Og2VOwZk0ux32j|N;3e4+gi2t*GUud7n5i7fZ3ePb5YRaHT6sP{=`0fp8WM|XP#pG+s&`$nN4Z- zi#oJft>C6(3y&CrECo~7Rrp9HU<(7g6-4evL|8bjo3%?Peqv;WZ(Ddqbxk$xmfgF* zq@3mB8`RO&wfK~BZ8-K&j5rNQd?+l>$cL)s80e!e{HA~Wa;G}2Y)j$9+=m{;ub6mC6mi2SW8C&G&k65aD4kNEbG?AU#ia8t1o}-yb?p$n}=xz zS$sscOylc)kC860ndDt1;Ix5V9z{91x{4WWnyj!0zN7A6l)+tGuj`m9B9)^ReyfQm_bgcmv9LO{#+uG3??^JzELx z5at`Smr?Mo`hvs3FZ-PD@x4P2t_{ddvE=p)t!t6mBE;)=hz`yj%mPa(JoV3`$5VjD ztAgrJCb#}^R1sQR0rMrdZrMU{9jBaIT9r7!y|m1;zi=f3hu_ziNE*iEMG!<)!)PCT zJtW&_Rb=;+6+YU=&>uE3+Cedy3*kWYjs z0tY51hC_Q4LxkX74BoA%etvA?damI)riG>1wZ5Rc;H8bFYNRlof^2ZcdrklrB6RzQ zgOqgx$QK6s`T0#VY|VLi>!nzZ;t3ghm5Fuk`K_`edm>mZ4(f^US%#Z&DgOR^ltL&; zICbOVwff&DenKss2$kQ2pVPjN{qY|1u4F zAUijAVBA}UP4mI)RaVBWe0pc)RK(W4^*F$&3HNx8s_W!K=4}FL4y6x#bhs|LrMq9w zKQbN=Z2Y-WZF_F<-x1da#7gZD3ck-S5NhUNf(McgMnCh42i-s=tL0Uyc#q&B} z(%d%x#b~E1y@_%y)6+mOFmKshJx9&AC6=Pi%A4ZqG%*c9r0CXgb()QO z!Fc!0jFa%PJmntUh-ue%Fdi#Dg7~niU<=nj3q78^c#J|s7*tlWYg54dx)}Av`2S{K zO_{%O@2ZpYPL(WIy-i6BT#4aA8oyFAs{>RKI*d&b+4`0lne4DDoU_X24=~=tuIjLX z-1*zL*UQy%IyXCPuhDsAy87ev=87JBQ(Yx>ee(yc5*jHtKs@w-%1Z)GPIOWPX+ED3 zy^*nwp58hK2ReRlA=h0=i`70BImM};zrK1h{Q&5PD>WcJ9&KrL-+u3MoCk@~v) zzPIuyZ=`Cq83)9~yjkP{fa+5x)Bj$wQ0)G^X@1y+&2eOb}ynW}1xky648tb7R z!(@Nk;l_NOUAJ2xotW#yA4>1t>q=oaZqNc6w;sW5;w=r2Arro`ZH<7)5lh%cw4gOO zM_4e6-xC#%jx=}n)yp%yPh1nQk$B*?Z9C_sN-cp*iOC@VU~=mJ!PAJU<8VYp_v1Z0 z247O`JA9IUj@}$=dvkU>1${L7pt#$5>N*h+#0k_Vz6T7$IR|G(t-;jiOOWXFqMYk4 zZ}zpyh>RIpquRvq#P-Y-F9k`^Xq!>lO)u1_0=#^I;yGE)Nt)IF+DD9y@D2~8i}k!3 zvms})q`orBFn+F$+gDqEoI+lK1~r>3s6$)M1y1O2GL#18g`FgMBi#gs-n~kV#!D&! zLPE-|vdtQ5dVd`H`{amdSmYBsx6X+TX6)y?zkk=ni^Y=lA7Xj{J`)krE)Wak6V+lQQqbep`2=Usrf?A9i)OIx~p zABBJ@4Wo8L;cW0hD8xcE>mu2~*mq4qY|#vrqwny$@9TS9&%P3*sar zqcfneT3*>iBCn^5u&ag_VOYPkt%miFm#Ws+Rf8_2zNJ3(G^aSQQ}y9$RFS`!xUB}h zp^1^SWI$BymJ6@Sd4xA(k<3tr3c3`YpSjFGG8b#mu|P0pM zR(&ymg&l7Qz?Mwn{e@FsPhEoc*ME-~?kGqlu;BiAu0Ha%OTcR8{P}3VCb{*Tb8MH> zhgYhC^G1afe9Ruc1Flw|#wSOGfZ#WPM22nhv$jbu3#b%P;`abahFUx)bl1VW?%6Ts z>z{XOJ(0W09il*kR{3eozJMr6LqkL2V^4lD|3Eo>YyT{0NL2rM@l(Eykd}es zwe4G7BBZutm&6@=ank28nIq7_d?Nl0AMF%M)2t+^2=FQ{nzzgYGbcg#{KowItI9B=krQh>o2Ct{Oeed4+^Czfs&8Ye01q*m#PB;8s;;^edAxm|=s7M9$ z@X9S|o~IQzDvcG0HLMa^il@te3kiI!v+EujMjxS&fh)Yg@yq$$ za#{YvI4zJ-vf!_WTcr}7j>~rotCq=C1gzK4PDQxb+YUv3W~dSBTBk7Lb*^qI^e0vo><%KZppp>^WSL;-s>GVg1^rF~M(QT_g8ND;em~?&(@v%*vGF>NYt+>@ zsD5{7S1brf`^E*zC6YBL>L6b90Y^~+JoiwHqRz<+Yo}nkV~*Se9v&WU=4c-N^8b`~u5mS{YaCuAj7n39B&SG9shldJ5G9RR zY>JrZ;G9~8X&iPMhoo6eTYg13=MW?3sW3{SLd2Mn5t5}a&Zjau%ynn>r~PSv-TQ+N zem`1ky*=;q-p_qs|7%%726Ng|VM7#NPu{|uEgKB2%-JOw!?8XRI?pL@%q`Pjv1VY1 zX-o~unV_yHv+=rbx?o#y8 zAK@5#MQy8`CvObcn10)3VkCv2okV(LaUfk>d*_p$#m6xpAgX{aQgpMk zL%C3KJ?F&-ZT>co5<1YL~mKx^5ONBrY(M3Q}@e} z_kQCJefvXsZHdXc*`)Q{85*};cV440uewxR{DAX%VA+wGLBYZFdyB4I830k5v6nr4 z7K|F~8zozZ1xKpSon2a?S)?%YR_GsGb71KG?Ahn}u^M}x0@S-Ckbw?j}>ex|S8RK3Rbj@P;=SUxAhPGlo{ zggF@`232zVe|H$0#-Rfe`*GO|+$sNhZgX*OIP23rv?Gefv`f*Z+J#wft0(9msHu-H zjXmIY&h$GLsHt93KROQyK-)*S^uK2Wurd$n~pdRS97mrg?tMYkWTbsN>Bjg-cyCe!^`-hzo*vZg8_5KV#XKTv&;Q z1tG^p7D3slh`PPc`Q4q3H+7t%weyCgJu}sRIQ@0Y>c?My^G$a9yiH2L9Rj`=AXU7P zwQ!cjyOAWI%$Qqeh$u)dU)E|f`U@gDmyLW}hJ%qPAjLGUjUV+%6oia6c0OEC;LcNIYu5d5|FEUj z&H*jtLOD8Yj-5}d*UI8*7d@AVN)N877#PW2JJ8Aughu%@*xJGiMp4`ZP{lJDL!<1J zh=PO)G6Ij^zG@Z4Tw46fNDG>4=SD(uFJm9uJEHeqsv$w(GO_fz)z5%5Nsxgt&^esp4&$YwB_6!`K&CF=S*jsf#7Ea;4@Ed9p0Yl-$NP0 z(oY&LbS+F~C4SKYQagZ2*U@+}hrhrQC{bGm<9pJca`@wRl1&xxml6acY$&Pa$djgt zhMtA|lyIg+XWm@uvz(BTu;=s^i4KJ|xK31_rbgxR>aqGq~qn9;xvq92w(GfR4a^UhfR zwxE`k`J!Z?vb=u%IxWbxkO87zZjy@kvS5J+3Wu3GXkk7XBT-JG#&uZybP`*x(vyc% z-@b&X0BjwQOrVF+jb^3*clr=Xu)SkiO1`}=3i2^v$e8Q~D^Ormfm3S8;Z+Mv%k5gV zwq4>u2mv}l)zyXE-dDKJwWR8^xt=s?`bK&O5DnuN>9sehQgj-~8r^sa+*R{;F8;)b zKMz}G6bC0jW|_!=2e(f-3*;fvQz`inE~xI+kWHA7p|lVQqiAAio2(zRr#E&PY%eAJ zetiVxz+qGN^D;-amo@5ECw*;Xbe%HEJx=82nyy3ZUY!><_v#(Wk$4k_nA0y#ZJ>PK zlH#2?`Lp*s@?IwC3;kiW-N+tV+S`{F1evRBId&FVh#g7Noj3$IFb>JeVujPjofo;k zT^YZ1;+GG|%16vlz9O=yA&5I0WJ9;};3Q<0bDTRgVVCB~6buO;-&RZYE$KX76%*9r zdyV{`(jWc$GwlC9HC5fuVH)(eu-k&MkmFI`GoARPG=Pp~E5cl!WX>_sg z6|6R&MF)Y=07aq;8c+$i@NtJ^eL|~FrbZMbraJ@!jlkp5J5iVoj*Mj*EUAGIk2ZSe#s9>Z z;Rw_v_bdjShmg+UFCu_jU*m45eE$3^+yIYJFi4!s+FGXGM!#(EoGV=_mjN+qtrLlP%TaS@~MNa*kDXZ@`K08LN zWfFK99Lzrid48KqB%J?C?d`Amqn!G>gLRPDaA1XKrbz{`e7Oro0S&Lp`14KC*oWraJvETv?4Diaah^}WQO)dcLDGqOk-P2bB}Rescra0JUF`B@$L j|M6WR|NUqF=vw&m%8)i5@#FaZ7sZ%Sbx1jPIWUcbk; literal 0 HcmV?d00001 diff --git a/latest/control_data_collecting_tool/resource/circumscribing_circle.png b/latest/control_data_collecting_tool/resource/circumscribing_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..2c1996f92c68c04e9c9474b80f01ce152cd2f4ea GIT binary patch literal 41673 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 E160Yx;Q#;t literal 0 HcmV?d00001 diff --git a/latest/control_data_collecting_tool/resource/circumscribing_circle_counter_clockwise.png b/latest/control_data_collecting_tool/resource/circumscribing_circle_counter_clockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..be54aaf9178e59494ec53c7fa0f680779424e240 GIT binary patch literal 43624 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 E07bIIx&QzG literal 0 HcmV?d00001 diff --git a/latest/control_data_collecting_tool/resource/common_tangent.png b/latest/control_data_collecting_tool/resource/common_tangent.png new file mode 100644 index 0000000000000000000000000000000000000000..77af0f3f11b4576452c70ffa7b8b25cec174e99c GIT binary patch literal 47572 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 R9!vOZn)M8;B$?aB{{U>31MC0* literal 0 HcmV?d00001 diff --git a/latest/control_data_collecting_tool/resource/common_tangent_counter_clockwise.png b/latest/control_data_collecting_tool/resource/common_tangent_counter_clockwise.png new file mode 100644 index 0000000000000000000000000000000000000000..b1208b25e8370af8fea1dd7ccfa76fbfaba36f6b GIT binary patch literal 49721 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 literal 0 HcmV?d00001 diff --git a/latest/control_data_collecting_tool/resource/looking_ahead.png b/latest/control_data_collecting_tool/resource/looking_ahead.png new file mode 100644 index 0000000000000000000000000000000000000000..10d0dcad376037b4bc308cc8c3c10e79cbc1d1cd GIT binary patch literal 17543 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 z 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 literal 0 HcmV?d00001 diff --git a/latest/search/search_index.json b/latest/search/search_index.json index d0fbdbd3..f42495a6 100644 --- a/latest/search/search_index.json +++ b/latest/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"autoware_tools","text":""},{"location":"#autoware_tools","title":"autoware_tools","text":"

    This is a repository for keeping packages that are not needed at runtime, including packages for benchmarking, debugging, tuning, calibrating, etc.

    "},{"location":"CODE_OF_CONDUCT/","title":"Contributor Covenant Code of Conduct","text":""},{"location":"CODE_OF_CONDUCT/#contributor-covenant-code-of-conduct","title":"Contributor Covenant Code of Conduct","text":""},{"location":"CODE_OF_CONDUCT/#our-pledge","title":"Our Pledge","text":"

    We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

    We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

    "},{"location":"CODE_OF_CONDUCT/#our-standards","title":"Our Standards","text":"

    Examples of behavior that contributes to a positive environment for our community include:

    • Demonstrating empathy and kindness toward other people
    • Being respectful of differing opinions, viewpoints, and experiences
    • Giving and gracefully accepting constructive feedback
    • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
    • Focusing on what is best not just for us as individuals, but for the overall community

    Examples of unacceptable behavior include:

    • The use of sexualized language or imagery, and sexual attention or advances of any kind
    • Trolling, insulting or derogatory comments, and personal or political attacks
    • Public or private harassment
    • Publishing others' private information, such as a physical or email address, without their explicit permission
    • Other conduct which could reasonably be considered inappropriate in a professional setting
    "},{"location":"CODE_OF_CONDUCT/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"

    Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

    Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

    "},{"location":"CODE_OF_CONDUCT/#scope","title":"Scope","text":"

    This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

    "},{"location":"CODE_OF_CONDUCT/#enforcement","title":"Enforcement","text":"

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at conduct@autoware.org. All complaints will be reviewed and investigated promptly and fairly.

    All community leaders are obligated to respect the privacy and security of the reporter of any incident.

    "},{"location":"CODE_OF_CONDUCT/#enforcement-guidelines","title":"Enforcement Guidelines","text":"

    Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

    "},{"location":"CODE_OF_CONDUCT/#1-correction","title":"1. Correction","text":"

    Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

    Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

    "},{"location":"CODE_OF_CONDUCT/#2-warning","title":"2. Warning","text":"

    Community Impact: A violation through a single incident or series of actions.

    Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

    "},{"location":"CODE_OF_CONDUCT/#3-temporary-ban","title":"3. Temporary Ban","text":"

    Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

    Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

    "},{"location":"CODE_OF_CONDUCT/#4-permanent-ban","title":"4. Permanent Ban","text":"

    Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

    Consequence: A permanent ban from any sort of public interaction within the community.

    "},{"location":"CODE_OF_CONDUCT/#attribution","title":"Attribution","text":"

    This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

    Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

    For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

    "},{"location":"CONTRIBUTING/","title":"Contributing","text":""},{"location":"CONTRIBUTING/#contributing","title":"Contributing","text":"

    See https://autowarefoundation.github.io/autoware-documentation/main/contributing/.

    "},{"location":"DISCLAIMER/","title":"DISCLAIMER","text":"

    DISCLAIMER

    \u201cAutoware\u201d will be provided by The Autoware Foundation under the Apache License 2.0. This \u201cDISCLAIMER\u201d will be applied to all users of Autoware (a \u201cUser\u201d or \u201cUsers\u201d) with the Apache License 2.0 and Users shall hereby approve and acknowledge all the contents specified in this disclaimer below and will be deemed to consent to this disclaimer without any objection upon utilizing or downloading Autoware.

    Disclaimer and Waiver of Warranties

    1. AUTOWARE FOUNDATION MAKES NO REPRESENTATION OR WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH RESPECT TO PROVIDING AUTOWARE (the \u201cService\u201d) including but not limited to any representation or warranty (i) of fitness or suitability for a particular purpose contemplated by the Users, (ii) of the expected functions, commercial value, accuracy, or usefulness of the Service, (iii) that the use by the Users of the Service complies with the laws and regulations applicable to the Users or any internal rules established by industrial organizations, (iv) that the Service will be free of interruption or defects, (v) of the non-infringement of any third party's right and (vi) the accuracy of the content of the Services and the software itself.

    2. The Autoware Foundation shall not be liable for any damage incurred by the User that are attributable to the Autoware Foundation for any reasons whatsoever. UNDER NO CIRCUMSTANCES SHALL THE AUTOWARE FOUNDATION BE LIABLE FOR INCIDENTAL, INDIRECT, SPECIAL OR FUTURE DAMAGES OR LOSS OF PROFITS.

    3. A User shall be entirely responsible for the content posted by the User and its use of any content of the Service or the Website. If the User is held responsible in a civil action such as a claim for damages or even in a criminal case, the Autoware Foundation and member companies, governments and academic & non-profit organizations and their directors, officers, employees and agents (collectively, the \u201cIndemnified Parties\u201d) shall be completely discharged from any rights or assertions the User may have against the Indemnified Parties, or from any legal action, litigation or similar procedures.

    Indemnity

    A User shall indemnify and hold the Indemnified Parties harmless from any of their damages, losses, liabilities, costs or expenses (including attorneys' fees or criminal compensation), or any claims or demands made against the Indemnified Parties by any third party, due to or arising out of, or in connection with utilizing Autoware (including the representations and warranties), the violation of applicable Product Liability Law of each country (including criminal case) or violation of any applicable laws by the Users, or the content posted by the User or its use of any content of the Service or the Website.

    "},{"location":"autoware_dependency_checker/","title":"autoware_dependency_checker","text":""},{"location":"autoware_dependency_checker/#autoware_dependency_checker","title":"autoware_dependency_checker","text":"

    This package provides a script for checking whether each package's dependencies listed in a package.xml are used or not. Currently, it mainly checks packages that start with autoware_.

    "},{"location":"autoware_dependency_checker/#dependency-checking","title":"Dependency Checking","text":"

    The script will try to match the dependencies and the headers by reading the dependencies listed in package.xml and the included headers in the source files.

    Some dependency in package.xml and the included header might differ. The following table shows the matching between dependency names and headers:

    from to description autoware_pkg_name autoware/pkg_name Usually this style should be used autoware_*_msgs autoware_*_msgs For messages autoware_other_pkg autoware_other_pkg E.g. autoware_lanelet2_extension"},{"location":"autoware_dependency_checker/#usage","title":"Usage","text":"
    # build\n$ cd to/autoware_tools\n$ colcon build --symlink-install --cmake-args --packages-up-to autoware_dependency_checker\n$ source\n\n# run\n$ cd to/your/autoware\n$ ros2 run autoware_dependency_checker dependency_checker.sh\n\n# run in some package\n$ cd to/some/package\n$ ros2 run autoware_dependency_checker dependency_checker.sh\n
    "},{"location":"bag2lanelet/","title":"bag2lanelet","text":""},{"location":"bag2lanelet/#bag2lanelet","title":"bag2lanelet","text":"

    This package generates a lanelet map necessary for Autoware's autonomous driving from rosbag data containing information about Localization (/tf). This enables autonomous driving based on manual driving information.

    The provided functionalities are as follows:

    • bag2lanelet.py: Generates lanelet (.osm) from a rosbag based on the position of base_link.
    • bag2trajectory.py: Generates trajectory information (.csv) for vector_map_builder from a rosbag.
    "},{"location":"bag2lanelet/#example","title":"Example","text":"

    As an example, the process of lanelet generation based on driving trajectories from the planning simulator is performed as follows. Typically, the expectation is to use rosbag data from manual driving, rather than from the planning simulator.

    Firstly, you need to run the planning_simulator following the planning_simulator tutorial in Autoware Documentation. The process would be, install Autoware, download the maps, run the planning_simulator, and start autonomous driving. Make sure to save the rosbag during this driving session using the following command:

    ros2 bag record /tf -o /tmp/bag2lanelet_sample.bag\n

    After completing the drive, you can run the bag2lanelet.py script. This requires specifying the output directory, lane width and MGRS coordinates:

    ./bag2lanelet.py /tmp/bag2lanelet_sample.bag /tmp/bag2lanelet_sample -l 3.0 -m 54SUE\n

    The map will be saved in the specified directory, following the naming convention <date>-lanelet2_map.osm. The map generated will appear like this. You can see the example result in ./example/lanelet2_map.osm.

    When you relaunch the planning_simulator with the new lanelet2 map, you will see the following.

    Please note that at this stage, although this map works with Autoware, the shape of the lanes will appear jagged. (Refer to the 'Limitations' section for more details.) While this is an issue that should be addressed in the future, it can currently be resolved by loading it in Vector Map Builder as follows.

    Following the documentation of the Vector Map Builder, import the generated Lanelet2 map. You can see the refined lane on the application.

    Then, Export the map. You can run the planning_simulator with the refined lanelet2 map and see how it goes on the Rviz.

    "},{"location":"bag2lanelet/#requirements","title":"Requirements","text":"
    sudo apt update\nsudo apt install ros-humble-tf-transformations ros-humble-tf-transformations\npip install -r requirements.txt\n
    "},{"location":"bag2lanelet/#usage","title":"Usage","text":"

    Check ./bag2lanelet.py --help

    "},{"location":"bag2lanelet/#generate-lanelet2-file","title":"generate lanelet2 file","text":"

    For given lane width and MGRS coordinate.

    ./bag2lanelet.py /home/autoware/rosbag/sample .  -l 3.0 -m 54SUE\n
    "},{"location":"bag2lanelet/#generate-trajectory-file-for-vector-map-builder","title":"generate trajectory file for Vector Map Builder","text":"
    ./bag2trajectory.py /home/autoware/rosbag/sample sample.csv\n
    "},{"location":"bag2lanelet/#limitations","title":"Limitations","text":"

    Here is the limitations of this package. Contributions to further improvements are more than welcome.

    • Due to the low conversion accuracy from MGRS to latitude and longitude in this script, the lanes in the output lanelet.osm appear jagged. Importing and then exporting through vector_map_builder corrects these values with high accuracy.
    "},{"location":"common/autoware_debug_tools/","title":"Autoware Debug Tools","text":""},{"location":"common/autoware_debug_tools/#autoware-debug-tools","title":"Autoware Debug Tools","text":"

    This package provides tools for debugging Autoware.

    "},{"location":"common/autoware_debug_tools/#processing-time-visualizer","title":"Processing Time Visualizer","text":"

    This tool visualizes tier4_debug_msgs/msg/ProcessingTimeTree messages.

    "},{"location":"common/autoware_debug_tools/#usage","title":"Usage","text":"
    1. Run the following command to start the visualizer.

      ros2 run autoware_debug_tools processing_time_visualizer\n
    2. Select a topic to visualize.

    3. Then, the visualizer will show the processing time tree.

    "},{"location":"common/autoware_debug_tools/#summarized-output","title":"summarized output","text":"

    Running with --summarize, it will output the summarized information.

    > ros2 run autoware_debug_tools processing_time_visualizer --summarize\n\nobjectsCallback: 17.99 [ms], run count: 1\n    \u251c\u2500\u2500 removeStaleTrafficLightInfo: 0.00 [ms], run count: 1\n    \u251c\u2500\u2500 updateObjectData: 0.03 [ms], run count: 13\n    \u251c\u2500\u2500 getCurrentLanelets: 4.81 [ms], run count: 13\n    \u2502   \u251c\u2500\u2500 checkCloseLaneletCondition: 2.43 [ms], run count: 130\n    \u2502   \u251c\u2500\u2500 isDuplicated: 0.02 [ms], run count: 17\n    \u2502   \u2514\u2500\u2500 calculateLocalLikelihood: 0.66 [ms], run count: 12\n    \u251c\u2500\u2500 updateRoadUsersHistory: 0.30 [ms], run count: 13\n    \u2514\u2500\u2500 getPredictedReferencePath: 5.47 [ms], run count: 5\n        \u251c\u2500\u2500 predictObjectManeuver: 0.40 [ms], run count: 5\n        \u2502   \u2514\u2500\u2500 predictObjectManeuverByLatDiffDistance: 0.34 [ms], run count: 5\n        \u2502       \u2514\u2500\u2500 calcRightLateralOffset: 0.03 [ms], run count: 12\n        \u251c\u2500\u2500 calculateManeuverProbability: 0.01 [ms], run count: 5\n        \u2514\u2500\u2500 addReferencePaths: 4.66 [ms], run count: 15\n            \u251c\u2500\u2500 updateFuturePossibleLanelets: 0.08 [ms], run count: 8\n            \u2514\u2500\u2500 convertPathType: 4.29 [ms], run count: 8\n
    "},{"location":"common/autoware_debug_tools/#system-usage-monitor","title":"System Usage Monitor","text":"

    The purpose of the System Usage Monitor is to monitor, visualize and publish the CPU usage and memory usage of the ROS processes. By providing a real-time terminal-based visualization, users can easily confirm the cpu and memory usage as in the picture below.

    You can run the program by the following command.

    ros2 run autoware_debug_tools system_usage_monitor\n
    "},{"location":"common/autoware_debug_tools/#system-performance-plotter","title":"System Performance Plotter","text":"

    This script plots the following metrics by each Autoware's module.

    • processing time
    • CPU usage
    • memory usage
    "},{"location":"common/autoware_debug_tools/#usage_1","title":"Usage","text":"

    Run the following commands according to your purpose.

    # plot processing time\nros2 run autoware_debug_tools processing_time_plotter <bag-path>\n\n# plot CPU usage\nros2 run autoware_debug_tools cpu_usage_plotter <bag-path>\n\n# plot memory usage\nros2 run autoware_debug_tools memory_usage_plotter <bag-path>\n

    There are several options.

    • -c:
      • can filter modules in the specific component (e.g. all, planning, system, etc).
    • -n <number>:
      • can pick up top <number> critical modules.
    • -g <text>
      • can filter the modules which include <text>.
    • -y <val>
      • can set the height of the plot to <val>.
    "},{"location":"common/autoware_debug_tools/#examples","title":"Examples","text":"
    ros2 run autoware_debug_tools processing_time_plotter <bag-path> -c planning -g behavior_path -y 300\n
    ros2 run autoware_debug_tools cpu_usage_plotter <bag-path> -n 20\n
    "},{"location":"common/autoware_debug_tools/#rosout-log-reconstructor","title":"Rosout Log Reconstructor","text":"

    This script shows the log from the /rosout topic on the terminal.

    "},{"location":"common/autoware_debug_tools/#usage_2","title":"Usage","text":"
    ros2 run autoware_debug_tools rosout_log_reconstructor\n
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/","title":"Topic Connection Checker","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-connection-checker","title":"Topic Connection Checker","text":"

    The Topic Connection Checker is an advanced diagnostic tool designed to simulate how an Autoware Engineer debugs an Autoware system in the field when certain topics are not functioning as expected. This tool is essential for identifying and resolving issues in the complex topic network of an Autoware system.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#overview","title":"Overview","text":"

    The tool consists of two main components:

    1. Topic Connection Checker
    2. Topic Localizer

    These components work together to provide a comprehensive debugging experience, following a systematic approach to identify and locate problematic topics in the Autoware system.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#debugging-process","title":"Debugging Process","text":"

    The Topic Connection Checker follows a step-by-step process that mimics an experienced Autoware Engineer's debugging approach:

    1. Identify key topics with unexpected output using diagnostic information and major final output topics.
    2. Track the publishing nodes of these blocked output topics.
    3. Investigate the subscribed inputs of these publishing nodes to find upstream blocked topics.
    4. Trace back to the source to identify key topics that are not being published.
    5. Locate the source of lost topics in the code or launching system.

    Steps 1-4 are handled by the Topic Connection Checker, while step 5 is addressed by the Topic Localizer.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-connection-checker_1","title":"Topic Connection Checker","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#usage","title":"Usage","text":"

    To run the Topic Connection Checker, use the following command:

    ros2 run autoware_debug_tools topic_connection_checker\n
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#mechanism","title":"Mechanism","text":"

    The Topic Connection Checker operates as follows:

    1. Subscribes to /diagnostics for three seconds, focusing on hardware_id with topic_state_monitor.
    2. Subscribes to and traces stuck topics and all upstream topics.
    3. Performs multiple iterations to identify topics without publishers.
    4. Reports ERROR in the command line for problematic topics.

    The identified problematic topics can then be used as input for the Topic Localizer.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-localizer","title":"Topic Localizer","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#usage_1","title":"Usage","text":"

    When launching from the autoware/pilot-auto directory, use the following command:

    ros2 run autoware_debug_tools topic_localizer . $TOPIC1,$TOPIC2\n\n## If we launch from a different directory\nros2 run autoware_debug_tools topic_localizer $AUTOWARE_DIRECTORY $TOPIC1,$TOPIC2\n

    Replace $TOPIC1,$TOPIC2 with the actual topic names you want to localize, separated by commas.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#mechanism_1","title":"Mechanism","text":"

    The Topic Localizer employs a two-step approach to find the source of problematic topics:

    1. Direct Search:

      • Scans all HPP/CPP and launch.py files for code snippets containing the exact names of the target topics.
    2. Launch System Analysis:

      • Starts with autoware_launch/launch/autoware.launch.xml using default arguments.
      • Statically traces all XML files in the launch system.
      • Identifies launch parameters or remapped topics matching the names of the target topics.
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#best-practices","title":"Best Practices","text":"
    1. Always start with the Topic Connection Checker to identify problematic topics.
    2. Use the output from the Topic Connection Checker as input for the Topic Localizer.
    3. Pay attention to ERROR messages in the command line output.
    4. When using the Topic Localizer, ensure you're in the correct directory (autoware/pilot-auto).
    5. Keep track of the relationships between topics to understand the flow of data in your Autoware system.
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#troubleshooting","title":"Troubleshooting","text":"
    • If the Topic Connection Checker doesn't identify any issues, but you're still experiencing problems, it could be related to the pulishing frequencies. The connection checker marks a topic as \"fine\" if it has a single output in five seconds.
    • If the Topic Localizer doesn't find any matches, it is usually because of the topics are launch using launch.py files with sophisticated construction functions.

    By using these tools effectively, Autoware Engineers can quickly identify and resolve topic-related issues, ensuring smooth operation of the Autoware system.

    "},{"location":"common/mission_planner_rviz_plugin/","title":"mission_planner_rviz_plugin","text":""},{"location":"common/mission_planner_rviz_plugin/#mission_planner_rviz_plugin","title":"mission_planner_rviz_plugin","text":""},{"location":"common/mission_planner_rviz_plugin/#mrmgoaltool","title":"MrmGoalTool","text":"

    This is a copy of rviz_default_plugins::tools::GoalTool. Used together with the RouteSelectorPanel to set the MRM route. After adding the tool, change the topic name to /rviz/route_selector/mrm/goal from the topic property panel in rviz.

    "},{"location":"common/mission_planner_rviz_plugin/#routeselectorpanel","title":"RouteSelectorPanel","text":"

    This panel shows the main and mrm route state in the route_selector and the route states in the mission_planner. Additionally, it provides clear and set functions for each main route and mrm route.

    Trigger Action main route clear button call /planning/mission_planning/route_selector/main/clear_route mrm route clear button call /planning/mission_planning/route_selector/mrm/clear_route /rviz/route_selector/main/goal topic call /planning/mission_planning/route_selector/main/set_waypoint_route /rviz/route_selector/mrm/goal topic call /planning/mission_planning/route_selector/mrm/set_waypoint_route"},{"location":"common/rtc_manager_rviz_plugin/","title":"rtc_manager_rviz_plugin","text":""},{"location":"common/rtc_manager_rviz_plugin/#rtc_manager_rviz_plugin","title":"rtc_manager_rviz_plugin","text":""},{"location":"common/rtc_manager_rviz_plugin/#purpose","title":"Purpose","text":"

    The purpose of this Rviz plugin is

    1. To display each content of RTC status.

    2. To switch each module of RTC auto mode.

    3. To change RTC cooperate commands by button.

    "},{"location":"common/rtc_manager_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/rtc_manager_rviz_plugin/#input","title":"Input","text":"Name Type Description /api/external/get/rtc_status tier4_rtc_msgs::msg::CooperateStatusArray The statuses of each Cooperate Commands"},{"location":"common/rtc_manager_rviz_plugin/#output","title":"Output","text":"Name Type Description /api/external/set/rtc_commands tier4_rtc_msgs::src::CooperateCommands The Cooperate Commands for each planning /planning/enable_auto_mode/* tier4_rtc_msgs::src::AutoMode The Cooperate Commands mode for each planning module"},{"location":"common/rtc_manager_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.

    2. tier4_state_rviz_plugin/RTCManagerPanel and press OK.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/","title":"tier4_automatic_goal_rviz_plugin","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#tier4_automatic_goal_rviz_plugin","title":"tier4_automatic_goal_rviz_plugin","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#purpose","title":"Purpose","text":"
    1. Defining a GoalsList by adding goals using RvizTool (Pose on the map).

    2. Automatic execution of the created GoalsList from the selected goal - it can be stopped and restarted.

    3. Looping the current GoalsList.

    4. Saving achieved goals to a file.

    5. Plan the route to one (single) selected goal and starting that route - it can be stopped and restarted.

    6. Remove any goal from the list or clear the current route.

    7. Save the current GoalsList to a file and load the list from the file.

    8. The application enables/disables access to options depending on the current state.

    9. The saved GoalsList can be executed without using a plugin - using a node automatic_goal_sender.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#input","title":"Input","text":"Name Type Description /api/operation_mode/state autoware_adapi_v1_msgs::msg::OperationModeState The topic represents the state of operation mode /api/routing/state autoware_adapi_v1_msgs::msg::RouteState The topic represents the state of route /rviz2/automatic_goal/goal geometry_msgs::msgs::PoseStamped The topic for adding goals to GoalsList"},{"location":"common/tier4_automatic_goal_rviz_plugin/#output","title":"Output","text":"Name Type Description /api/operation_mode/change_to_autonomous autoware_adapi_v1_msgs::srv::ChangeOperationMode The service to change operation mode to autonomous /api/operation_mode/change_to_stop autoware_adapi_v1_msgs::srv::ChangeOperationMode The service to change operation mode to stop /api/routing/set_route_points autoware_adapi_v1_msgs::srv::SetRoutePoints The service to set route /api/routing/clear_route autoware_adapi_v1_msgs::srv::ClearRoute The service to clear route state /rviz2/automatic_goal/markers visualization_msgs::msg::MarkerArray The topic to visualize goals as rviz markers"},{"location":"common/tier4_automatic_goal_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.

    2. Select tier4_automatic_goal_rviz_plugin/AutowareAutomaticGoalPanel and press OK.

    3. Select Add a new tool.

    4. Select tier4_automatic_goal_rviz_plugin/AutowareAutomaticGoalTool and press OK.

    5. Add goals visualization as markers to Displays.

    6. Append goals to the GoalsList to be achieved using 2D Append Goal - in such a way that routes can be planned.

    7. Start sequential planning and goal achievement by clicking Send goals automatically

    8. You can save GoalsList by clicking Save to file.

    9. After saving, you can run the GoalsList without using a plugin also:

      • example: ros2 launch tier4_automatic_goal_rviz_plugin automatic_goal_sender.launch.xml goals_list_file_path:=\"/tmp/goals_list.yaml\" goals_achieved_dir_path:=\"/tmp/\"
        • goals_list_file_path - is the path to the saved GoalsList file to be loaded
        • goals_achieved_dir_path - is the path to the directory where the file goals_achieved.log will be created and the achieved goals will be written to it
    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#hints","title":"Hints","text":"

    If the application (Engagement) goes into ERROR mode (usually returns to EDITING later), it means that one of the services returned a calling error (code!=0). In this situation, check the terminal output for more information.

    • Often it is enough to try again.
    • Sometimes a clearing of the current route is required before retrying.
    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#material-design-icons","title":"Material Design Icons","text":"

    This project uses Material Design Icons by Google. These icons are used under the terms of the Apache License, Version 2.0.

    Material Design Icons are a collection of symbols provided by Google that are used to enhance the user interface of applications, websites, and other digital products.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#license","title":"License","text":"

    The Material Design Icons are licensed under the Apache License, Version 2.0. You may obtain a copy of the License at:

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#acknowledgments","title":"Acknowledgments","text":"

    We would like to express our gratitude to Google for making these icons available to the community, helping developers and designers enhance the visual appeal and user experience of their projects.

    "},{"location":"common/tier4_control_rviz_plugin/","title":"tier4_control_rviz_plugin","text":""},{"location":"common/tier4_control_rviz_plugin/#tier4_control_rviz_plugin","title":"tier4_control_rviz_plugin","text":"

    This package is to mimic external control for simulation.

    "},{"location":"common/tier4_control_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/tier4_control_rviz_plugin/#input","title":"Input","text":"Name Type Description /control/current_gate_mode tier4_control_msgs::msg::GateMode Current GATE mode /vehicle/status/velocity_status autoware_vehicle_msgs::msg::VelocityReport Current velocity status /api/autoware/get/engage tier4_external_api_msgs::srv::Engage Getting Engage /vehicle/status/gear_status autoware_vehicle_msgs::msg::GearReport The state of GEAR"},{"location":"common/tier4_control_rviz_plugin/#output","title":"Output","text":"Name Type Description /control/gate_mode_cmd tier4_control_msgs::msg::GateMode GATE mode /external/selected/control_cmd autoware_control_msgs::msg::ControlCommand Control command /external/selected/gear_cmd autoware_vehicle_msgs::msg::GearCommand GEAR"},{"location":"common/tier4_control_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select Panels.

    2. Select tier4_control_rviz_plugin/ManualController and press OK.

    3. Enter velocity in \"Set Cruise Velocity\" and Press the button to confirm. You can notice that GEAR shows D (DRIVE).

    4. Press \"Enable Manual Control\" and you can notice that \"GATE\" and \"Engage\" turn \"Ready\" and the vehicle starts!

    "},{"location":"common/tier4_debug_rviz_plugin/","title":"tier4_debug_rviz_plugin","text":""},{"location":"common/tier4_debug_rviz_plugin/#tier4_debug_rviz_plugin","title":"tier4_debug_rviz_plugin","text":"

    This package is including jsk code. Note that jsk_overlay_utils.cpp and jsk_overlay_utils.hpp are BSD license.

    "},{"location":"common/tier4_debug_rviz_plugin/#plugins","title":"Plugins","text":""},{"location":"common/tier4_debug_rviz_plugin/#float32multiarraystampedpiechart","title":"Float32MultiArrayStampedPieChart","text":"

    Pie chart from tier4_debug_msgs::msg::Float32MultiArrayStamped.

    "},{"location":"common/tier4_debug_tools/","title":"tier4_debug_tools","text":""},{"location":"common/tier4_debug_tools/#tier4_debug_tools","title":"tier4_debug_tools","text":"

    This package provides useful features for debugging Autoware.

    "},{"location":"common/tier4_debug_tools/#usage","title":"Usage","text":""},{"location":"common/tier4_debug_tools/#tf2pose","title":"tf2pose","text":"

    This tool converts any tf to pose topic. With this tool, for example, you can plot x values of tf in rqt_multiplot.

    ros2 run tier4_debug_tools tf2pose {tf_from} {tf_to} {hz}\n

    Example:

    $ ros2 run tier4_debug_tools tf2pose base_link ndt_base_link 100\n\n$ ros2 topic echo /tf2pose/pose -n1\nheader:\n  seq: 13\nstamp:\n    secs: 1605168366\nnsecs: 549174070\nframe_id: \"base_link\"\npose:\n  position:\n    x: 0.0387684271191\n    y: -0.00320360406477\n    z: 0.000276674520819\n  orientation:\n    x: 0.000335221893885\n    y: 0.000122020672186\n    z: -0.00539673212896\n    w: 0.999985368502\n---\n
    "},{"location":"common/tier4_debug_tools/#pose2tf","title":"pose2tf","text":"

    This tool converts any pose topic to tf.

    ros2 run tier4_debug_tools pose2tf {pose_topic_name} {tf_name}\n

    Example:

    $ ros2 run tier4_debug_tools pose2tf /localization/pose_estimator/pose ndt_pose\n\n$ ros2 run tf tf_echo ndt_pose ndt_base_link 100\nAt time 1605168365.449\n- Translation: [0.000, 0.000, 0.000]\n- Rotation: in Quaternion [0.000, 0.000, 0.000, 1.000]\nin RPY (radian) [0.000, -0.000, 0.000]\nin RPY (degree) [0.000, -0.000, 0.000]\n
    "},{"location":"common/tier4_debug_tools/#stop_reason2pose","title":"stop_reason2pose","text":"

    This tool extracts pose from stop_reasons. Topics without numbers such as /stop_reason2pose/pose/detection_area are the nearest stop_reasons, and topics with numbers are individual stop_reasons that are roughly matched with previous ones.

    ros2 run tier4_debug_tools stop_reason2pose {stop_reason_topic_name}\n

    Example:

    $ ros2 run tier4_debug_tools stop_reason2pose /planning/scenario_planning/status/stop_reasons\n\n$ ros2 topic list | ag stop_reason2pose\n/stop_reason2pose/pose/detection_area\n/stop_reason2pose/pose/detection_area_1\n/stop_reason2pose/pose/obstacle_stop\n/stop_reason2pose/pose/obstacle_stop_1\n\n$ ros2 topic echo /stop_reason2pose/pose/detection_area -n1\nheader:\n  seq: 1\nstamp:\n    secs: 1605168355\nnsecs:    821713\nframe_id: \"map\"\npose:\n  position:\n    x: 60608.8433457\n    y: 43886.2410876\n    z: 44.9078212441\n  orientation:\n    x: 0.0\n    y: 0.0\n    z: -0.190261378408\n    w: 0.981733470901\n---\n
    "},{"location":"common/tier4_debug_tools/#stop_reason2tf","title":"stop_reason2tf","text":"

    This is an all-in-one script that uses tf2pose, pose2tf, and stop_reason2pose. With this tool, you can view the relative position from base_link to the nearest stop_reason.

    ros2 run tier4_debug_tools stop_reason2tf {stop_reason_name}\n

    Example:

    $ ros2 run tier4_debug_tools stop_reason2tf obstacle_stop\nAt time 1605168359.501\n- Translation: [0.291, -0.095, 0.266]\n- Rotation: in Quaternion [0.007, 0.011, -0.005, 1.000]\nin RPY (radian) [0.014, 0.023, -0.010]\nin RPY (degree) [0.825, 1.305, -0.573]\n
    "},{"location":"common/tier4_debug_tools/#lateral_error_publisher","title":"lateral_error_publisher","text":"

    This node calculate the control error and localization error in the trajectory normal direction as shown in the figure below.

    Set the reference trajectory, vehicle pose and ground truth pose in the launch file.

    ros2 launch tier4_debug_tools lateral_error_publisher.launch.xml\n
    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/","title":"tier4_logging_level_configure_rviz_plugin","text":""},{"location":"common/tier4_logging_level_configure_rviz_plugin/#tier4_logging_level_configure_rviz_plugin","title":"tier4_logging_level_configure_rviz_plugin","text":"

    This package provides an rviz_plugin that can easily change the logger level of each node.

    This plugin dispatches services to the \"logger name\" associated with \"nodes\" specified in YAML, adjusting the logger level.

    Warning

    It is highly recommended to use this plugin when you're attempting to print any debug information. Furthermore, it is strongly advised to avoid using the logging level INFO, as it might flood the terminal with your information, potentially causing other useful information to be missed.

    Note

    To add your logger to the list, simply include the node_name and logger_name in the logger_config.yaml under the corresponding component or module. If the relevant component or module is not listed, you may add them yourself.

    Note

    As of November 2023, in ROS 2 Humble, users are required to initiate a service server in the node to use this feature. (This might be integrated into ROS standards in the future.) For easy service server generation, you can use the LoggerLevelConfigure utility.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#how-to-use-the-plugin","title":"How to use the plugin","text":"

    In RVIZ2, go to Panels and add LoggingLevelConfigureRVizPlugin. Then, search for the node you're interested in and select the corresponding logging level to print the logs.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#how-to-add-or-find-your-logger-name","title":"How to add or find your logger name","text":"

    Because there are no available ROS 2 CLI commands to list loggers, there isn't a straightforward way to check your logger name. Additionally, the following assumes that you already know which node you're working with.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#for-logger-as-a-class-member-variable","title":"For logger as a class member variable","text":"

    If your class doesn't have an rclcpp::Logger member variable, you can start by including one yourself:

    mutable rclcpp::Logger logger_;\n

    If your node already has a logger, it should, under normal circumstances, be similar to the node's name.

    For instance, if the node name is /some_component/some_node/node_child, the logger_name would be some_component.some_node.node_child.

    Should your log not print as expected, one approach is to initially set your logging level in the code to info, like so:

    RCLCPP_INFO(logger_, \"Print something here.\");\n

    This will result in something like the following being printed in the terminal:

    [component_container_mt-36] [INFO 1711949149.735437551] [logger_name]: Print something here. (func() at /path/to/code:line_number)\n

    Afterward, you can simply copy the logger_name.

    Warning

    Remember to revert your code to the appropriate logging level after testing.

    RCLCPP_DEBUG(logger_, \"Print something here.\");\n
    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#for-libraries","title":"For libraries","text":"

    When dealing with libraries, such as utility functions, you may need to add the logger manually. Here's an example:

    RCLCPP_WARN(\nrclcpp::get_logger(\"some_component\").get_child(\"some_child\").get_child(\"some_child2\"),\n\"Print something here.\");\n

    In this scenario, the logger_name would be some_component.some_child.some_child2.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/","title":"tier4_screen_capture_rviz_plugin","text":""},{"location":"common/tier4_screen_capture_rviz_plugin/#tier4_screen_capture_rviz_plugin","title":"tier4_screen_capture_rviz_plugin","text":""},{"location":"common/tier4_screen_capture_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin captures the screen of rviz.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/#interface","title":"Interface","text":"Name Type Description /debug/capture/video std_srvs::srv::Trigger Trigger to start screen capturing. /debug/capture/video_with_buffer std_srvs::srv::Trigger Trigger to start screen capturing with buffer. /debug/capture/screen_shot std_srvs::srv::Trigger Trigger to capture screen shot."},{"location":"common/tier4_screen_capture_rviz_plugin/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    This is only for debug or analyze. The capture screen button is still beta version which can slow frame rate. set lower frame rate according to PC spec.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select panels/Add new panel.
    "},{"location":"common/tier4_simulated_clock_rviz_plugin/","title":"tier4_simulated_clock_rviz_plugin","text":""},{"location":"common/tier4_simulated_clock_rviz_plugin/#tier4_simulated_clock_rviz_plugin","title":"tier4_simulated_clock_rviz_plugin","text":""},{"location":"common/tier4_simulated_clock_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin allows publishing and controlling the simulated ROS time.

    "},{"location":"common/tier4_simulated_clock_rviz_plugin/#output","title":"Output","text":"Name Type Description /clock rosgraph_msgs::msg::Clock the current simulated time"},{"location":"common/tier4_simulated_clock_rviz_plugin/#how-to-use-the-plugin","title":"How to use the plugin","text":"
    1. Launch planning simulator with use_sim_time:=true.

      ros2 launch autoware_launch planning_simulator.launch.xml map_path:=$HOME/autoware_map/sample-map-planning vehicle_model:=sample_vehicle sensor_model:=sample_sensor_kit use_sim_time:=true\n

      Warning If you launch the planning simulator without adding the tier4_simulated_clock_rviz_plugin, your simulation will not be running. You'll not even be able to place the initial and the goal poses.

    2. Start rviz and select panels/Add new panel.

    3. Select tier4_clock_rviz_plugin/SimulatedClock and press OK.

    4. Use the added panel to control how the simulated clock is published.

      1. Pause button: pause/resume the clock.
      2. Speed: speed of the clock relative to the system clock.
      3. Rate: publishing rate of the clock.
      4. Step button: advance the clock by the specified time step.
      5. Time step: value used to advance the clock when pressing the step button d).
      6. Time unit: time unit associated with the value from e).

      Warning If you set the time step too large, your simulation will go haywire.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/","title":"tier4_string_viewer_rviz_plugin","text":""},{"location":"common/tier4_string_viewer_rviz_plugin/#tier4_string_viewer_rviz_plugin","title":"tier4_string_viewer_rviz_plugin","text":""},{"location":"common/tier4_string_viewer_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin displays the ROS message whose topic type is autoware_internal_debug_msgs::msg::StringStamped in rviz.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    TBD.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select panels/Add new panel.
    2. Select tier4_string_viewer_rviz_plugin/StringViewerPanel and press OK.
    "},{"location":"common/tier4_target_object_type_rviz_plugin/","title":"tier4_target_object_type_rviz_plugin","text":""},{"location":"common/tier4_target_object_type_rviz_plugin/#tier4_target_object_type_rviz_plugin","title":"tier4_target_object_type_rviz_plugin","text":"

    This plugin allows you to check which types of the dynamic object is being used by each planner.

    "},{"location":"common/tier4_target_object_type_rviz_plugin/#limitations","title":"Limitations","text":"

    Currently, which parameters of which module to check are hardcoded. In the future, this will be parameterized using YAML.

    "},{"location":"control/stop_accel_evaluator/","title":"Stop Accel Evaluator","text":""},{"location":"control/stop_accel_evaluator/#stop-accel-evaluator","title":"Stop Accel Evaluator","text":"

    The role of this node is to evaluate how smooth it is when a vehicle stops by calculating vehicle acceleration just before stopping.

    "},{"location":"control/stop_accel_evaluator/#how-to-use","title":"How to use","text":"
    ros2 launch stop_accel_evaluator stop_accel_evaluator.launch.xml\n

    Then you can see stop_accel_evaluator/stop_accel topic. This topic is published only when a vehicle stops.

    "},{"location":"control/vehicle_cmd_analyzer/","title":"Vehicle Command Analyzer description","text":""},{"location":"control/vehicle_cmd_analyzer/#vehicle-command-analyzer-description","title":"Vehicle Command Analyzer description","text":""},{"location":"control/vehicle_cmd_analyzer/#overview","title":"Overview","text":"

    This is a visualization tool for vehicle commands. You need plotjuggler to plot.

    The following time series data will be plotted on the left side.

    • Velocity
    • Acceleration (acceleration and derivative of velocity)
    • Jerk (derivative of acceleration and second derivative of velocity)
    • Lateral acceleration

    The following data will be plotted on the right side.

    • XY plot of jerk-acceleration

    "},{"location":"control/vehicle_cmd_analyzer/#how-to-use","title":"How to use","text":"
    1. Launch the node.

      ros2 launch vehicle_cmd_analyzer vehicle_cmd_analyzer.launch.xml vehicle_model:=lexus\n
    2. Launch plotjuggler.

      ros2 run plotjuggler plotjuggler\n
    3. Load layout.xml from File->Layout.

    4. Press ok in the confirmation dialog.
    5. Select/vehicle_cmd_analyzer/debug_values.
    "},{"location":"control_data_collecting_tool/","title":"Control data collecting tool","text":""},{"location":"control_data_collecting_tool/#control-data-collecting-tool","title":"Control data collecting tool","text":"

    This package provides tools for automatically collecting data using pure pursuit control within a specified rectangular area.

    "},{"location":"control_data_collecting_tool/#overview","title":"Overview","text":"
    • This package aims to collect a dataset consisting of control inputs (i.e. control_cmd) and observation variables (i.e. kinematic_state, steering_status, etc).
    • The collected dataset can be used as training dataset for learning-based controllers, including smart_mpc.
    • Data collecting approach is as follows:

      • Following the trajectory using a pure pursuit control law.
      • Adding noises to the trajectory and the control command for data diversity, improving the prediction accuracy of learning model.
      • Setting the trajectory from the following types of trajectories ( [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle, along_road] ).

        • COURSE_NAME: eight_course

        • COURSE_NAME: u_shaped_return

        • COURSE_NAME: straight_line_positive or COURSE_NAME: straight_line_negative

          ( Both \"straight_line_positive\" and \"straight_line_negative\" represent straight line courses, but the direction of travel of the course is reversed.)

        • COURSE_NAME: reversal_loop_circle

          Drive within a circle while adding trajectories and collect data.

        • COURSE_NAME: along_road

          Generate trajectories along the road. This is particularly useful when drawing long straight paths along the road.

          In this course, data collection is conducted only on long straight trajectories, while constant velocity, velocity_on_curve, is maintained when driving on sections that include curves.

          The minimum length of these long straight trajectories can be specified using the parameter minimum_length_of_straight_line (These two parameters velocity_on_curve and minimum_length_of_straight_line can be configured in ./config/course_param/along_road_param.yaml).

    "},{"location":"control_data_collecting_tool/#how-to-use","title":"How to Use","text":"
    1. Launch Autoware.

      ros2 launch autoware_launch planning_simulator.launch.xml map_path:=$HOME/autoware_map/sample-map-planning vehicle_model:=sample_vehicle sensor_model:=sample_sensor_kit\n
    2. Set an initial pose, see here.

    3. Add the DataCollectingAreaSelectionTool and DataCollectingGoalPlugin RViz plugins by clicking the \"+\" icon at the top of the RViz window.

    4. Launch control_data_collecting_tool.

      ros2 launch control_data_collecting_tool control_data_collecting_tool.launch.py map_path:=$HOME/autoware_map/sample-map-planning\n

      - If you use the along_road course, please specify the same map for map_path as the one used when launching Autoware. map_path is not necessary when using courses other than along_road.

      - Control data collecting tool automatically records topics included in config/topics.yaml when the above command is executed. Topics will be saved in rosbag2 format in the current directory.

      - The data from /localization/kinematic_state and /localization/acceleration located in the directory (rosbag2 format) where the command is executed will be automatically loaded and reflected in the data count for these topics. (If LOAD_ROSBAG2_FILES in config/param.yaml is set to false, the data is not loaded.)

    5. Add visualization in rviz:

      - /data_collecting_area - Type: Polygon - /data_collecting_trajectory_marker_array - Type: MarkerArray - /data_collecting_lookahead_marker_array - Type: MarkerArray

    6. The following actions differ depending on the selected course. If you select the trajectory from [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle], please proceed to 6.1. If you select the trajectory from [along_road], please proceed to 6.2.

      - 6.1 If you choose the trajectory from [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle], select DataCollectingAreaSelectionTool plugin.

      <img src=\"resource/DataCollectingAreaSelection.png\" width=\"480\">\n\nHighlight the data collecting area by dragging the mouse over it.\n\n<img src=\"resource/select_area.gif\" width=\"480\">\n\n> [!NOTE]\n> You cannot change the data collecting area while driving.\n

      - 6.2 If you choose the trajectory from [along_road], select DataCollectingGoalPose plugin.

        <img src=\"resource/DataCollectingGoalPose.png\" width=\"480\">\n\nBy setting the pose of the goal point, a trajectory is generated on the map.\n\n  <img src=\"resource/set_trajectory_along_road.gif\" width=\"480\">\n\nAs soon as the trajectory is generated, the plot with the map and trajectory drawn on it will be created (please see the following picture).\nIn the sections labeled `velocity = const (velocity_on_curve)` in the legend, the vehicle travels at a constant velocity of `velocity_on_curve`. In the sections labeled `Data collection is conducted`, data collection is performed.\n\n  <img src=\"resource/along_load_plot.png\" width=\"480\">\n\n> [!NOTE]\n> You cannot change the goal pose while driving.\n> In cases where course generation fails, which can happen under certain conditions, please reposition the vehicle or redraw the goal pose.\n
    7. Click the LOCAL button in AutowareStatePanel.

      Then, data collecting starts.

      You can monitor the data collection status in real-time through the window that pops up when this node is launched. (From top to bottom: the speed-acceleration phase diagram, the speed-acceleration heatmap, the speed-steering angle heatmap, the speed-steer rate heatmap, and the speed-jerk heatmap.)

      For the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap, the collection range can be specified by the masks located in the folder config/masks/MASK_NAME where MASK_NAME is a parameter specifying mask name (Please also see config/common_param.yaml). The specified heatmap cells are designed to change from blue to green once a certain amount of data (VEL_ACC_THRESHOLD, VEL_STEER_THRESHOLD, VEL_ABS_STEER_RATE_THRESHOLD ) is collected. It is recommended to collect data until as many cells as possible turn green.

    8. If you want to stop data collecting automatic driving, run the following command

      ros2 topic pub /data_collecting_stop_request std_msgs/msg/Bool \"data: true\" --once\n

      [!NOTE] When the car crosses the green boundary line, a similar stopping procedure will be automatically triggered.

    9. If you want to restart data collecting automatic driving, run the following command

      ros2 topic pub /data_collecting_stop_request std_msgs/msg/Bool \"data: false\" --once\n
    "},{"location":"control_data_collecting_tool/#specify-data-collection-range","title":"Specify data collection range","text":"

    You can create an original mask to specify the data collection range for the heatmap explained in step 7 of the \"How to Use\" section.

    1. Change the MASK_NAME parameter in config/common_param.yaml from its default value of default to any name you prefer.

    2. Modify parameters such as VEL_ACC_THRESHOLD, VEL_STEER_THRESHOLD, and VEL_ABS_STEER_RATE_THRESHOLD to determine the desired amount of data for each cell in the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap.

    3. In the scripts/masks directory, run

      python3 mask_selector.py\n

      then, matplotlib windows for selecting the collection range of the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap will be displayed, one for each.

      In these windows, you can modify the heatmaps by clicking or dragging within them. Once you've made your changes, pressing Ctrl+C in the terminal will automatically save the updated maps.

      Afterward, rebuild the control_data_collecting_tool using the following command

      colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=\"-w\" --symlink-install --continue-on-error --packages-up-to control_data_collecting_tool\n

      and relaunch the control_data_collecting_tool with

      ros2 launch control_data_collecting_tool control_data_collecting_tool.launch.py map_path:=$HOME/autoware_map/sample-map-planning\n

      This will allow you to see the selected mask applied.

    "},{"location":"control_data_collecting_tool/#parameter","title":"Parameter","text":"

    There are parameters that are common to all trajectories and parameters that are specific to each trajectory.

    "},{"location":"control_data_collecting_tool/#common-parameters","title":"Common Parameters","text":"

    ROS 2 parameters which are common in all trajectories (/config/common_param.yaml):

    Name Type Description Default value LOAD_ROSBAG2_FILES bool Flag that determines whether to load rosbag2 data or not true COURSE_NAME string Course name [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle, along_road] reversal_loop_circle NUM_BINS_V int Number of bins of velocity in heatmap 10 NUM_BINS_STEER int Number of bins of steer in heatmap 20 NUM_BINS_A int Number of bins of acceleration in heatmap 10 NUM_BINS_ABS_STEER_RATE int Number of bins of absolute value of steer rate in heatmap 5 NUM_BINS_JERK int Number of bins of jerk in heatmap 10 V_MIN double Minimum velocity in heatmap [m/s] 0.0 V_MAX double Maximum velocity in heatmap [m/s] 11.5 STEER_MIN double Minimum steer in heatmap [rad] -0.6 STEER_MAX double Maximum steer in heatmap [rad] 0.6 A_MIN double Minimum acceleration in heatmap [m/s^2] -1.0 A_MAX double Maximum acceleration in heatmap [m/s^2] 1.0 max_lateral_accel double Max lateral acceleration limit [m/s^2] 2.00 ABS_STEER_RATE_MIN double Minimum absolute value of steer rate in heatmap [rad/s] 0.0 ABS_STEER_RATE_MAX double Maximum absolute value of steer rate in heatmap [rad/s] 0.3 JERK_MIN double Minimum jerk in heatmap [m/s^3] -0.5 JERK_MAX double Maximum jerk in heatmap [m/s^3] 0.5 MASK_NAME string Directory name of masks for data collection default VEL_ACC_THRESHOLD int Threshold of velocity-and-acc heatmap in data collection 40 VEL_STEER_THRESHOLD int Threshold of velocity-and-steer heatmap in data collection 20 VEL_ABS_STEER_RATE_THRESHOLD int Threshold of velocity-and-abs_steer_rate heatmap in data collection 20 max_lateral_accel double Max lateral acceleration limit [m/s^2] 2.00 lateral_error_threshold double Lateral error threshold where applying velocity limit [m] 1.50 yaw_error_threshold double Yaw error threshold where applying velocity limit [rad] 0.75 velocity_limit_by_tracking_error double Velocity limit applied when tracking error exceeds threshold [m/s] 1.0 mov_ave_window int Moving average smoothing window size 50 target_longitudinal_velocity double Target longitudinal velocity [m/s] 6.0 pure_pursuit_type string Pure pursuit type (naive or linearized steer control law ) linearized wheel_base double Wheel base [m] 2.79 acc_kp double Accel command proportional gain 1.0 lookahead_time double Pure pursuit lookahead time [s] 2.0 min_lookahead double Pure pursuit minimum lookahead length [m] 2.0 linearized_pure_pursuit_steer_kp_param double Linearized pure pursuit steering P gain parameter 2.0 linearized_pure_pursuit_steer_kd_param double Linearized pure pursuit steering D gain parameter 2.0 stop_acc double Accel command for stopping data collecting driving [m/s^2] -2.0 stop_jerk_lim double Jerk limit for stopping data collecting driving [m/s^3] 5.0 lon_acc_lim double Longitudinal acceleration limit [m/s^2] 1.5 lon_jerk_lim double Longitudinal jerk limit [m/s^3] 0.5 steer_lim double Steering angle limit [rad] 0.6 steer_rate_lim double Steering angle rate limit [rad/s] 0.6

    The following parameters are common to all trajectories but can be defined individually for each trajectory. (/config/course_param/COURSE_NAME_param.yaml):

    Name Type Description Default value COLLECTING_DATA_V_MIN double Minimum velocity for data collection [m/s] 0.5 COLLECTING_DATA_V_MAX double Maximum velocity for data collection [m/s] 8.0 COLLECTING_DATA_A_MIN double Minimum velocity for data collection [m/s^2] 1.0 COLLECTING_DATA_A_MAX double Maximum velocity for data collection [m/s^2] -1.0 longitudinal_velocity_noise_amp double Target longitudinal velocity additional sine noise amplitude [m/s] 0.01 longitudinal_velocity_noise_min_period double Target longitudinal velocity additional sine noise minimum period [s] 5.0 longitudinal_velocity_noise_max_period double Target longitudinal velocity additional sine noise maximum period [s] 20.0 acc_noise_amp double Accel command additional sine noise amplitude [m/ss] 0.01 acc_noise_min_period double Accel command additional sine noise minimum period [s] 5.0 acc_noise_max_period double Accel command additional sine noise maximum period [s] 20.0 steer_noise_amp double Steer command additional sine noise amplitude [rad] 0.01 steer_noise_max_period double Steer command additional sine noise maximum period [s] 5.0 steer_noise_min_period double Steer command additional sine noise minimum period [s] 20.0"},{"location":"control_data_collecting_tool/#course-specific-parameters","title":"Course-Specific Parameters","text":"

    Each trajectory has specific ROS 2 parameters.

    • COURSE_NAME: eight_course
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 4.5 smoothing_window double Width of the window for trajectory smoothing 400
    • COURSE_NAME: u_shaped_return
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 4.5
    • COURSE_NAME: straight_line_positive or COURSE_NAME: straight_line_negative
    Name Type Description Default value stopping_buffer_distance double The safety distance from end of the straight line [m] 10.0
    • COURSE_NAME: reversal_loop_circle
    Name Type Description Default value trajectory_radius double Radius of the circle where trajectories are generated [m] 35.0 enclosing_radius double Radius of the circle enclosing the generated trajectories [m] 40.0 look_ahead_distance double The distance referenced ahead of the vehicle for collecting steering angle data [m] 15.0
    • COURSE_NAME: along_road
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 3.5 stopping_buffer_distance double The safety distance from end of the straight line [m] 15.0 course_width double The width of the trajectory [m] 1.5 smoothing_window double Width of the window for trajectory smoothing 100 minimum_length_of_straight_line double The minimum length of straight line for data collection [m] 50.0 longitude double The longitude of the origin specified when loading the map [degree] 139.6503 latitude double The latitude of the origin specified when loading the map [degree] 35.6762"},{"location":"driving_environment_analyzer/","title":"Driving Environment Analyzer","text":""},{"location":"driving_environment_analyzer/#driving-environment-analyzer","title":"Driving Environment Analyzer","text":"

    \u3053\u306e\u30c4\u30fc\u30eb\u306fROSBAG\u306b\u542b\u307e\u308c\u308b\u8d70\u884c\u5c65\u6b74\u3092\u5143\u306b\u8d70\u884c\u74b0\u5883\u306eODD\u3092\u89e3\u6790\u3059\u308b\u30c4\u30fc\u30eb\u3067\u3059\u3002

    "},{"location":"driving_environment_analyzer/#rosbagodd","title":"ROSBAG\u306e\u7279\u5b9a\u6642\u523b\u306b\u304a\u3051\u308b\u5468\u56f2\u306eODD\u3092\u89e3\u6790\u3059\u308b\u5834\u5408","text":"

    \u3053\u306e\u5834\u5408\u306b\u306fRviz\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3042\u308bdriving_environment_analyzer_rviz_panel\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3092\u304a\u3059\u3059\u3081\u3057\u307e\u3059\u3002

    \u73fe\u5728\u4ee5\u4e0b\u306e\u60c5\u5831\u304c\u51fa\u529b\u53ef\u80fd\u3067\u3059\u3002

    • EGO\u306e\u73fe\u5728\u8eca\u901f
    • \u73fe\u5728\u4f4d\u7f6e\u306e\u52fe\u914d
    • EGO\u306e\u6319\u52d5
    • \u73fe\u5728\u306e\u8eca\u7dda\u60c5\u5831

    \u3053\u3061\u3089\u306e\u30c4\u30fc\u30eb\u306fautoware_launch\u306b\u542b\u307e\u308c\u308blogging_simulator\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u307e\u305a\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u304b\u3089\u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u3092\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    ros2 launch autoware_launch logging_simulator.launch.xml map_path:=<MAP> vehicle_model:=<VEHICLE_NAME> sensor_model:=<AIP_NAME> sensing:=false control:=false planning:=false perception:=false localization:=false system:=false

    \u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u8d77\u52d5\u6642\u306b\u5730\u56f3\u3092\u8aad\u307f\u8fbc\u3080\u305f\u3081ROSBAG\u306b\u5730\u56f3\u60c5\u5831\u304c\u542b\u307e\u308c\u3066\u3044\u306a\u304f\u3066\u3082ODD\u306e\u89e3\u6790\u304c\u53ef\u80fd\u3067\u3059\u3002\uff08\u305f\u3060\u3057\u3001\u305d\u306e\u5834\u5408\u306b\u306fROSBAG\u53d6\u5f97\u306e\u969b\u306b\u4f7f\u7528\u3057\u305f\u5730\u56f3\u3092\u6307\u5b9a\u3057\u3066\u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u3092\u8d77\u52d5\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\uff09

    \u6b21\u306b\u672c\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u542b\u307e\u308c\u308b\u89e3\u6790\u30c4\u30fc\u30eb\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002Rviz\u753b\u9762\u5de6\u4e0a\u90e8\u306eAdd New Panel\u304b\u3089DrivingEnvironmentAnalyzerPanel\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u308c\u3067Rviz\u5de6\u4e0b\u306b\u65b0\u3057\u304f\u64cd\u4f5c\u30d1\u30cd\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002

    \u672c\u30c4\u30fc\u30eb\u306fROSBAG\u30d5\u30a1\u30a4\u30eb\u6307\u5b9a\u3057\u3066\u30ed\u30fc\u30c9\u3067\u304d\u308b\u4ed6\u3001\u8907\u6570\u306eROSBAG\u30d5\u30a1\u30a4\u30eb\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\u305f\u3060\u3057\u3001\u305d\u306e\u5834\u5408\u306b\u306f\u4e8b\u524d\u306b\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3067metadata.yaml\u306e\u751f\u6210\u304c\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u3002

    ros2 bag reindex <DIR_PATH> sqlite3

    ROSBAG\u306e\u8aad\u307f\u8fbc\u307f\u304c\u5b8c\u4e86\u3057\u305f\u3089ODD\u3092\u89e3\u6790\u3057\u305f\u3044\u6642\u523b\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u6642\u523b\u306e\u6307\u5b9a\u306b\u306fUnix time\u3092\u76f4\u63a5\u6307\u5b9a\u3059\u308b\u307b\u304b\u30b9\u30e9\u30a4\u30c9\u30d0\u30fc\u3082\u4f7f\u7528\u53ef\u80fd\u3067\u3059\u3002\u5de6\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u65e5\u6642\u3092\u53c2\u8003\u306b\u8abf\u6574\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    \u307e\u305f\u3001\u3053\u306e\u3068\u304dViews\u306eTarget Flame\u3092base_link\u306b\u3057\u3066\u304a\u304f\u3053\u3068\u3067\u3001\u6307\u5b9a\u3057\u305f\u6642\u523b\u306eEGO\u306e\u4f4d\u7f6e\u3068\u5468\u56f2\u306e\u72b6\u6cc1\u3092Rviz\u3067\u53ef\u8996\u5316\u53ef\u80fd\u3067\u3059\u3002

    \u6642\u523b\u306e\u6307\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001Set time stamp\u30dc\u30bf\u30f3\u3092\u62bc\u3057\u3001\u6700\u5f8c\u306bAnalyze dynamic ODD factor\u3092\u62bc\u3059\u3053\u3068\u3067\u89e3\u6790\u304c\u59cb\u307e\u308a\u307e\u3059\u3002

    [rviz2-11] ***********************************************************\n[rviz2-11]                    ODD analysis result\n[rviz2-11] ***********************************************************\n[rviz2-11] Type: TIME SPECIFIED\n[rviz2-11] Time: 2024-04-22 14:48:05\n[rviz2-11]\n[rviz2-11]\n[rviz2-11] - EGO INFO\n[rviz2-11]   [SPEED]                       : 0 [m/s]\n[rviz2-11]   [ELEVATION ANGLE]             : 0.00963597 [rad]\n[rviz2-11]\n[rviz2-11] - EGO BEHAIOVR\n[rviz2-11]   [AVOIDANCE(R)]                : NONE\n[rviz2-11]   [AVOIDANCE(L)]                : NONE\n[rviz2-11]   [LANE_CHANGE(R)]              : NONE\n[rviz2-11]   [LANE_CHANGE(L)]              : NONE\n[rviz2-11]   [START_PLANNER]               : SAFE: true COMMAND: deactivate\n[rviz2-11]   [GOAL_PLANNER]                : NONE\n[rviz2-11]   [CROSSWALK]                   : NONE\n[rviz2-11]   [INTERSECTION]                : NONE\n[rviz2-11]\n[rviz2-11] - LANE INFO\n[rviz2-11]   [ID]                          : 176126\n[rviz2-11]   [WIDTH]                       : 4.24132 [m]\n[rviz2-11]   [SHAPE]                       : STRAIGHT\n[rviz2-11]   [RIGHT LANE NUM]              : 0\n[rviz2-11]   [LEFT LANE NUM]               : 0\n[rviz2-11]   [TOTAL LANE NUM]              : 1\n[rviz2-11]   [SAME DIRECTION LANE]         : NONE\n[rviz2-11]   [OPPOSITE DIRECTION LANE]     : NONE\n[rviz2-11]   [ROAD SHOULDER]               : EXIST\n[rviz2-11]\n[rviz2-11] - SURROUND OBJECT NUM\n[rviz2-11]   [UNKNOWN]                     : 0\n[rviz2-11]   [CAR]                         : 6\n[rviz2-11]   [TRUCK]                       : 0\n[rviz2-11]   [BUS]                         : 3\n[rviz2-11]   [TRAILER]                     : 2\n[rviz2-11]   [MOTORCYCLE]                  : 0\n[rviz2-11]   [BICYCLE]                     : 0\n[rviz2-11]   [PEDESTRIAN]                  : 7\n[rviz2-11] ***********************************************************\n
    "},{"location":"driving_environment_analyzer/#rosbagodd_1","title":"ROSBAG\u5168\u4f53\u306b\u5bfe\u3057\u3066\u7d4c\u8def\u6cbf\u3044\u306eODD\u3092\u89e3\u6790\u3059\u308b\u5834\u5408","text":"

    \u73fe\u5728\u4ee5\u4e0b\u306e\u60c5\u5831\u304c\u51fa\u529b\u53ef\u80fd\u3067\u3059\u3002

    • \u8d70\u884c\u7d4c\u8def\u306e\u9577\u3055
    • \u8d70\u884c\u7d4c\u8def\u306e\u8eca\u7dda\u60c5\u5831
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u30fb\u6700\u5c0f\u52fe\u914d
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u66f2\u7387
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u30fb\u6700\u5c0f\u8eca\u7dda\u5e45
    • \u4ea4\u5dee\u70b9\u306e\u6709\u7121
    • \u4fe1\u53f7\u6a5f\u306e\u6709\u7121
    • \u6a2a\u65ad\u6b69\u9053\u306e\u6709\u7121

    \u8d77\u52d5\u6642\u306bbag_path\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u89e3\u6790\u3057\u305f\u3044ROSBAG\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u6307\u5b9a\u3082.db3\u30d5\u30a1\u30a4\u30eb\u306e\u76f4\u63a5\u6307\u5b9a\u3082\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\u3002\uff09

    \u89e3\u6790\u306b\u5fc5\u8981\u306atopic\u306f\u4ee5\u4e0b\u306e\u3068\u304a\u308a\u3067\u3059\u3002\uff08\u4eca\u5f8c\u5897\u3048\u308b\u53ef\u80fd\u6027\u3082\u3042\u308a\u307e\u3059\u3002\uff09

    • /planning/mission_planning/route
    • /map/vector_map

    \u4ee5\u4e0b\u306e\u3088\u3046\u306blaunch\u3059\u308b\u3053\u3068\u3067ODD\u306e\u89e3\u6790\u7d50\u679c\u304c\u5f97\u3089\u308c\u307e\u3059\u3002

    ros2 launch driving_environment_analyzer driving_environment_analyzer.launch.xml use_map_in_bag:=true bag_path:=<ROSBAG>

    [component_container-1] [INFO 1708999777.768870564] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.768922452] [driving_environment_analyzer]:  data is ready. start ODD analysis...\n[component_container-1] [INFO 1708999777.768933574] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.768967412] [driving_environment_analyzer]: - Length of total lanes : 2357.50 [m]\n[component_container-1] [INFO 1708999777.769031174] [driving_environment_analyzer]: - Length of lane that has adjacent lane : 2080.43 [m]\n[component_container-1] [INFO 1708999777.769076141] [driving_environment_analyzer]: - Length of lane that has opposite lane : 0.00 [m]\n[component_container-1] [INFO 1708999777.769101793] [driving_environment_analyzer]: - Length of lane that has no adjacent lane : 277.07 [m]\n[component_container-1] [INFO 1708999777.769225729] [driving_environment_analyzer]: - Min lane width: 3.14 [m] Max lane width: 4.94 [m]\n[component_container-1] [INFO 1708999777.769278698] [driving_environment_analyzer]: - Max curvature: 0.007967 [1/m]\n[component_container-1] [INFO 1708999777.769293161] [driving_environment_analyzer]: - Min curve radius: 125.52 [m]\n[component_container-1] [INFO 1708999777.769336094] [driving_environment_analyzer]: - Min elevation angle: -0.033037 [rad] Max elevation angle: 0.026073 [rad]\n[component_container-1] [INFO 1708999777.769403870] [driving_environment_analyzer]: - Min speed limit: 13.89 [m/s] Max speed limit: 16.67 [m/s]\n[component_container-1] [INFO 1708999777.769424648] [driving_environment_analyzer]: - Exist traffic light: true\n[component_container-1] [INFO 1708999777.769435813] [driving_environment_analyzer]: - Exist intersection: true\n[component_container-1] [INFO 1708999777.769620035] [driving_environment_analyzer]: - Exist crosswalk: true\n[component_container-1] [INFO 1708999777.769634980] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.769642769] [driving_environment_analyzer]:  complete ODD analysis. shutdown.\n[component_container-1] [INFO 1708999777.769650034] [driving_environment_analyzer]: ======================================\n

    \u305f\u3060\u3057\u3001map/vector_map\u306b\u95a2\u3057\u3066\u306fuse_map_in_bag\u3092false\u306b\u3059\u308b\u3053\u3068\u3067\u30ed\u30fc\u30ab\u30eb\u74b0\u5883\u306b\u4fdd\u5b58\u3055\u308c\u3066\u3044\u308b\u5730\u56f3\u3092\u4f7f\u7528\u3057\u3066ODD\u89e3\u6790\u3092\u884c\u3046\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\u305d\u306e\u5834\u5408\u3001map_path\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u5730\u56f3\u306e\u30d1\u30b9\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    ros2 launch driving_environment_analyzer driving_environment_analyzer.launch.xml use_map_in_bag:=false map_path:=<MAP> bag_path:=<ROSBAG>

    \u4ee5\u4e0a\u306e\u3088\u3046\u306b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067ROSBAG\u306b\u5730\u56f3\u60c5\u5831\u304c\u4fdd\u5b58\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082ODD\u89e3\u6790\u304c\u53ef\u80fd\u3067\u3059\u3002

    "},{"location":"evaluation/tier4_metrics_rviz_plugin/","title":"tier4_metrics_rviz_plugin","text":""},{"location":"evaluation/tier4_metrics_rviz_plugin/#tier4_metrics_rviz_plugin","title":"tier4_metrics_rviz_plugin","text":""},{"location":"evaluation/tier4_metrics_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin panel to visualize planning_evaluator output.

    "},{"location":"evaluation/tier4_metrics_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":"Name Type Description /planning/planning_evaluator/metrics diagnostic_msgs::msg::DiagnosticArray Subscribe planning_evaluator output"},{"location":"evaluation/tier4_metrics_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.
    2. Select MetricsVisualizePanel and press OK.
    "},{"location":"localization/deviation_estimation_tools/ReadMe/","title":"deviation_estimation_tools","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#deviation_estimation_tools","title":"deviation_estimation_tools","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#1-quick-start","title":"1. Quick start","text":"

    This repository consists of three main tools implemented on ROS 2.

    1. Deviation Estimator
    2. Deviation Evaluator
    3. Deviation Evaluation Visualizer
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#a-estimation-step","title":"A. Estimation step","text":"

    Here you estimate the following parameters using deviation_estimator.

    • the standard deviation of velocity and yaw rate
    • the bias of velocity and yaw rate

    Launch the node with the following command. Make sure you set the correct parameters (see Sec. 2).

    ros2 launch deviation_estimator deviation_estimator.launch.xml\n

    Then, you need to run either ROS bag or autoware_launch to provide pose and twist to deviation_estimator.

    If you are using rosbag, it should contain the following topics:

    • Raw IMU data (default: /sensing/imu/tamagawa/imu_raw)
    • Raw velocity data (default: /vehicle/status/velocity_status)
    • /localization/pose_estimator/pose_with_covariance
    • /clock
    • /tf_static (that contains transform from base_link to imu_link)

    NOTE that the pose and twist must be estimated with default parameters (see known issues section for detail).

    Play the rosbag in a different terminal:

    ros2 bag play YOUR_BAG # You can also play in a faster rate, e.g. -r 5\n

    You can check the results in the following three output files:

    1. IMU parameters (default: $HOME/imu_corrector.param.yaml)
    2. Velocity parameters (default: $HOME/vehicle_velocity_converter.param.yaml)
    3. Logs (default: $HOME/output.txt)
    sample input (rosbag)

    Files:             localized_sensors_0.db3\nBag size:          9.6 MiB\nStorage id:        sqlite3\nDuration:          76.539s\nStart:             Jul  8 2022 11:21:41.220 (1657246901.220)\nEnd:               Jul  8 2022 11:22:57.759 (1657246977.759)\nMessages:          32855\nTopic information: Topic: /localization/pose_estimator/pose_with_covariance | Type: geometry_msgs/msg/PoseWithCovarianceStamped | Count: 2162 | Serialization Format: cdr\n                   Topic: /clock | Type: rosgraph_msgs/msg/Clock | Count: 57309 | Serialization Format: cdr\n                   Topic: /tf_static | Type: tf2_msgs/msg/TFMessage | Count: 2 | Serialization Format: cdr\n                   Topic: /sensing/imu/tamagawa/imu_raw | Type: sensor_msgs/msg/Imu | Count: 8076 | Serialization Format: cdr\n                   Topic: /vehicle/status/velocity_status | Type: autoware_vehicle_msgs/msg/VelocityReport | Count: 8275 | Serialization Format: cdr\n
    sample output (output.txt)

    # Validation results\n# value: [min, max]\n[OK] coef_vx: [0.99538, 0.99593]\n[OK] stddev_vx: [0.17192, 0.19161]\n[OK] angular_velocity_offset_x: [-0.00742, -0.00727]\n[OK] angular_velocity_offset_y: [-0.00119, -0.00115]\n[OK] angular_velocity_offset_z: [0.00635, 0.00641]\n[OK] angular_velocity_stddev_xx: [0.04151, 0.04258]\n[OK] angular_velocity_stddev_yy: [0.04151, 0.04258]\n[OK] angular_velocity_stddev_zz: [0.04151, 0.04258]\n
    sample output (imu_corrector.param.yaml)
    # Estimated by deviation_estimator\n/**:\n  ros__parameters:\n    angular_velocity_stddev_xx: 0.01798\n    angular_velocity_stddev_yy: 0.01798\n    angular_velocity_stddev_zz: 0.01798\n    angular_velocity_offset_x: -0.00952\n    angular_velocity_offset_y: -0.00095\n    angular_velocity_offset_z: 0.00607\n

    sample output (vehicle_velocity_converter.param.yaml)
    # Estimated by deviation_estimator\n/**:\n  ros__parameters:\n    speed_scale_factor: 0.99507\n    velocity_stddev_xx: 0.16708\n    velocity_stddev_xx: 0.1 # Default value\nframe_id: base_link # Default value\n

    unit tool If you build normally, a binary will be generated under `install/deviation_estimator/lib/`.
    colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --packages-up-to deviation_estimator\nsource ~/autoware/install/setup.bash\n~/autoware/install/deviation_estimator/lib/deviation_estimator/deviation_estimator_unit_tool <path_to_rosbag>\n

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#b-evaluation-step","title":"B. Evaluation step","text":"

    Here, you can evaluate the estimated standard deviation and bias using a package deviation_evaluator. Execute the following command:

    ros2 launch deviation_evaluator deviation_evaluator.launch.xml map_path:=MAP_PATH rviz:=true in_imu:=YOUR_IMU_TOPIC_NAME in_wheel_odometry:=YOUR_VELOCITY_TOPIC_NAME\nros2 bag play YOUR_BAG\n
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#c-visualization-step","title":"C. Visualization step","text":"

    After the evaluation, run the following command to generate the final results in $HOME/deviation_evaluator_sample.

    pip3 install -r requirements.txt\nros2 launch deviation_evaluator deviation_evaluation_visualizer.launch.xml\n

    Done!

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#2-description-of-deviation-estimator","title":"2. Description of Deviation Estimator","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#overview","title":"Overview","text":"

    The Deviation Estimator estimates the standard deviation and bias for velocity and yaw bias, by comparing the velocity and gyro observations with ground truth poses (e.g. from LiDAR-based localization).

    Here are some assumptions made for input data:

    • The data should have accurate localization results. It doesn't need to be strictly precise, but data that is obviously incorrect should be avoided. In case of NDT in Autoware, it should not have any TP or NVTL warnings from the ndt_scan_matcher.
    • The data should cover a reasonable duration of driving. A few minutes of data is sufficient. It is desirable to have a distance of approximately 500 meters. (For example, around 2 minutes at a speed of 15 km/h).
    • The data should include sections of driving in a straight line. This is necessary for estimating velocity-related parameters. Having at least one minute of straight line driving is enough.
    • The data should cover the expected speed range during operation.
    • [Optional] Ideally, the data should be recorded as recently as possible. Especially in cases where IMU or tire replacement has occurred, data recorded before those changes may not provide accurate estimations.
    • [Optional] The data should cover various driving behaviors expected during operation, such as right turns, left turns, acceleration, and deceleration.
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#launch","title":"Launch","text":"

    The deviation_estimator can be launched with the following command.

    ros2 launch deviation_estimator deviation_estimator.launch.xml\nros2 bag play YOUR_BAG # You can also play in a faster rate, e.g. -r 5\n

    The parameters and input topic names can be seen in the deviation_estimator.launch.xml file. YOUR_BAG should include all the required inputs written below.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#input","title":"Input","text":"Name Type Description in_pose_with_covariance |geometry_msgs::msg::PoseWithCovarianceStamped` Input pose in_imu sensor_msgs::msg::Imu Input IMU data in_wheel_odometry autoware_vehicle_msgs::msg::VelocityReport Input wheel odometry"},{"location":"localization/deviation_estimation_tools/ReadMe/#output","title":"Output","text":"Name Type Description /estimated_stddev_vx std_msgs::msg::Float64 estimated standard deviation of vx /estimated_stddev_angular_velocity geometry_msgs/msg/Vector3 estimated standard deviation of angular velocity /estimated_coef_vx std_msgs::msg::Float64 coef of vx /estimated_bias_angular_velocity geometry_msgs/msg/Vector3 bias of angular velocity"},{"location":"localization/deviation_estimation_tools/ReadMe/#parameters-for-deviation-estimator","title":"Parameters for deviation estimator","text":"Name Type Description Default value show_debug_info bool Flag to display debug info true t_design double Maximum expected duration of dead-reckoning [s] 10.0 x_design double Maximum expected trajectory length of dead-reckoning [m] 30.0 time_window double Estimation period [s] 4.0 results_dir string Text path where the estimated results will be stored \"$(env HOME)\" gyro_estimation.only_use_straight bool Flag to use only straight sections for gyro estimation true gyro_estimation.only_use_moving bool Flag to use only moving sections for gyro estimation true gyro_estimation.only_use_constant_velocity bool Flag to use only constant velocity sections for gyro estimation true velocity_estimation.only_use_straight bool Flag to use only straight sections for velocity estimation true velocity_estimation.only_use_moving bool Flag to use only moving sections for velocity estimation true velocity_estimation.only_use_constant_velocity bool Flag to use only constant velocity sections for velocity estimation true"},{"location":"localization/deviation_estimation_tools/ReadMe/#functions","title":"Functions","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#bias-estimation","title":"Bias estimation","text":"

    By assuming that the pose information is a ground truth, the node estimates the bias of velocity and yaw rate.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#standard-deviation-estimation","title":"Standard deviation estimation","text":"

    The node also estimates the standard deviation of velocity and yaw rate. This can be used as a parameter in ekf_localizer. Note that the final estimation takes into account the bias.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#3-description-of-deviation-evaluator","title":"3. Description of Deviation Evaluator","text":"

    You can use deviation_evaluator for evaluating the estimated standard deviation parameters. This can be run with the following command:

    ros2 launch deviation_evaluator deviation_evaluator.launch.xml map_path:=MAP_PATH rviz:=true in_imu:=YOUR_IMU_TOPIC_NAME in_wheel_odometry:=YOUR_VELOCITY_TOPIC_NAME\nros2 bag play YOUR_BAG\n

    All the ros2bag and config files will be stored in $HOME/deviation_evaluator_sample (you can change this with save_dir parameter in the launch file).

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#features","title":"Features","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#a-visualization-of-confidence-ellipse","title":"A. Visualization of confidence ellipse","text":"

    deviation_evaluator supports rviz visualization. To use this feature, set rviz:=true and map_path:=/path/to/map_folder.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#b-check-the-compatibility-with-a-threshold-in-localization_error_monitor","title":"B. Check the compatibility with a threshold in localization_error_monitor","text":"

    The deviation_evaluator also checks the compatibility of the estimated parameters and the threshold in localization_error_monitor.

    Concretely, it checks if the two following statement holds:

    1. localization_error_monitor would NOT diagnose the system as WARN nor ERROR as long as the NDT is available.
    2. localization_error_monitor detects the anomaly with a recall over 0.99.

    Given the result of this validation, the users can verify that the estimated parameters in deviation_estimator can be safely applied to Autoware.

    Here, note that the localization_error_monitor treat the system as an anomaly if either of error along long-axis of confidence ellipse or error along lateral direction is over threshold. Please refer to the package in autoware.universe for detail.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#architecture-of-deviation_evaluator","title":"Architecture of deviation_evaluator","text":"

    The architecture of deviation_evaluator is shown below. It launches two ekf_localizer, one for ground truth estimation and one for (partially) dead reckoning estimation. Outputs of both ekf_localizer will be recorded and analyzed with deviation_evaluation_visualizer.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#inputs-outputs_1","title":"Inputs / Outputs","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#input_1","title":"Input","text":"Name Type Description in_ndt_pose_with_covariance geometry_msgs::msg::PoseWithCovarianceStamped Input pose in_ekf_dr_odom nav_msgs::msg::Odometry dead-reckoning EKF outputs in_ekf_gt_odom nav_msgs::msg::Odometry ground-truth EKF outputs"},{"location":"localization/deviation_estimation_tools/ReadMe/#output_1","title":"Output","text":"Name Type Description out_pose_with_covariance_dr geometry_msgs::msg::PoseWithCovarianceStamped Output pose (for dead reckoning ekf_localizer) out_pose_with_covariance_gt geometry_msgs::msg::PoseWithCovarianceStamped Output pose (for ground truth ekf_localizer) out_initial_pose_with_covariance geometry_msgs::msg::PoseWithCovarianceStamped Output initial pose (for both ekf_localizer)"},{"location":"localization/deviation_estimation_tools/ReadMe/#parameters-for-deviation-evaluator","title":"Parameters for deviation evaluator","text":"Name Type Description Default value rviz bool Show rviz if true false map_path string Path to the directory where map data (OpenStreetMap or .osm data) is saved \"\" save_dir string Output directory where figures, parameter files, and scores are saved \"$(env HOME)/deviation_evaluator_sample\" period double [s] Duration of cycle 10 (in config/deviation_evaluator.yaml) cut double [s] Duration of ndt-cut-off 9 (in config/deviation_evaluator.yaml)"},{"location":"localization/deviation_estimation_tools/ReadMe/#4-reflect-the-estimated-parameters-in-autoware","title":"4. Reflect the estimated parameters in Autoware","text":"

    The results of deviation_estimator is stored in two scripts:

    • imu_corrector param file (default: $HOME/imu_corrector.param.yaml)
    • vehicle_velocity_converter param file (default: $HOME/vehicle_velocity_converter.param.yaml)

    Please modify your Autoware configuration so that it will launch using the above two parameter files.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#5-known-issues","title":"5. Known issues","text":"
    • The plot of deviation_evaluator.png generated by deviation_evaluation_visualizer may diverge, possibly due to the large covariance caused by a failure in localization.
    • ekf_localizer in deviation_evaluator may not start properly. As for now, please launch deviation_evaluator first and then run ros2 bag play to provide pose and twist data.
    "},{"location":"map/autoware_lanelet2_map_utils/","title":"autoware_lanelet2_map_utils","text":""},{"location":"map/autoware_lanelet2_map_utils/#autoware_lanelet2_map_utils","title":"autoware_lanelet2_map_utils","text":"

    This package is for preprocessing the lanelet map.

    "},{"location":"map/autoware_lanelet2_map_validator/","title":"autoware_lanelet2_map_validator","text":""},{"location":"map/autoware_lanelet2_map_validator/#autoware_lanelet2_map_validator","title":"autoware_lanelet2_map_validator","text":"

    autoware_lanelet2_map_validator is a tool to validate Lanelet2 maps to ensure that Autoware can work properly with it.

    This validation tool is an extension of lanelet2_validation so that Autoware specific rules can be applied. As you can see from the codes in the src/validators directory, the group of validators belong to this tool inherits the lanelet::validation::MapValidator class from the original lanelet2_validation. Therefore, we believe that reading the source code of the lanelet2_validation will help you understand this tool better.

    Note that this validator is still on construction that there are only a few rules and a template to define those rules.

    The official Autoware requirements for lanelet2 maps are described in Vector Map creation requirement specifications (in Autoware Documentation).

    "},{"location":"map/autoware_lanelet2_map_validator/#design-concept","title":"Design concept","text":"

    The autoware_lanelet2_map_validator is designed to validate .osm map files by using and extending the lanelet2_validation package for Autoware.

    autoware_lanelet2_map_validator takes the lanelet2 map (.osm file) and requirement set (JSON file, optional) as the input, and output validation results to the console.

    If a requirement set is given, autoware_lanelet2_map_validator also outputs validation results reflecting the input requirement set. See \"Run with a requirement set\" for further information, \"Input file\" to understand the input format, and \"Output file\" to understand the output format.

    "},{"location":"map/autoware_lanelet2_map_validator/#how-to-use","title":"How to use","text":"

    Basically, you can use the following command to execute autoware_lanelet2_map_validator. However, note that autoware_lanelet2_map_validator is a ROS/rclcpp free tool, so you can just run the built executable whatever way.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-all-validators","title":"Run ALL validators","text":"

    You can use autoware_lanelet2_map_validator with the following command. This will run all validators including the default built-in validators in the lanelet2_validation.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-a-specific-validator","title":"Run a specific validator","text":"

    autoware_lanelet2_map_validator consists of multiple small validators in order to realize complex requirements with a combination of them. If you want to call a few validators, you can select them with the --validator, -v option.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --validator mapping.traffic_light.missing_regulatory_elements\n

    You can get a list of available validators with the --print option. (-p is for --projection)

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --print\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-with-a-requirement-set","title":"Run with a requirement set","text":"

    autoware_lanelet2_map_validator can manage to run a group of validators by a list of validator names. autoware_lanelet2_map_validator will scan through the input JSON file given by the --input_requirements, -i option, and output the validation results to the directory given by the --output_directory, -o option. The output filename will be lanelet2_validation_results.json.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --input_requirements autoware_requirements_set.json --output_directory ./\n

    (Short version)

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator -m path/to_your/lanelet2_map.osm -p mgrs -i autoware_requirements_set.json -o ./\n
    "},{"location":"map/autoware_lanelet2_map_validator/#input-file","title":"Input file","text":"

    The JSON file input should follow the structure like this example.

    {\n\"requirements\": [\n{\n\"id\": \"vm-02-02\",\n\"validators\": [\n{\n\"name\": \"mapping.stop_line.missing_regulatory_elements\"\n}\n]\n},\n{\n\"id\": \"vm-04-01\",\n\"validators\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n},\n{\n\"name\": \"mapping.crosswalk.regulatory_element_details\",\n\"prerequisites\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n}\n]\n}\n]\n},\n{\n\"id\": \"vm-05-01\",\n\"validators\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n},\n{\n\"name\": \"mapping.traffic_light.regulatory_element_details\",\n\"prerequisites\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n}\n]\n}\n]\n}\n]\n}\n
    • MUST have a single requirements field.
    • The requirements field MUST be a list of requirements. A requirement MUST have
      • id : The id of the requirement. Its name is arbitrary.
      • validators : A list of validators that structures the requirement.
        • A validator MUST be given with its name on the name field.
        • The name list of available validators can be obtained from the --print option.
        • You can add a list of prerequisites to each validator. Then, the validator will only be run when the prerequisites pass the validation.
        • In the prerequisites field, you can add forgive_warnings: true in order to run the validator even if the prerequisites output warning issues. (Error issues from prerequisites will still skip the validation.). Note that NOT writing the forgive_warnings field and writing forgive_warnings: false means the same.
    • The user can write any other field (like version) besides requirements.
    "},{"location":"map/autoware_lanelet2_map_validator/#output-file","title":"Output file","text":"

    When the input_requirements is thrown to autoware_lanelet2_map_validator, it will output a lanelet2_validation_results.json file which looks like the following example.

    {\n\"requirements\": [\n{\n\"id\": \"vm-02-02\",\n\"passed\": true,\n\"validators\": [\n{\n\"name\": \"mapping.stop_line.missing_regulatory_elements\",\n\"passed\": true\n}\n]\n},\n{\n\"id\": \"vm-04-01\",\n\"passed\": false,\n\"validators\": [\n{\n\"issues\": [\n{\n\"id\": 163,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 164,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 165,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 166,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\",\n\"passed\": false\n},\n{\n\"issues\": [\n{\n\"id\": 0,\n\"message\": \"Prerequisites didn't pass\",\n\"primitive\": \"primitive\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.crosswalk.regulatory_element_details\",\n\"passed\": false,\n\"prerequisites\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n}\n]\n}\n]\n},\n{\n\"id\": \"vm-05-01\",\n\"passed\": false,\n\"validators\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\",\n\"passed\": true\n},\n{\n\"issues\": [\n{\n\"id\": 9896,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9918,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9838,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9874,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.traffic_light.regulatory_element_details\",\n\"passed\": false,\n\"prerequisites\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n}\n]\n}\n]\n}\n]\n}\n
    • lanelet2_validation_results.json inherits the JSON file of input_requirements and add results to it.
      • So additional input information not related to this validator also remains in the output.
    • autoware_lanelet2_map_validator adds a boolean passed field to each requirement. If all validators of the requirement have been passed, the passed field of the requirement will be true (false if not).
    • The passed field is also given to each validator. If the validator found any issues the passed field will turn to be false (true if not), and adds an issues field which is a list of issues found. Each issue contains information of severity, primitive, id, and message.
    "},{"location":"map/autoware_lanelet2_map_validator/#available-command-options","title":"Available command options","text":"option description -h, --help Explains about this tool and show a list of options --print Print all available checker without running them -m, --map_file Path to the map to be validated -i, --input_requirements Path to the JSON file where the list of requirements and validations is written -o, --output_directory Directory to save the list of validation results in a JSON format -v, --validator Comma separated list of regexes to filter the applicable validators. Will run all validators by default. Example: mapping.* to run all checks for the mapping -p, --projector Projector used for loading lanelet map. Available projectors are: mgrs, utm, and transverse_mercator. -l, --location Location of the map (for instantiating the traffic rules), e.g. de for Germany --participants Participants for which the routing graph will be instantiated (default: vehicle) --lat latitude coordinate of map origin. This is required for the transverse mercator and utm projector. --lon longitude coordinate of map origin. This is required for the transverse mercator and utm projector."},{"location":"map/autoware_lanelet2_map_validator/#available-validators","title":"Available validators","text":"

    Since there will be hundreds of validators in the future, the documents for each validator should categorized in the docs file. The directory structure should be the same to that of the src/validators directory.

    "},{"location":"map/autoware_lanelet2_map_validator/#stop-line","title":"Stop Line","text":"
    • mapping.stop_line.missing_regulatory_elements
    "},{"location":"map/autoware_lanelet2_map_validator/#traffic-light","title":"Traffic Light","text":"
    • mapping.traffic_light.missing_regulatory_elements
    • mapping.traffic_light.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/#crosswalk","title":"Crosswalk","text":"
    • mapping.crosswalk.missing_regulatory_elements
    • mapping.crosswalk.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/#how-to-add-a-new-validator","title":"How to add a new validator","text":"

    If you want to contribute to autoware_lanelet2_map_validator, please check out the how_to_contribute first.

    "},{"location":"map/autoware_lanelet2_map_validator/#relationship-between-requirements-and-validators","title":"Relationship between requirements and validators","text":"

    This is a table describing the correspondence between the validators that each requirement consists of. The \"Validators\" column will be blank if it hasn't be implemented.

    ID Requirements Validators vm-01-01 Lanelet basics vm-01-02 Allowance for lane changes vm-01-03 Linestring sharing vm-01-04 Sharing of the centerline of lanes for opposing traffic vm-01-05 Lane geometry vm-01-06 Line position (1) vm-01-07 Line position (2) vm-01-08 Line position (3) vm-01-09 Speed limits vm-01-10 Centerline vm-01-11 Centerline connection (1) vm-01-12 Centerline connection (2) vm-01-13 Roads with no centerline (1) vm-01-14 Roads with no centerline (2) vm-01-15 Road shoulder vm-01-16 Road shoulder Linestring sharing vm-01-17 Side strip vm-01-18 Side strip Linestring sharing vm-01-19 Walkway vm-02-01 Stop line alignment (Not detectable) vm-02-02 Stop sign mapping.stop_line.missing_regulatory_elements vm-03-01 Intersection criteria vm-03-02 Lanelet's turn direction and virtual vm-03-03 Lanelet width in the intersection vm-03-04 Lanelet creation in the intersection vm-03-05 Lanelet division in the intersection vm-03-06 Guide lines in the intersection vm-03-07 Multiple lanelets in the intersection vm-03-08 Intersection Area range mapping.intersection.intersection_area_validity, mapping.intersection.intersection_area_segment_type vm-03-09 Range of Lanelet in the intersection vm-03-10 Right of way (with signal) vm-03-11 Right of way (without signal) vm-03-12 Right of way supplements vm-03-13 Merging from private area, sidewalk vm-03-14 Road marking vm-03-15 Exclusive bicycle lane vm-04-01 Traffic light basics mapping.traffic_light.missing_regulatory_elements, mapping.traffic_light.regulatory_element_details, mapping.traffic_light.missing_referrers vm-04-02 Traffic light position and size mapping.traffic_light.correct_facing (Undone) vm-04-03 Traffic light lamps vm-05-01 Crosswalks across the road mapping.crosswalk.missing_regulatory_elements, mapping.crosswalk.regulatory_element_details vm-05-02 Crosswalks with pedestrian signals vm-05-03 Deceleration for safety at crosswalks vm-05-04 Fences vm-06-01 Buffer Zone vm-06-02 No parking signs vm-06-03 No stopping signs vm-06-04 No stopping sections vm-06-05 Detection area vm-07-01 Vector Map creation range vm-07-02 Range of detecting pedestrians who enter the road vm-07-03 Guardrails, guard pipes, fences vm-07-04 Ellipsoidal height"},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/","title":"How to contribute to `autoware_lanelet2_map_validator`","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#how-to-contribute-to-autoware_lanelet2_map_validator","title":"How to contribute to autoware_lanelet2_map_validator","text":"

    Your contribution is welcome to achieve a broad view of validation for lanelet2 maps. This document gives you the instructions on how to add a validator to autoware_lanelet2_map_validator. Please take a look at the Design Concept and follow the Contribution Guide.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#design-concept","title":"Design Concept","text":"

    The main goal of autoware_lanelet2_map_validator is to validate whether the lanelet2 map matches the vector map requirements for Autoware. autoware_lanelet2_map_validator achieves this by running a list of small validators. In other words, each vector map requirement will be validated by one or more validators. It is recommended to keep validators small and they don't have to be unique to a specific requirement so that we can broaden the expression of map requirements. (It doesn't mean that a validator should output only one kind of error!)

    The list of small validators will be defined as a JSON file (see autoware_requirement_set.json for an example), and the output will also be a JSON file that appends validation results to a copy of the input. See How to use autoware_lanelet2_map_validator for further information about how the input and output are processed.

    Please note that the validators are categorized according to the vector map requirements written in the Autoware Documentation. If there are any suggestions for new categories please let the pull request (PR) reviewers know. The available categories as of now are

    • Lane
    • Stop line
    • Intersection
    • Traffic light
    • Crosswalk
    • Area
    • Others
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#contribution-guide","title":"Contribution Guide","text":"

    This section is aimed at contributors who want to add their own validators. If you want to change the core process of autoware_lanelet2_map_validator, please open a PR and discuss it with the maintainers.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#1-implement-your-validator","title":"1. Implement your validator","text":"

    autoware_lanelet2_map_validator is based on the Lanelet2 library provided by fzi-forschungszentrum-informatik.

    Contributors are encouraged to make their validators by following the class structure shown in validator_template.cpp and validator_template.hpp. Looking at other implementations may also be helpful.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-path-structure","title":"Restrictions for path structure","text":"
    • The source file (.cpp) must belong to src/validators/\\<CATEGORY\\>/
    • Avoid source file names that are the same as those in other categories.
    • The header file (.hpp) must belong to src/include/lanelet2_map_validator/validators/\\<CATEGORY\\>/
    • Currently, there are no naming rules for source and header files, but the pair of source and header files should have the same name.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-validator-class-implementation","title":"Restrictions for validator class implementation","text":"
    • Define the name of the validator in the header file (.hpp file).
      • The name must follow the structure aaa.bbb.ccc
        • The first part (aaa) must be either mapping, routing or rule
        • The second part (bbb) should be either general, lane, stop_line, intersection, traffic_light, crosswalk, area, others.
        • The third part can be anything, as long as it is not hard to recognize the validator's feature.
      • The issue code of the validator will be generated from this name. It removes the first part of the name, converts it to upper camel case, and adds a number for classification. (e. g. Bbb.Ccc-001)
    • Write your implementation in the operator() function that outputs an Issues (a.k.a vector\\<Issue>) object. Not all of the implementation has to be written in the operator; you can privately define and use functions in your validator class.
    • Since autoware_lanelet2_map_validator outputs issue codes, please add an issue code prefix with square brackets on top of your issue message.
      • You may use the append_issue_code_prefix function to generate the issue code prefix.
      • Even if the validator only detects a single type of issue, please include the number 001 to your issue code.
      • The issue code must correspond to the issue message one-to-one.
    • Currently, there are no rules to decide the severity of the issue. If you're not confident about your severity decisions please discuss them with your PR reviewers.
    • Other coding rules are mentioned in the Autoware Documentation. However, this coding rule doesn't hold if it conflicts with the Lanelet2 library.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#2-write-a-test-code","title":"2. Write a test code","text":"

    Contributors must also provide test codes to ensure your validator is working properly and be able to be tested again when changes occur to the validator in the future.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-path-structure_1","title":"Restrictions for path structure","text":"
    • The source code (.cpp) must belong to test/src/.
      • The test codes are not categorized because there are few codes, but they might be categorized in the future.
    • The source code name should be test_<ORIGINAL_SOURCE_NAME>.cpp
    • The maps (.osm) for testing must belong to test/data/map/\\<CATEGORY\\>/
    • The JSON files (.json) for testing must belong to test/data/json/
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-test-code-implementation","title":"Restrictions for test code implementation","text":"
    • Tests should be executable by colcon test. It is strongly recommended to use the gtest (googletest) format.
    • If possible, the MapValidationTester class may be useful to inherit common map loading process.
    • The test code must contain the following.
      • A test function that checks whether the validator is available.
      • A test function for each unique issue the validator can detect. It is recommended to create a small lanelet2 map for each unique issue.
        • In this test, please also check that the issue code is emitted as expected.
      • A test function ensuring that no issues occur when validating test/data/map/sample_map.osm. If sample_map.osm violates the validation or doesn't contain the primitive to validate, please fix or add the primitives to it.
    • Add the test code to CMakeLists.txt using the add_validation_test function.
      • Currently, this part must be added to CMakeLists.txt manually. Automation is expected in the future.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#3-test-the-entire-validator","title":"3. Test the entire validator","text":"

    Please check that the autoware_lanelet2_map_validator works perfectly.

    1. Execute colcon test --packages-select autoware_lanelet2_map_validator --event-handlers console_cohesion+ and confirm that all tests pass.
    2. Execute the following command and confirm that no issues appear.
    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator -p mgrs -m <PATH_TO_sample_map.osm> -i <PATH_TO_autoware_requirement_set.json> -o ./\n
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#4-write-a-document","title":"4. Write a document","text":"

    Contributors must provide documentation to explain what the validator can do. The document must explain the following.

    • The validator's name
    • Feature of the validator
    • The source code where the validator is implemented
    • A table of issues that the validator can detect. The following details are required.
      • Issue Code
      • Message
      • Severity
      • Primitive
      • Description of the issue
      • Approach to fix the issue

    In addition, add a link of the document to the table Relationship between requirements and validators in the main README.md to let the users know which map requirement your validator relates with.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#5-submit-a-pull-request","title":"5. Submit a pull request","text":"

    Submit a pull request to the autowarefoundation/autoware_tools repository.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/","title":"missing_regulator_elements_for_crosswalk","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#missing_regulator_elements_for_crosswalk","title":"missing_regulator_elements_for_crosswalk","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#validator-name","title":"Validator name","text":"

    mapping.crosswalk.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#feature","title":"Feature","text":"

    This validator checks whether each crosswalk subtype lanelet has a relevant regulatory element. Required information for a crosswalk is written in the Autoware documentation.

    The output issue marks \"lanelet\" as the primitive, and the lanelet ID is written together as ID.

    Issue Code Message Severity Description Approach Crosswalk.MissingRegulatoryElements-001 \"No regulatory element refers to this crosswalk.\" Error There is a crosswalk subtype lanelet that hasn't been referred to any regulatory element. Create a crosswalk subtype regulatory element and refer to the crosswalk lanelet."},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_crosswalk.hpp
    • missing_regulatory_elements_for_crosswalk.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/","title":"regulatory_element_details_for_crosswalks","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#regulatory_element_details_for_crosswalks","title":"regulatory_element_details_for_crosswalks","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#validator-name","title":"Validator name","text":"

    mapping.crosswalk.regulatory_element_details

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#feature","title":"Feature","text":"

    This validator checks whether the details in the crosswalk subtype regulatory elements are valid. Required information for a crosswalk is written in the Autoware documentation. This validator checks eight types of issues.

    The output issue marks \"lanelet\", \"linestring\" or \"regulatory_element\" as the primitive, and the regulatory element ID is written together as ID.

    Issue Code Message Severity Primitive Description Approach Crosswalk.RegulatoryElementDetails-001 \"Regulatory element of crosswalk must have lanelet of crosswalk(refers).\" Error regulatory element There is a crosswalk subtype regulatory element that has no referses. Write refers referring to a crosswalk subtype lanelet in the regulatory element Crosswalk.RegulatoryElementDetails-002 \"Regulatory element of crosswalk must have only one lanelet of crosswalk(refers).\" Error regulatory element There is a crosswalk subtype regulatory element that has multiple referses. A crosswalk subtype regulatory element can have only one refers. Remove the refers that is not a crosswalk lanelet. Crosswalk.RegulatoryElementDetails-003 \"Regulatory element of crosswalk does not have stop line(ref_line).\" Info regulatory element There is a crosswalk subtype regulatory element that has no ref_lines Generally, there should be a stop line for the crosswalk. Be sure that the stop line exists or doesn't. Crosswalk.RegulatoryElementDetails-004 \"Regulatory element of crosswalk is nice to have crosswalk_polygon.\" Warning regulatory element There is a crosswalk subtype regulatory element that has no crosswalk_polygons. It is recommended to surround a crosswalk with a crosswalk_polygon. Create one and add a crosswalk_polygon role member to the regulatory element with the polygon ID. Crosswalk.RegulatoryElementDetails-005 \"Regulatory element of crosswalk must have only one crosswalk_polygon.\" Error regulatory element There is a crosswalk subtype regulatory element that has multiple crosswalk_polygons. Only one crosswalk_polygon is allowed per crosswalk. Remove the unnecessary ones. Crosswalk.RegulatoryElementDetails-006 \"Refers of crosswalk regulatory element must have type of crosswalk.\" Error lanelet There is a crosswalk subtype regulatory element whose refers is not a crosswalk subtype lanelet. Check that the refers is a crosswalk subtype lanelet Crosswalk.RegulatoryElementDetails-007 \"ref_line of crosswalk regulatory element must have type of stopline.\" Error linestring There is a crosswalk subtype regulatory element whose ref_line is not a stop_line type linestring. Check that the ref_line is a stop_line type linestring Crosswalk.RegulatoryElementDetails-008 \"Crosswalk polygon of crosswalk regulatory element must have type of crosswalk_polygon.\" Error polygon There is a crosswalk subtype regulatory element whose crosswalk_polygon is not a crosswalk_polygon type polygon. Check that the crosswalk_polygon mentioned in the regulatory element refers to a crosswalk_polygon type area."},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#related-source-codes","title":"Related source codes","text":"
    • regulatory_element_details_for_crosswalks.hpp
    • regulatory_element_details_for_crosswalks.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/","title":"intersection_area_segment_type","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#intersection_area_segment_type","title":"intersection_area_segment_type","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#validator-name","title":"Validator name","text":"

    mapping.intersection.intersection_area_segment_type

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#feature","title":"Feature","text":"

    This validator check whether each intersection_area type polygon is made from points that belong to road_border type linestrings or the starting/ending edge of a lanelet.

    This is achieved by the following procedure.

    1. Create a 2D bounding box that circumscribes the polygon.
    2. Collect road_border type linestrings within or intersecting the 2D bounding box.
    3. Collect starting/ending edges of lanelets within or intersecting the 2D bounding box.
    4. Examine each point that constitutes the polygon whether it belongs to the collection above.

    The validator outputs the following issue with the corresponding ID of the primitive.

    Issue Code Message Severity Primitive Description Approach Intersection.IntersectionAreaSegmentType-001 \"This intersection area is not made by points from road_border linestrings or lanelet edges. (Point ID: \\<POINT ID LIST>)\" Error Polygon The intersection_area polygon has points that doesn't belong to road_border type linestrings or lanelet edges. The violating points are listed up at \\<POINT ID LIST>. Ensure that the intersection_area is formed ONLY by road_border linestrings and lanelet edges."},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#supplementary-information","title":"Supplementary information","text":"

    Note that this validator only examines what type of linestring the points constituting the polygon belongs to, and doesn't examine they have a valid connection. Use the mapping.intersection.intersection_area_validity to check whether the polygon is boost::geometry::is_valid().

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#related-source-codes","title":"Related source codes","text":"
    • intersection_area_segment_type.hpp
    • intersection_area_segment_type.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/","title":"intersection_area_validity","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#intersection_area_validity","title":"intersection_area_validity","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#validator-name","title":"Validator name","text":"

    mapping.intersection.intersection_area_validity

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#feature","title":"Feature","text":"

    This validator check whether each intersection_area type polygon satisfies boost::geometry::is_valid.

    The validator outputs the following issue with the corresponding ID of the primitive.

    Issue Code Message Severity Primitive Description Approach Intersection.IntersectionAreaValidity-001 \"This intersection_area doesn't satisfy boost::geometry::is_valid (reason: \\<MESSAGE>) Error Polygon The intersection_area polygon didn't satisfy boost::geometry::is_valid. There are several reasons expected and it is written in \"(reason: \\<MESSAGE>)\". The \\<MESSAGE> is a copy of the output message defined in the boost::geometry library."},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#related-source-codes","title":"Related source codes","text":"
    • intersection_area_validity.hpp
    • intersection_area_validity.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/","title":"missing_regulator_elements_for_stop_lines","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#missing_regulator_elements_for_stop_lines","title":"missing_regulator_elements_for_stop_lines","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#validator-name","title":"Validator name","text":"

    mapping.stop_line.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#feature","title":"Feature","text":"

    This validator checks whether each stop_line type linestring has a relevant regulatory element. Required information for a stop line is written in the Autoware documentation.

    The output issue marks \"linestring\" as the primitive, and the linestring ID is written together as ID.

    Issue Code Message Severity Description Approach StopLine.MissingRegulatoryElements-001 \"No regulatory element refers to this stop line.\" Error There is a stop_line type linestring that hasn't been referred to any regulatory element. Create a regulatory element that refers to this stop line."},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_stop_line.cpp
    • missing_regulatory_elements_for_stop_line.hpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/","title":"missing_referrers_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#missing_referrers_for_traffic_lights","title":"missing_referrers_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.missing_referrers

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light type regulatory element has been referred by at least one lanelet.

    Issue Code Message Severity Primitive Description Approach TrafficLight.MissingReferrers-001 Regulatory element of traffic light must be referred by at least one lanelet. Error Regulatory Element There is a traffic_light type regulatory element that hasn't been referred by any lanelet. The lanelet that might be controlled by the traffic light must refer this regulatory element."},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • missing_referrers_for_traffic_lights.cpp
    • missing_referrers_for_traffic_lights.hpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/","title":"missing_regulator_elements_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#missing_regulator_elements_for_traffic_lights","title":"missing_regulator_elements_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light type linestring has a relevant regulatory element. Required information for traffic lights is written in the Autoware documentation.

    The output issue marks \"linestring\" as the primitive, and the linestring ID is written together as ID.

    Issue Code Message Severity Description Approach TrafficLight.MissingRegulatoryElements-001 \"No regulatory element refers to this traffic light.\" Error There is a traffic_light type linestring that hasn't been referred to any regulatory element. Create a traffic_light subtype regulatory element that refers to this linestring"},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_traffic_light.hpp
    • missing_regulatory_elements_for_traffic_light.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/","title":"regulatory_element_details_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#regulatory_element_details_for_traffic_lights","title":"regulatory_element_details_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.regulatory_element_details

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether the details in the traffic_light subtype regulatory elements are valid. Required information for traffic lights is written in the Autoware documentation. This validator checks four types of issues.

    The output issue marks \"linestring\" or \"regulatory element\" as the primitive, and the lanelet ID is written together as ID.

    Issue Code Message Severity Primitive Description Approach TrafficLight.RegulatoryElementDetails-001 \"Regulatory element of traffic light must have a stop line(ref_line).\" Error regulatory element There is a traffic_light subtype regulatory element that has no ref_lines Add ref_line to the regulatory element that refers to the id of the stop line linestring. TrafficLight.RegulatoryElementDetails-002 \"Refers of traffic light regulatory element must have type of traffic_light.\" Error linestring There is a traffic_light subtype regulatory element whose refers is not a traffic_light type linestring. Check that the refers in the regulatory element is a traffic_light type linestring. TrafficLight.RegulatoryElementDetails-003 \"ref_line of traffic light regulatory element must have type of stop_line.\" Error linestring There is a traffic_light subtype regulatory element whose ref_line is not a stop_line type linestring. Check that the ref_line in the regulatory element is a stop_line type linestring"},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • regulatory_element_details_for_traffic_lights.hpp
    • regulatory_element_details_for_traffic_lights.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/","title":"traffic_light_facing","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#traffic_light_facing","title":"traffic_light_facing","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.correct_facing

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#recommended-prerequisite-validators","title":"Recommended prerequisite validators","text":"
    • mapping.traffic_light.missing_referrers
    • mapping.traffic_light.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light linestring is drawn with the correct direction, because the linestring direction describes the facing of the traffic_light. If the traffic light is facing to the viewer, the traffic light linestring must be drawn from the left point to the right point seen from the viewer. Note that this validator only check traffic lights whose subtype are red_yellow_green. This validator checks five types of issues. The former three issues are related to prerequisites to perform correct validation rather than direct validation results of the traffic light facing. The latter two issues mention to the traffic light facing.

    All output issues specify the traffic_light \"linestring\" or the traffic_light \"regulatory_element\" as the primitive, and the primitive ID will be specified as the ID.

    Issue Code Message Severity Primitive Description Approach TrafficLight.CorrectFacing-001 \"Lanelets referring this traffic_light have several divergent starting lines\" Info Linestring A traffic_light subtype regulatory element may be referred by multiple lanelets. This warning appears when the starting line of those lanelets (which tends to be the same or similar) diverge too much. This hardly happens, but maybe the referring lanelet is completely wrong or the traffic light cannot be seen from the starting edge of the referring lanelet. TrafficLight.CorrectFacing-002 \"The linestring direction seems to be wrong.\" Error Linestring This traffic_light type linestring is drawn with the wrong direction. Fix the traffic light linestring so that it is drawn from the left to the right seen from the stop line. TrafficLight.CorrectFacing-003 \"The linestring direction has been judged as both correct and wrong.\" Warning Linestring The validator cannot judge whether the direction of this traffic_light type linestring is correct. (Mostly they are correct.) This occurs from special regulatory element definitions and technical issues written below. This occurs in the Difficult Case written below. This validator currently cannot determine that the traffic light facing is correct in this case, so please recheck it by yourself and please ignore it if it is correct."},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#procedure","title":"Procedure","text":"

    This flow chart shows the simplified procedure how the validation is done.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#difficult-cases","title":"Difficult cases","text":"

    Currently, this validator assumes that all traffic lights in the same regulatory element has the same facing. However, there might be cases that this assumption doesn't hold, and this is only when traffic lights on the other side of the road is in the same regulatory element. It is hard to tell that this traffic light is for this road or the opposite road since the facing of the traffic light is unknown yet, so this validator keeps its ambiguity for now. This kind of traffic light will be judged as correct from the this side but not from the other side, and it will be misjudged oppositely if the traffic light linestring id drawn wrong. This validator will throws a warning for this case and tells the user to check it by their own.

    We assume that this kind of traffic light could be found only a few, but if you feel this concerning you can remove the traffic light on the other road from the regulatory element. This workaround affects nothing if your planning module doesn't utilize the information that the traffic light on the other road has the same timing of lighting.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#related-source-codes","title":"Related source codes","text":"
    • traffic_light_facing.hpp
    • traffic_light_facing.cpp
    "},{"location":"map/autoware_pointcloud_divider/","title":"autoware_pointcloud_divider","text":""},{"location":"map/autoware_pointcloud_divider/#autoware_pointcloud_divider","title":"autoware_pointcloud_divider","text":"

    This is a tool for processing pcd files, and it can perform the following functions:

    • Dividing point clouds
    • Downsampling point clouds
    • Generating metadata to efficiently handle the divided point clouds
    "},{"location":"map/autoware_pointcloud_divider/#supported-data-format","title":"Supported Data Format","text":"

    Currently, only pcl::PointXYZ and pcl::PointXYZI are supported. Any PCD will be loaded as those two types.

    This tool can be used with files that have data fields other than XYZI (e.g., XYZRGB) and files that only contain XYZ.

    • Data fields other than XYZI are ignored during loading.
    • When loading XYZ-only data, the intensity field is assigned 0.
    "},{"location":"map/autoware_pointcloud_divider/#installation","title":"Installation","text":"
    cd <PATH_TO_pilot-auto.*> # OR <PATH_TO_autoware>\ncd src/\ngit clone git@github.com:autowarefoundation/autoware_tools.git\ncd ..\ncolcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --catkin-skip-building-tests --symlink-install --packages-up-to autoware_pointcloud_divider\n
    "},{"location":"map/autoware_pointcloud_divider/#usage","title":"Usage","text":"
    • Select directory, process all files found with find $INPUT_DIR -name \"*.pcd\".

      ros2 launch autoware_pointcloud_divider pointcloud_divider.launch.xml input_pcd_or_dir:=<INPUT_DIR> output_pcd_dir:=<OUTPUT_DIR> prefix:=<PREFIX>\n
      Name Description INPUT_DIR Directory that contains all PCD files OUTPUT_DIR Output directory name PREFIX Prefix of output PCD file name

    INPUT_DIR and OUTPUT_DIR should be specified as absolute paths.

    NOTE: The folder OUTPUT_DIR is auto generated. If it already exists, all files within that folder will be deleted before the tool runs. Hence, users should backup the important files in that folder if necessary.

    "},{"location":"map/autoware_pointcloud_divider/#parameters","title":"Parameters","text":"Name Type Description Default Range use_large_grid boolean Pack small segments to larger folders false N/A leaf_size float Resolution in meter for downsampling the output segments. Setting to negative to get the raw output PCDs. 0.2 N/A grid_size_x float The x size in meter of the output segments 20 N/A grid_size_y float The y size in meter of the output segments 20 N/A input_pcd_or_dir string The path to the folder containing the input PCD files N/A output_pcd_dir string The path to the folder containing the output PCD files N/A prefix string The prefix for the name of the output PCD files N/A point_type string Type of the point when processing PCD files. Could be point_xyz or point_xyzi point_xyzi N/A

    How the point cloud is processed.

    How the PCD file is named

    "},{"location":"map/autoware_pointcloud_divider/#parameter-example","title":"Parameter example","text":"
    1. Dividing point clouds without downsampling

      use_large_grid: false\nleaf_size: -1.0 # any negative number\ngrid_size_x: 20\ngrid_size_y: 20\n
    2. Dividing and downsampling point clouds

      use_large_grid: false\nleaf_size: 0.2\ngrid_size_x: 20\ngrid_size_y: 20\n
    "},{"location":"map/autoware_pointcloud_divider/#metadata-yaml-format","title":"Metadata YAML Format","text":"

    The metadata file should be named metadata.yaml. It contains the following fields:

    • x_resolution: The resolution along the X-axis.
    • y_resolution: The resolution along the Y-axis.

    Additionally, the file contains entries for individual point cloud files (.pcd files) and their corresponding grid coordinates. The key is the file name, and the value is a list containing the X and Y coordinates of the lower-left corner of the grid cell associated with that file. The grid cell's boundaries can be calculated using the x_resolution and y_resolution values.

    For example:

    x_resolution: 100.0\ny_resolution: 150.0\nA.pcd: [1200, 2500] # -> 1200 <= x <= 1300, 2500 <= y <= 2650\nB.pcd: [1300, 2500] # -> 1300 <= x <= 1400, 2500 <= y <= 2650\nC.pcd: [1200, 2650] # -> 1200 <= x <= 1300, 2650 <= y <= 2800\nD.pcd: [1400, 2650] # -> 1400 <= x <= 1500, 2650 <= y <= 2800\n
    "},{"location":"map/autoware_pointcloud_divider/#license","title":"LICENSE","text":"

    Parts of files grid_info.hpp, pcd_divider.hpp, and pcd_divider.cpp are copied from MapIV's pointcloud_divider and are under BSD-3-Clauses license. The remaining code are under Apache License 2.0

    "},{"location":"map/autoware_pointcloud_merger/","title":"autoware_pointcloud_merger","text":""},{"location":"map/autoware_pointcloud_merger/#autoware_pointcloud_merger","title":"autoware_pointcloud_merger","text":"

    This is a tool for processing pcd files, and it can perform the following functions:

    • Merging multiple PCD files to a single PCD file
    • Downsampling point clouds
    "},{"location":"map/autoware_pointcloud_merger/#supported-data-format","title":"Supported Data Format","text":"

    Currently, only pcl::PointXYZ and pcl::PointXYZI are supported. Any PCD will be loaded as those two types .

    This tool can be used with files that have data fields other than XYZI (e.g., XYZRGB) and files that only contain XYZ.

    • Data fields other than XYZI are ignored during loading.
    • When loading XYZ-only data, the intensity field is assigned 0.
    "},{"location":"map/autoware_pointcloud_merger/#installation","title":"Installation","text":"
    cd <PATH_TO_pilot-auto.*> # OR <PATH_TO_autoware>\ncd src/\ngit clone git@github.com:autowarefoundation/autoware_tools.git\ncd ..\ncolcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --catkin-skip-building-tests --symlink-install --packages-up-to autoware_pointcloud_merger\n
    "},{"location":"map/autoware_pointcloud_merger/#usage","title":"Usage","text":"
    • Merger all PCD files from the input directory into a single output PCD

      ros2 launch autoware_pointcloud_merger pointcloud_merger.launch.xml input_pcd_dir:=<INPUT_DIR> output_pcd:=<OUTPUT_PCD>\n
      Name Description INPUT_DIR Directory that contains all input PCD files OUTPUT_PCD Name of the output PCD file

    INPUT_DIR and OUTPUT_PCD should be specified as absolute paths.

    "},{"location":"map/autoware_pointcloud_merger/#parameter","title":"Parameter","text":"Name Type Description Default Range leaf_size float Resolution in meter for downsampling the output PCD. Setting to negative to get the raw output PCD. -0.1 N/A input_pcd_dir string The path to the folder containing the input PCD files N/A output_pcd string The path to the merged PCD file N/A point_type string Type of the point when processing PCD files. Could be point_xyz or point_xyzi point_xyzi N/A"},{"location":"map/autoware_pointcloud_merger/#license","title":"LICENSE","text":"

    Parts of files pcd_merger.hpp, and pcd_merger.cpp are copied from MapIV's pointcloud_divider and are under BSD-3-Clauses license. The remaining code are under Apache License 2.0

    "},{"location":"planning/autoware_planning_data_analyzer/","title":"Planning Data Analyzer","text":""},{"location":"planning/autoware_planning_data_analyzer/#planning-data-analyzer","title":"Planning Data Analyzer","text":""},{"location":"planning/autoware_planning_data_analyzer/#usage","title":"Usage","text":"
    ros2 launch autoware_planning_data_analyzer behavior_analyzer.launch.xml bag_path:=<ROSBAG>\n
    "},{"location":"planning/autoware_planning_data_analyzer/#output","title":"Output","text":"Name Type Description ~/output/manual_metrics tier4_debug_msgs::msg::Float32MultiArrayStamped Metrics calculated from the driver's driving trajectory. ~/output/system_metrics tier4_debug_msgs::msg::Float32MultiArrayStamped Metrics calculated from the autoware output. ~/output/manual_score tier4_debug_msgs::msg::Float32MultiArrayStamped Driving scores calculated from the driver's driving trajectory. ~/output/system_score tier4_debug_msgs::msg::Float32MultiArrayStamped Driving scores calculated from the autoware output."},{"location":"planning/autoware_route_client/","title":"Route Client","text":""},{"location":"planning/autoware_route_client/#route-client","title":"Route Client","text":"

    This package contains a tool to send request to set route.

    "},{"location":"planning/autoware_route_client/#usage","title":"Usage","text":""},{"location":"planning/autoware_route_client/#prepare-a-route-file","title":"Prepare a route file","text":"

    Prepare a YAML file containing route information. The file format is like following:

    goal:\nposition:\nx: 0.0\ny: 0.0\nz: 0.0\norientation:\nx: 0.0\ny: 0.0\nz: 0.0\nw: 0.0\nsegments:\n- preferred:\nid: 0\ntype: lane\nalternatives:\n- id: 1\ntype: lane\n- preferred:\nid: 2\ntype: lane\nalternatives: []\n- preferred:\nid: 3\ntype: lane\nalternatives:\n- id: 4\ntype: lane\n
    "},{"location":"planning/autoware_route_client/#send-request-to-set-route","title":"Send request to set route","text":"

    Execute following command.

    ros2 run autoware_route_client route_client.py <path_to_yaml_file>\n
    "},{"location":"planning/autoware_rtc_replayer/","title":"rtc_replayer","text":""},{"location":"planning/autoware_rtc_replayer/#rtc_replayer","title":"rtc_replayer","text":""},{"location":"planning/autoware_rtc_replayer/#purpose","title":"Purpose","text":"

    The current issue for RTC commands is that service is not recorded to rosbag, so it's very hard to analyze what was happened exactly. So this package makes it possible to replay rtc commands service from rosbag rtc status topic to resolve that issue.

    "},{"location":"planning/autoware_rtc_replayer/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"planning/autoware_rtc_replayer/#input","title":"Input","text":"Name Type Description /debug/rtc_status tier4_rtc_msgs::msg::CooperateStatusArray CooperateStatusArray that is recorded in rosbag"},{"location":"planning/autoware_rtc_replayer/#output","title":"Output","text":"Name Type Description /api/external/set/rtc_commands tier4_rtc_msgs::msg::CooperateCommands CooperateCommands that is replayed by this package"},{"location":"planning/autoware_rtc_replayer/#inner-workings-algorithms","title":"Inner-workings / Algorithms","text":""},{"location":"planning/autoware_rtc_replayer/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    This package can't replay CooperateCommands correctly if CooperateStatusArray is not stable. And this replay is always later one step than actual however it will not affect much for behavior.

    "},{"location":"planning/autoware_rtc_replayer/#future-extensions-unimplemented-parts","title":"Future extensions / Unimplemented parts","text":"

    tbd.

    "},{"location":"planning/planning_debug_tools/","title":"Planning Debug Tools","text":""},{"location":"planning/planning_debug_tools/#planning-debug-tools","title":"Planning Debug Tools","text":"

    This package contains several planning-related debug tools.

    • Trajectory analyzer: visualizes the information (speed, curvature, yaw, etc) along the trajectory
    • Closest velocity checker: prints the velocity information indicated by each modules
    • Perception reproducer: generates detected objects from rosbag data in planning simulator environment
    • processing time checker: displays processing_time of modules on the terminal
    • logging level updater: updates the logging level of the planning modules.
    "},{"location":"planning/planning_debug_tools/#trajectory-analyzer","title":"Trajectory analyzer","text":"

    The trajectory_analyzer visualizes the information (speed, curvature, yaw, etc) along the trajectory. This feature would be helpful for purposes such as \"investigating the reason why the vehicle decelerates here\". This feature employs the OSS PlotJuggler.

    "},{"location":"planning/planning_debug_tools/#stop-reason-visualizer","title":"Stop reason visualizer","text":"

    This is to visualize stop factor and reason. see the details

    "},{"location":"planning/planning_debug_tools/#how-to-use","title":"How to use","text":"

    please launch the analyzer node

    ros2 launch planning_debug_tools trajectory_analyzer.launch.xml\n

    and visualize the analyzed data on the plot juggler following below.

    "},{"location":"planning/planning_debug_tools/#setup-plotjuggler","title":"setup PlotJuggler","text":"

    For the first time, please add the following code to reactive script and save it as the picture below! (Looking for the way to automatically load the configuration file...)

    You can customize what you plot by editing this code.

    in Global code

    behavior_path = '/planning/scenario_planning/lane_driving/behavior_planning/path_with_lane_id/debug_info'\nbehavior_velocity = '/planning/scenario_planning/lane_driving/behavior_planning/path/debug_info'\nmotion_avoid = '/planning/scenario_planning/lane_driving/motion_planning/path_optimizer/trajectory/debug_info'\nmotion_smoother_latacc = '/planning/scenario_planning/motion_velocity_smoother/debug/trajectory_lateral_acc_filtered/debug_info'\nmotion_smoother = '/planning/scenario_planning/trajectory/debug_info'\n

    in function(tracker_time)

    PlotCurvatureOverArclength('k_behavior_path', behavior_path, tracker_time)\nPlotCurvatureOverArclength('k_behavior_velocity', behavior_velocity, tracker_time)\nPlotCurvatureOverArclength('k_motion_avoid', motion_avoid, tracker_time)\nPlotCurvatureOverArclength('k_motion_smoother', motion_smoother, tracker_time)\n\nPlotVelocityOverArclength('v_behavior_path', behavior_path, tracker_time)\nPlotVelocityOverArclength('v_behavior_velocity', behavior_velocity, tracker_time)\nPlotVelocityOverArclength('v_motion_avoid', motion_avoid, tracker_time)\nPlotVelocityOverArclength('v_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotVelocityOverArclength('v_motion_smoother', motion_smoother, tracker_time)\n\nPlotAccelerationOverArclength('a_behavior_path', behavior_path, tracker_time)\nPlotAccelerationOverArclength('a_behavior_velocity', behavior_velocity, tracker_time)\nPlotAccelerationOverArclength('a_motion_avoid', motion_avoid, tracker_time)\nPlotAccelerationOverArclength('a_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotAccelerationOverArclength('a_motion_smoother', motion_smoother, tracker_time)\n\nPlotYawOverArclength('yaw_behavior_path', behavior_path, tracker_time)\nPlotYawOverArclength('yaw_behavior_velocity', behavior_velocity, tracker_time)\nPlotYawOverArclength('yaw_motion_avoid', motion_avoid, tracker_time)\nPlotYawOverArclength('yaw_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotYawOverArclength('yaw_motion_smoother', motion_smoother, tracker_time)\n\nPlotCurrentVelocity('localization_kinematic_state', '/localization/kinematic_state', tracker_time)\n

    in Function Library

    function PlotValue(name, path, timestamp, value)\n  new_series = ScatterXY.new(name)\n  index = 0\n  while(true) do\n    series_k = TimeseriesView.find( string.format( \"%s/\"..value..\"[%d]\", path, index) )\n    series_s = TimeseriesView.find( string.format( \"%s/arclength[%d]\", path, index) )\n    series_size = TimeseriesView.find( string.format( \"%s/size\", path) )\n\n    if series_k == nil or series_s == nil then break end\n\n    k = series_k:atTime(timestamp)\n    s = series_s:atTime(timestamp)\n    size = series_size:atTime(timestamp)\n\n    if index >= size then break end\n\n    new_series:push_back(s,k)\n    index = index+1\n  end\nend\n\nfunction PlotCurvatureOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"curvature\")\nend\n\nfunction PlotVelocityOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"velocity\")\nend\n\nfunction PlotAccelerationOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"acceleration\")\nend\n\nfunction PlotYawOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"yaw\")\nend\n\nfunction PlotCurrentVelocity(name, kinematics_name, timestamp)\n  new_series = ScatterXY.new(name)\n  series_v = TimeseriesView.find( string.format( \"%s/twist/twist/linear/x\", kinematics_name))\n  if series_v == nil then\n    print(\"error\")\n    return\n  end\n  v = series_v:atTime(timestamp)\n  new_series:push_back(0.0, v)\nend\n

    Then, run the plot juggler.

    "},{"location":"planning/planning_debug_tools/#how-to-customize-the-plot","title":"How to customize the plot","text":"

    Add Path/PathWithLaneIds/Trajectory topics you want to plot in the trajectory_analyzer.launch.xml, then the analyzed topics for these messages will be published with TrajectoryDebugINfo.msg type. You can then visualize these data by editing the reactive script on the PlotJuggler.

    "},{"location":"planning/planning_debug_tools/#requirements","title":"Requirements","text":"

    The version of the plotJuggler must be > 3.5.0

    "},{"location":"planning/planning_debug_tools/#closest-velocity-checker","title":"Closest velocity checker","text":"

    This node prints the velocity information indicated by planning/control modules on a terminal. For trajectories calculated by planning modules, the target velocity on the trajectory point which is closest to the ego vehicle is printed. For control commands calculated by control modules, the target velocity and acceleration is directly printed. This feature would be helpful for purposes such as \"investigating the reason why the vehicle does not move\".

    You can launch by

    ros2 run planning_debug_tools closest_velocity_checker.py\n

    "},{"location":"planning/planning_debug_tools/#trajectory-visualizer","title":"Trajectory visualizer","text":"

    The old version of the trajectory analyzer. It is written in Python and more flexible, but very slow.

    "},{"location":"planning/planning_debug_tools/#for-other-use-case-experimental","title":"For other use case (experimental)","text":"

    To see behavior velocity planner's internal plath with lane id add below example value to behavior velocity analyzer and set is_publish_debug_path: true

    crosswalk ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/crosswalk/debug_info'\nintersection ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/intersection/debug_info'\ntraffic_light ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/traffic_light/debug_info'\nmerge_from_private ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/merge_from_private/debug_info'\nocclusion_spot ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/occlusion_spot/debug_info'\n
    PlotVelocityOverArclength('v_crosswalk', crosswalk, tracker_time)\nPlotVelocityOverArclength('v_intersection', intersection, tracker_time)\nPlotVelocityOverArclength('v_merge_from_private', merge_from_private, tracker_time)\nPlotVelocityOverArclength('v_traffic_light', traffic_light, tracker_time)\nPlotVelocityOverArclength('v_occlusion', occlusion_spot, tracker_time)\n\nPlotYawOverArclength('yaw_crosswalk', crosswalk, tracker_time)\nPlotYawOverArclength('yaw_intersection', intersection, tracker_time)\nPlotYawOverArclength('yaw_merge_from_private', merge_from_private, tracker_time)\nPlotYawOverArclength('yaw_traffic_light', traffic_light, tracker_time)\nPlotYawOverArclength('yaw_occlusion', occlusion_spot, tracker_time)\n\nPlotCurrentVelocity('localization_kinematic_state', '/localization/kinematic_state', tracker_time)\n
    "},{"location":"planning/planning_debug_tools/#perception-reproducer","title":"Perception reproducer","text":"

    This script can overlay the perception results from the rosbag on the planning simulator synchronized with the simulator's ego pose.

    "},{"location":"planning/planning_debug_tools/#how-it-works","title":"How it works","text":"

    Whenever the ego's position changes, a chronological reproduce_sequence queue is generated based on its position with a search radius (default to 2 m). If the queue is empty, the nearest odom message in the rosbag is added to the queue. When publishing perception messages, the first element in the reproduce_sequence is popped and published.

    This design results in the following behavior:

    • When ego stops, the perception messages are published in chronological order until queue is empty.
    • When the ego moves, a perception message close to ego's position is published.
    "},{"location":"planning/planning_debug_tools/#available-options","title":"Available Options","text":"
    • -b, --bag: Rosbag file path (required)
    • -d, --detected-object: Publish detected objects
    • -t, --tracked-object: Publish tracked objects
    • -r, --search-radius: Set the search radius in meters (default: 1.5m). If set to 0, always publishes the nearest message
    • -c, --reproduce-cool-down: Set the cool down time in seconds (default: 80.0s)
    • -p, --pub-route: Initialize localization and publish a route based on poses from the rosbag
    • -n, --noise: Apply perception noise to objects when publishing repeated messages (default: True)
    • -f, --rosbag-format: Specify rosbag data format (default: \"db3\")
    • -v, --verbose: Output debug data
    "},{"location":"planning/planning_debug_tools/#how-to-use_1","title":"How to use","text":"

    First, launch the planning simulator, and put the ego pose. Then, run the script according to the following command.

    By designating a rosbag, perception reproducer can be launched.

    ros2 run planning_debug_tools perception_reproducer.py -b <bag-file>\n

    You can designate multiple rosbags in the directory.

    ros2 run planning_debug_tools perception_reproducer.py -b <dir-to-bag-files>\n

    Instead of publishing predicted objects, you can publish detected/tracked objects by designating -d or -t, respectively.

    The --pub-route option enables automatic route generation based on the rosbag data. When enabled, the script:

    1. Extracts the initial and goal poses from the beginning and end of the rosbag file
    2. Initializes the localization system with the initial pose
    3. Generates and publishes a route to the goal pose

    Example usage with route publication:

    ros2 run planning_debug_tools perception_reproducer.py -b <bag-file> -p\n
    "},{"location":"planning/planning_debug_tools/#perception-replayer","title":"Perception replayer","text":"

    A part of the feature is under development.

    This script can overlay the perception results from the rosbag on the planning simulator.

    In detail, this script publishes the data at a certain timestamp from the rosbag. The timestamp will increase according to the real time without any operation. By using the GUI, you can modify the timestamp by pausing, changing the rate or going back into the past.

    "},{"location":"planning/planning_debug_tools/#how-to-use_2","title":"How to use","text":"

    First, launch the planning simulator, and put the ego pose. Then, run the script according to the following command.

    By designating a rosbag, perception replayer can be launched. The GUI is launched as well with which a timestamp of rosbag can be managed.

    ros2 run planning_debug_tools perception_replayer.py -b <bag-file>\n

    You can designate multiple rosbags in the directory.

    ros2 run planning_debug_tools perception_replayer.py -b <dir-to-bag-files>\n

    Instead of publishing predicted objects, you can publish detected/tracked objects by designating -d or -t, respectively.

    "},{"location":"planning/planning_debug_tools/#processing-time-checker","title":"Processing time checker","text":"

    The purpose of the Processing Time Subscriber is to monitor and visualize the processing times of various ROS 2 topics in a system. By providing a real-time terminal-based visualization, users can easily confirm the processing time performance as in the picture below.

    You can run the program by the following command.

    ros2 run planning_debug_tools processing_time_checker.py -f <update-hz> -m <max-bar-time>\n

    This program subscribes to ROS 2 topics that have a suffix of processing_time_ms.

    The program allows users to customize two parameters via command-line arguments:

    • --max_display_time (or -m): This sets the maximum display time in milliseconds. The default value is 150ms.
    • --display_frequency (or -f): This sets the frequency at which the terminal UI updates. The default value is 5Hz.

    By adjusting these parameters, users can tailor the display to their specific monitoring needs.

    "},{"location":"planning/planning_debug_tools/#logging-level-updater","title":"Logging Level Updater","text":"

    The purpose of the Logging Level Updater is to update the logging level of the planning modules via ROS 2 service. Users can easily update the logging level for debugging.

    ros2 run planning_debug_tools update_logger_level.sh <module-name> <logger-level>\n

    <logger-level> will be DEBUG, INFO, WARN, or ERROR.

    When you have a typo of the planning module, the script will show the available modules.

    "},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/","title":"Doc stop reason visualizer","text":""},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/#stop_reason_visualizer","title":"stop_reason_visualizer","text":"

    This module is to visualize stop factor quickly without selecting correct debug markers. This is supposed to use with virtual wall marker like below.

    "},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/#how-to-use","title":"How to use","text":"

    Run this node.

    ros2 run planning_debug_tools stop_reason_visualizer_exe\n

    Add stop reason debug marker from rviz.

    Note: ros2 process can be sometimes deleted only from killall stop_reason_visualizer_exe

    Reference

    "},{"location":"simulator/simulator_compatibility_test/","title":"simulator_compatibility_test","text":""},{"location":"simulator/simulator_compatibility_test/#simulator_compatibility_test","title":"simulator_compatibility_test","text":""},{"location":"simulator/simulator_compatibility_test/#purpose","title":"Purpose","text":"

    Test procedures (e.g. test codes) to check whether a certain simulator is compatible with Autoware

    "},{"location":"simulator/simulator_compatibility_test/#overview-of-the-test-codes","title":"Overview of the test codes","text":"

    File structure

    • test_base
    • test_sim_common_manual_testing
    • test_morai_sim
    1. test_base provides shared methods for testing. Other test codes are created based on functions defined here.
    2. test_sim_common_manual_testing provides the most basic functions. Any simulator can be tested using codes here. However, to make these codes usable with any simulators, the codes do not include any features for test automation.
    3. test_morai_sim is an automated version of test_sim_common_manual_testing for MORAI SIM: Drive. Thus it includes 'MORAI SIM: Drive'-specific codes. Users of the other simulators may create similar version for their simulator of interest.
    "},{"location":"simulator/simulator_compatibility_test/#test-procedures-for-test_sim_common_manual_testing","title":"Test Procedures for test_sim_common_manual_testing","text":""},{"location":"simulator/simulator_compatibility_test/#build-process-before-test","title":"Build process before test","text":"
    source install/setup.bash\ncolcon build --packages-select simulator_compatibility_test\ncd src/universe/autoware.universe/tools/simulator_test/simulator_compatibility_test/test_sim_common_manual_testing\n

    To run each test case manually

    "},{"location":"simulator/simulator_compatibility_test/#test-case-1","title":"Test Case #1","text":"
    1. Run your simulator
    2. Load a map and an ego vehicle for the test
    3. Run the test using the following command

      python -m pytest test_01_control_mode_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle control mode is changed into Manual (If the simulator has a GUI for this one, it should display the ego is in Manual)
      • Ego vehicle control mode is changed into Auto (If the simulator has a GUI for this one, it should display the ego is in Auto)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-2","title":"Test Case #2","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_02_change_gear_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle gear mode is changed into \"P\" (If the simulator has a GUI for this one, it should display the gear mode is in \"P\")
      • Ego vehicle gear mode is changed into \"N\" (If the simulator has a GUI for this one, it should display the gear mode is in \"N\")
      • Ego vehicle gear mode is changed into \"R\" (If the simulator has a GUI for this one, it should display the gear mode is in \"R\")
      • Ego vehicle gear mode is changed into \"D\" (If the simulator has a GUI for this one, it should display the gear mode is in \"D\")
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-3","title":"Test Case #3","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_03_longitudinal_command_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle longitudinal velocity is greater than 10 kph (If the simulator has a GUI for this one, it should display the longitudinal velocity is greater than 10 kph)
      • Ego vehicle longitudinal velocity is going below 10 kph. This is an ego vehicle initialize process to ensure the following acceleration is made by longitudinal.acceleration value (If the simulator has a GUI for this one, it should display the longitudinal velocity is less than 10 kph)
      • Ego vehicle longitudinal velocity is greater than 10 kph (If the simulator has a GUI for this one, it should display the longitudinal velocity is greater than 10 kph)
      • Ego vehicle longitudinal velocity is going below 10 kph. This is an ego vehicle reset process to tear down this test case.
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-4","title":"Test Case #4","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_04_lateral_command_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle steering and/or tire value is greater than 0 degree (If the simulator has a GUI for this one, it should display the steering and/or tire is greater than 0 degree)
      • Ego vehicle steering and/or tire value is 0 degree. This is a reset process. (If the simulator has a GUI for this one, it should display the steering and/or tire is 0 degree)
      • Ego vehicle steering and/or tire value is less than 0 degree (If the simulator has a GUI for this one, it should display the steering and/or tire is less than 0 degree)
      • Ego vehicle steering and/or tire value is 0 degree. This is a reset process. (If the simulator has a GUI for this one, it should display the steering and/or tire is 0 degree)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-5","title":"Test Case #5","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_05_turn_indicators_cmd_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle left turn indicator is turned on (If the simulator has a GUI for this one, it should display the left turn indicator is turned on)
      • Ego vehicle right turn indicator is turned on (If the simulator has a GUI for this one, it should display the right turn indicator is turned on)
      • Ego vehicle both turn indicators are turned off. This is a reset process. (If the simulator has a GUI for this one, it should display both left and right turn indicators are turned off)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-6","title":"Test Case #6","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_06_hazard_lights_cmd_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle hazard lights are turned on (If the simulator has a GUI for this one, it should display the hazard lights are turned on or blinking)
      • Ego vehicle hazard lights are turned off. This is a reset process. (If the simulator has a GUI for this one, it should display the hazard lights are turned off)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-procedures-for-test_morai_sim","title":"Test Procedures for test_morai_sim","text":""},{"location":"simulator/simulator_compatibility_test/#build-process-before-test_1","title":"Build process before test","text":"
    source install/setup.bash\ncolcon build --packages-select simulator_compatibility_test\ncd src/universe/autoware.universe/tools/simulator_test/simulator_compatibility_test/test_morai_sim\n

    Detailed process

    (WIP)

    "},{"location":"simulator/simulator_compatibility_test/#inner-workings-algorithms","title":"Inner-workings / Algorithms","text":""},{"location":"simulator/simulator_compatibility_test/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"simulator/simulator_compatibility_test/#input","title":"Input","text":"Name Type Description /vehicle/status/control_mode autoware_vehicle_msgs::msg::ControlModeReport for [Test Case #1] /vehicle/status/gear_status autoware_vehicle_msgs::msg::GearReport for [Test Case #2] /vehicle/status/velocity_status autoware_vehicle_msgs::msg::VelocityReport for [Test Case #3] /vehicle/status/steering_status autoware_vehicle_msgs::msg::SteeringReport for [Test Case #4] /vehicle/status/turn_indicators_status autoware_vehicle_msgs::msg::TurnIndicatorsReport for [Test Case #5] /vehicle/status/hazard_lights_status autoware_vehicle_msgs::msg::HazardLightsReport for [Test Case #6]"},{"location":"simulator/simulator_compatibility_test/#output","title":"Output","text":"Name Type Description /control/command/control_cmd autoware_control_msgs/Control for [Test Case #3, #4] /control/command/control_mode_cmd autoware_vehicle_msgs/ControlModeCommand for [Test Case #1] /control/command/gear_cmd autoware_vehicle_msgs/GearCommand for [Test Case #2] /vehicle/status/steering_status autoware_vehicle_msgs/TurnIndicatorsCommand for [Test Case #5] /control/command/turn_indicators_cmd autoware_vehicle_msgs/HazardLightsCommand for [Test Case #6]"},{"location":"simulator/simulator_compatibility_test/#parameters","title":"Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#node-parameters","title":"Node Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#core-parameters","title":"Core Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    None.

    "},{"location":"system/rqt_diagnostic_graph_monitor/","title":"System diagnostic monitor","text":""},{"location":"vehicle/calibration_adapter/","title":"calibration_adapter","text":""},{"location":"vehicle/calibration_adapter/#calibration_adapter","title":"calibration_adapter","text":""},{"location":"vehicle/calibration_adapter/#purpose","title":"Purpose","text":"

    This package relay topic to Float32Stamped type of \"autoware_calibration_msgs\" to generalize calibration topics.

    "},{"location":"vehicle/calibration_adapter/#details","title":"Details","text":"
    • calibration_adapter_node_base This node has general calibration topics for all vehicle interface
    • calibration_adapter This node has vehicle specific or temporary topics to calibrate and this node inherit calibration_adapter_node_base.
    "},{"location":"vehicle/calibration_adapter/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    TBD.

    "},{"location":"vehicle/parameter_estimator/","title":"ParameterEstimation","text":""},{"location":"vehicle/parameter_estimator/#parameterestimation","title":"ParameterEstimation","text":"

    This parameter estimation node estimates a default parameters from inputs for steer offset,wheel base and gear ratio.

    "},{"location":"vehicle/parameter_estimator/#io","title":"I/O","text":""},{"location":"vehicle/parameter_estimator/#input","title":"input","text":"

    The following topics are used to estimate the parameters.

    • /sensing/imu/imu_data: used as vehicle angular velocity
    • /vehicle/status/twist: used as vehicle velocity
    • /vehicle/status/steering: used as vehicle steering angle (Only used in Steer Offset Estimator & Wheel Base Estimator)
    • /calibration/vehicle/handle_status: used as vehicle handle angle (Only used in Gear Estimator)
    • /vehicle/engage: used to check the driving operation status
    "},{"location":"vehicle/parameter_estimator/#output","title":"output","text":"

    The following topics are the output

    • /vehicle/status/gear_ratio
    • /vehicle/status/steering_offset
    • /vehicle/status/wheel_base

    For users, the EstimationResult.msg output contains the following items:

    • result: Estimated result.
    • result_mean: Average value of result.
    • result_stddev: Standard deviation value of the estimated parameter
    • absolute_error: Absolute error of the estimated parameters
    • mean_absolute_error: Mean absolute error of the estimated parameters
    • stddev_absolute_error: Standard Deviation of absolute error of the estimated parameters
    "},{"location":"vehicle/parameter_estimator/#these-values-can-be-confirmed-in-plot_juggler","title":"These values can be confirmed in plot_juggler","text":"
    • To display in the plot juggler, you need to drag the result into the table, currently plot juggler cannot auto display the value
    "},{"location":"vehicle/parameter_estimator/#how-to-run-parameter-estimator","title":"How to Run Parameter Estimator","text":"

    Note: You need to build the Autoware beforehand.

    The following command will start the parameter estimation node.

    ros2 launch parameter_estimator parameter_estimator.launch.xml vehicle_model:=lexus\n
    • The following arguments are using to select the estimator, default is true
      • select_gear_ratio_estimator
      • select_steer_offset_estimator
      • select_wheel_base_estimator
    • To deselect the specific estimator, you need to set estimator to false
    • Example, the following command will only launch gear ratio estimator
    ros2 launch parameter_estimator parameter_estimator.launch.xml vehicle_model:=lexus select_steer_offset_estimator:=false select_wheel_base_estimator:=false\n

    If you want to launch with Rviz, use the following launch file. Currently unavailable

    # Launch parameter Estimator with the Autoware\n$ ros2 launch parameter_estimator parameter_estimator_with_simulation.launch.xml map_path:=.../kashiwanoha2/ vehicle_model:=jpntaxi sensor_model:=aip_xx1 rviz:=true\n
    "},{"location":"vehicle/parameter_estimator/#how-to-check-the-estimated-parameters","title":"How to check the estimated parameters","text":"

    The necessary information is plotted in the plot_juggler, which displays the following information from top to bottom.

    • First row: Estimation results confirmation
    • Second row: error for estimation

    You need to adjust the value of (valid_min_) or (valid_max_). according to the standard deviation to determine the validity of the data.

    "},{"location":"vehicle/parameter_estimator/#estimation-results-confirmation","title":"Estimation results confirmation","text":"

    Check the estimation results.

    • result : parameter estimated at each step
    • result_mean : Average of the parameters
    • result_stddev : Standard deviation of the estimated parameters

    It is preferable to use the _mean for the calibration results.

    The parameters estimation starts when enough data is stored. The output value is zero until it is ready.

    "},{"location":"vehicle/parameter_estimator/#error-for-parameters-estimation","title":"Error for parameters estimation","text":"

    Check the statistics of the errors in the input/output data after the parameter estimation.

    • absolute_error : absolute error of measured and estimated of the parameters estimation
    • mean_absolute_error : Mean of the absolute error calculated in each estimation step
    • stddev_absolute_error : Standard deviation of the absolute error calculated in each estimation step

    If these values are large, the model needs to be reconsidered.

    "},{"location":"vehicle/parameter_estimator/#data-preprocessing","title":"Data preprocessing","text":""},{"location":"vehicle/parameter_estimator/#examine-the-results-of-processing-the-input-data","title":"Examine the results of processing the input data","text":"

    Data that do not satisfy the following conditions are considered invalid and will not be used for estimation.

    • Data variation (evaluated by standard deviation) is smaller than the threshold
    • The car is not in automatic operation mode (judged from Autoware's Engage, Vehicle's Engage, etc.)
    "},{"location":"vehicle/pitch_checker/","title":"pitch checker","text":""},{"location":"vehicle/pitch_checker/#pitch-checker","title":"pitch checker","text":"

    The role of this node is to visualize pitch of driving route. The source of pitch is tf (map->base_link).

    "},{"location":"vehicle/pitch_checker/#how-to-visualize","title":"How to visualize","text":""},{"location":"vehicle/pitch_checker/#collect-data","title":"Collect data","text":""},{"location":"vehicle/pitch_checker/#launch-data-collector-node","title":"launch data collector node","text":"
    ros2 launch pitch_checker pitch_checker.launch.xml\n
    "},{"location":"vehicle/pitch_checker/#save-file-to-data","title":"save file to data","text":"
    ros2 service call /pitch_checker/save_flag std_srvs/srv/Trigger {}\n

    (The pitch data is saved at <YOUR WORKSPACE>/install/pitch_checker/share/pitch_checker/pitch.csv)

    "},{"location":"vehicle/pitch_checker/#visualize-data","title":"Visualize data","text":"
    ros2 launch pitch_checker view_pitch.launch.xml\n

    The view_pitch.launch loads the data stored in the default path and visualize it is as below. The pitch angle [rad] is shown on the left plot, the value of the z-coordinate [m] on the right plot.

    "},{"location":"vehicle/time_delay_estimator/","title":"TimeDelayEstimation","text":""},{"location":"vehicle/time_delay_estimator/#timedelayestimation","title":"TimeDelayEstimation","text":"

    This delay estimation node estimates a time delay from inputs to outputs for accel, brake, and steer.

    "},{"location":"vehicle/time_delay_estimator/#input-response","title":"Input / Response","text":"

    The following topics are used to estimate the delay.

    • /vehicle/raw_vehicle_cmd: used as accel/brake target value
    • /control/control_cmd: used as steer target value
    • /calibration/vehicle/accel_status: used as accel observed value
    • /calibration/vehicle/brake_status: used as brake observed value
    • /vehicle/status/steering: used as steer observed value
    • /calibration/vehicle/is_engage: used to check the driving operation status

    output.

    For users, the TimeDelay.msg output contains the following items:

    • time_delay: Estimated time delay.
    • mean: Mean value of the estimated time delay
    • stddev: Standard deviation of the estimated time delay
    • is_valid_data: Validity determination of the current data
    • first_order_model_coefficients\uff1asize 2 array of model coefficients(b,k,t)
    • second_order_model_coefficients\uff1asize 2 array of model coefficients(m,b,k,t)

    In addition, the following items are output for developers.

    • Mean average error of delay estimation
    • Standard deviation of the mean error of delay estimation

    These values can be confirmed in rqt_multiplot, described below.

    "},{"location":"vehicle/time_delay_estimator/#how-to-run-time-delay-estimator","title":"How to Run Time Delay Estimator","text":"

    Note: You need to build the Autoware beforehand.

    The following command will start the delay estimation node.

    ros2 launch time_delay_estimator time_delay_estimator.launch.xml is_showing_debug_graph:=true\n

    "},{"location":"vehicle/time_delay_estimator/#change-the-estimator-type","title":"Change the estimator type","text":"

    You can decide the estimator_type with the following parameters

    • \"cc\" : Cross Correlation
    • \"ls\" : Least Squared
    • \"ls2\" : Least Squared Second

    Note: Only \"cc\" Cross Correlation will display the debug graph

    "},{"location":"vehicle/time_delay_estimator/#how-to-check-the-estimated-delay","title":"How to check the estimated delay","text":"

    The necessary information is plotted in the rqt_multiplot, which displays the following information from top to bottom.

    • First row: Input data processing results examination
    • Second row: Estimation results confirmation
    • Third row: The confidence level of the estimation results
    • Fourth row: Input/output error after delay compensation
    "},{"location":"vehicle/time_delay_estimator/#input-data-processing-results-examination","title":"Input data processing results examination","text":"

    Check the input and output data. It is also used to adjust parameters of the estimation logic.

    • input raw : input data
    • response raw : response data
    • input processed : input data after compensation (*)
    • response processed : response data after compensation (*)
    • data stddev : standard deviation of the data used for estimation (used to determine validity)
    • is valid data : Whether the data is valid or not
      • 0.0 : invalid because the standard deviation is less than the threshold (*_min_stddev_threshold).
      • 1.0 : valid because the standard deviation is greater than the threshold (*_min_stddev_threshold).

    (*) Smoothing, normalization, and resampling are applied as preprocessing.

    You need to adjust the value of *_min_stddev_threshold according to the standard deviation to determine the validity of the data.

    "},{"location":"vehicle/time_delay_estimator/#estimation-results-confirmation","title":"Estimation results confirmation","text":"

    Check the estimation results.

    • delay : Time delay estimated at each step
    • average : Average of the time delays
    • stddev : Standard deviation of the estimated delay

    It is preferable to use the average for the calibration results.

    The delay estimation starts when enough data is stored. The output value is zero until it is ready.

    "},{"location":"vehicle/time_delay_estimator/#confidence-level-of-the-estimation-results","title":"Confidence level of the estimation results","text":"

    The reliability of the estimated time delay can be analyzed by the correlation coefficient.

    • correlation peak : correlation coefficient between input and output (if this value is low (about 0.7 or less), the estimation may not be successful)
    • detection result : Whether the cross-correlation resulted in a good estimation or not.
      • 0.00 : Invalid estimation due to low correlation (output the previous value)
      • 0.50 : Estimation has not started yet or received invalid data
      • 1.00 : Estimation has been done properly

    "},{"location":"vehicle/time_delay_estimator/#inputoutput-error-after-delay-compensation","title":"Input/output error after delay compensation","text":"

    Check the statistics of the errors in the input/output data after the time delay compensation.

    • mae raw : Mean absolute error of input/output after the delay compensation
    • mae mean : Mean of the mean absolute error calculated in each estimation step
    • mae stddev : Standard deviation of mean absolute error

    If these values are large, the input/output model needs to be reconsidered.

    "},{"location":"vehicle/time_delay_estimator/#data-preprocessing","title":"Data preprocessing","text":""},{"location":"vehicle/time_delay_estimator/#examine-the-results-of-processing-the-input-data","title":"Examine the results of processing the input data","text":"

    Data that do not satisfy the following conditions are considered invalid and will not be used for estimation.

    • Data variation (evaluated by standard deviation) is smaller than the threshold
    • The car is not in automatic operation mode (judged from Autoware's Engage, Vehicle's Engage, etc.)
    "},{"location":"vehicle/time_delay_estimator/#visualization-of-delay-estimation-results","title":"Visualization of delay estimation results","text":"

    Before running the node, you need to set the is_showing_debug_info parameter in the yaml file to true for a visualization. Then the internal values of accel/brake/steer/test are plotted on the python visualization tool. If the superposition of input and response is good, we can say that we have a good estimation.

    "},{"location":"vehicle/time_delay_estimator/#test-wip","title":"Test WIP","text":"

    Execute the following command to perform an estimation on the sample data. This test should be used to see the characteristics when the parameters are changed.

    roslaunch time_delay_estimator test_time_delay_estimator.launch\n
    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"autoware_tools","text":""},{"location":"#autoware_tools","title":"autoware_tools","text":"

    This is a repository for keeping packages that are not needed at runtime, including packages for benchmarking, debugging, tuning, calibrating, etc.

    "},{"location":"CODE_OF_CONDUCT/","title":"Contributor Covenant Code of Conduct","text":""},{"location":"CODE_OF_CONDUCT/#contributor-covenant-code-of-conduct","title":"Contributor Covenant Code of Conduct","text":""},{"location":"CODE_OF_CONDUCT/#our-pledge","title":"Our Pledge","text":"

    We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

    We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

    "},{"location":"CODE_OF_CONDUCT/#our-standards","title":"Our Standards","text":"

    Examples of behavior that contributes to a positive environment for our community include:

    • Demonstrating empathy and kindness toward other people
    • Being respectful of differing opinions, viewpoints, and experiences
    • Giving and gracefully accepting constructive feedback
    • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
    • Focusing on what is best not just for us as individuals, but for the overall community

    Examples of unacceptable behavior include:

    • The use of sexualized language or imagery, and sexual attention or advances of any kind
    • Trolling, insulting or derogatory comments, and personal or political attacks
    • Public or private harassment
    • Publishing others' private information, such as a physical or email address, without their explicit permission
    • Other conduct which could reasonably be considered inappropriate in a professional setting
    "},{"location":"CODE_OF_CONDUCT/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"

    Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

    Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

    "},{"location":"CODE_OF_CONDUCT/#scope","title":"Scope","text":"

    This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

    "},{"location":"CODE_OF_CONDUCT/#enforcement","title":"Enforcement","text":"

    Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at conduct@autoware.org. All complaints will be reviewed and investigated promptly and fairly.

    All community leaders are obligated to respect the privacy and security of the reporter of any incident.

    "},{"location":"CODE_OF_CONDUCT/#enforcement-guidelines","title":"Enforcement Guidelines","text":"

    Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

    "},{"location":"CODE_OF_CONDUCT/#1-correction","title":"1. Correction","text":"

    Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

    Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

    "},{"location":"CODE_OF_CONDUCT/#2-warning","title":"2. Warning","text":"

    Community Impact: A violation through a single incident or series of actions.

    Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

    "},{"location":"CODE_OF_CONDUCT/#3-temporary-ban","title":"3. Temporary Ban","text":"

    Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

    Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

    "},{"location":"CODE_OF_CONDUCT/#4-permanent-ban","title":"4. Permanent Ban","text":"

    Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

    Consequence: A permanent ban from any sort of public interaction within the community.

    "},{"location":"CODE_OF_CONDUCT/#attribution","title":"Attribution","text":"

    This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.

    Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

    For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

    "},{"location":"CONTRIBUTING/","title":"Contributing","text":""},{"location":"CONTRIBUTING/#contributing","title":"Contributing","text":"

    See https://autowarefoundation.github.io/autoware-documentation/main/contributing/.

    "},{"location":"DISCLAIMER/","title":"DISCLAIMER","text":"

    DISCLAIMER

    \u201cAutoware\u201d will be provided by The Autoware Foundation under the Apache License 2.0. This \u201cDISCLAIMER\u201d will be applied to all users of Autoware (a \u201cUser\u201d or \u201cUsers\u201d) with the Apache License 2.0 and Users shall hereby approve and acknowledge all the contents specified in this disclaimer below and will be deemed to consent to this disclaimer without any objection upon utilizing or downloading Autoware.

    Disclaimer and Waiver of Warranties

    1. AUTOWARE FOUNDATION MAKES NO REPRESENTATION OR WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH RESPECT TO PROVIDING AUTOWARE (the \u201cService\u201d) including but not limited to any representation or warranty (i) of fitness or suitability for a particular purpose contemplated by the Users, (ii) of the expected functions, commercial value, accuracy, or usefulness of the Service, (iii) that the use by the Users of the Service complies with the laws and regulations applicable to the Users or any internal rules established by industrial organizations, (iv) that the Service will be free of interruption or defects, (v) of the non-infringement of any third party's right and (vi) the accuracy of the content of the Services and the software itself.

    2. The Autoware Foundation shall not be liable for any damage incurred by the User that are attributable to the Autoware Foundation for any reasons whatsoever. UNDER NO CIRCUMSTANCES SHALL THE AUTOWARE FOUNDATION BE LIABLE FOR INCIDENTAL, INDIRECT, SPECIAL OR FUTURE DAMAGES OR LOSS OF PROFITS.

    3. A User shall be entirely responsible for the content posted by the User and its use of any content of the Service or the Website. If the User is held responsible in a civil action such as a claim for damages or even in a criminal case, the Autoware Foundation and member companies, governments and academic & non-profit organizations and their directors, officers, employees and agents (collectively, the \u201cIndemnified Parties\u201d) shall be completely discharged from any rights or assertions the User may have against the Indemnified Parties, or from any legal action, litigation or similar procedures.

    Indemnity

    A User shall indemnify and hold the Indemnified Parties harmless from any of their damages, losses, liabilities, costs or expenses (including attorneys' fees or criminal compensation), or any claims or demands made against the Indemnified Parties by any third party, due to or arising out of, or in connection with utilizing Autoware (including the representations and warranties), the violation of applicable Product Liability Law of each country (including criminal case) or violation of any applicable laws by the Users, or the content posted by the User or its use of any content of the Service or the Website.

    "},{"location":"autoware_dependency_checker/","title":"autoware_dependency_checker","text":""},{"location":"autoware_dependency_checker/#autoware_dependency_checker","title":"autoware_dependency_checker","text":"

    This package provides a script for checking whether each package's dependencies listed in a package.xml are used or not. Currently, it mainly checks packages that start with autoware_.

    "},{"location":"autoware_dependency_checker/#dependency-checking","title":"Dependency Checking","text":"

    The script will try to match the dependencies and the headers by reading the dependencies listed in package.xml and the included headers in the source files.

    Some dependency in package.xml and the included header might differ. The following table shows the matching between dependency names and headers:

    from to description autoware_pkg_name autoware/pkg_name Usually this style should be used autoware_*_msgs autoware_*_msgs For messages autoware_other_pkg autoware_other_pkg E.g. autoware_lanelet2_extension"},{"location":"autoware_dependency_checker/#usage","title":"Usage","text":"
    # build\n$ cd to/autoware_tools\n$ colcon build --symlink-install --cmake-args --packages-up-to autoware_dependency_checker\n$ source\n\n# run\n$ cd to/your/autoware\n$ ros2 run autoware_dependency_checker dependency_checker.sh\n\n# run in some package\n$ cd to/some/package\n$ ros2 run autoware_dependency_checker dependency_checker.sh\n
    "},{"location":"bag2lanelet/","title":"bag2lanelet","text":""},{"location":"bag2lanelet/#bag2lanelet","title":"bag2lanelet","text":"

    This package generates a lanelet map necessary for Autoware's autonomous driving from rosbag data containing information about Localization (/tf). This enables autonomous driving based on manual driving information.

    The provided functionalities are as follows:

    • bag2lanelet.py: Generates lanelet (.osm) from a rosbag based on the position of base_link.
    • bag2trajectory.py: Generates trajectory information (.csv) for vector_map_builder from a rosbag.
    "},{"location":"bag2lanelet/#example","title":"Example","text":"

    As an example, the process of lanelet generation based on driving trajectories from the planning simulator is performed as follows. Typically, the expectation is to use rosbag data from manual driving, rather than from the planning simulator.

    Firstly, you need to run the planning_simulator following the planning_simulator tutorial in Autoware Documentation. The process would be, install Autoware, download the maps, run the planning_simulator, and start autonomous driving. Make sure to save the rosbag during this driving session using the following command:

    ros2 bag record /tf -o /tmp/bag2lanelet_sample.bag\n

    After completing the drive, you can run the bag2lanelet.py script. This requires specifying the output directory, lane width and MGRS coordinates:

    ./bag2lanelet.py /tmp/bag2lanelet_sample.bag /tmp/bag2lanelet_sample -l 3.0 -m 54SUE\n

    The map will be saved in the specified directory, following the naming convention <date>-lanelet2_map.osm. The map generated will appear like this. You can see the example result in ./example/lanelet2_map.osm.

    When you relaunch the planning_simulator with the new lanelet2 map, you will see the following.

    Please note that at this stage, although this map works with Autoware, the shape of the lanes will appear jagged. (Refer to the 'Limitations' section for more details.) While this is an issue that should be addressed in the future, it can currently be resolved by loading it in Vector Map Builder as follows.

    Following the documentation of the Vector Map Builder, import the generated Lanelet2 map. You can see the refined lane on the application.

    Then, Export the map. You can run the planning_simulator with the refined lanelet2 map and see how it goes on the Rviz.

    "},{"location":"bag2lanelet/#requirements","title":"Requirements","text":"
    sudo apt update\nsudo apt install ros-humble-tf-transformations ros-humble-tf-transformations\npip install -r requirements.txt\n
    "},{"location":"bag2lanelet/#usage","title":"Usage","text":"

    Check ./bag2lanelet.py --help

    "},{"location":"bag2lanelet/#generate-lanelet2-file","title":"generate lanelet2 file","text":"

    For given lane width and MGRS coordinate.

    ./bag2lanelet.py /home/autoware/rosbag/sample .  -l 3.0 -m 54SUE\n
    "},{"location":"bag2lanelet/#generate-trajectory-file-for-vector-map-builder","title":"generate trajectory file for Vector Map Builder","text":"
    ./bag2trajectory.py /home/autoware/rosbag/sample sample.csv\n
    "},{"location":"bag2lanelet/#limitations","title":"Limitations","text":"

    Here is the limitations of this package. Contributions to further improvements are more than welcome.

    • Due to the low conversion accuracy from MGRS to latitude and longitude in this script, the lanes in the output lanelet.osm appear jagged. Importing and then exporting through vector_map_builder corrects these values with high accuracy.
    "},{"location":"common/autoware_debug_tools/","title":"Autoware Debug Tools","text":""},{"location":"common/autoware_debug_tools/#autoware-debug-tools","title":"Autoware Debug Tools","text":"

    This package provides tools for debugging Autoware.

    "},{"location":"common/autoware_debug_tools/#processing-time-visualizer","title":"Processing Time Visualizer","text":"

    This tool visualizes tier4_debug_msgs/msg/ProcessingTimeTree messages.

    "},{"location":"common/autoware_debug_tools/#usage","title":"Usage","text":"
    1. Run the following command to start the visualizer.

      ros2 run autoware_debug_tools processing_time_visualizer\n
    2. Select a topic to visualize.

    3. Then, the visualizer will show the processing time tree.

    "},{"location":"common/autoware_debug_tools/#summarized-output","title":"summarized output","text":"

    Running with --summarize, it will output the summarized information.

    > ros2 run autoware_debug_tools processing_time_visualizer --summarize\n\nobjectsCallback: 17.99 [ms], run count: 1\n    \u251c\u2500\u2500 removeStaleTrafficLightInfo: 0.00 [ms], run count: 1\n    \u251c\u2500\u2500 updateObjectData: 0.03 [ms], run count: 13\n    \u251c\u2500\u2500 getCurrentLanelets: 4.81 [ms], run count: 13\n    \u2502   \u251c\u2500\u2500 checkCloseLaneletCondition: 2.43 [ms], run count: 130\n    \u2502   \u251c\u2500\u2500 isDuplicated: 0.02 [ms], run count: 17\n    \u2502   \u2514\u2500\u2500 calculateLocalLikelihood: 0.66 [ms], run count: 12\n    \u251c\u2500\u2500 updateRoadUsersHistory: 0.30 [ms], run count: 13\n    \u2514\u2500\u2500 getPredictedReferencePath: 5.47 [ms], run count: 5\n        \u251c\u2500\u2500 predictObjectManeuver: 0.40 [ms], run count: 5\n        \u2502   \u2514\u2500\u2500 predictObjectManeuverByLatDiffDistance: 0.34 [ms], run count: 5\n        \u2502       \u2514\u2500\u2500 calcRightLateralOffset: 0.03 [ms], run count: 12\n        \u251c\u2500\u2500 calculateManeuverProbability: 0.01 [ms], run count: 5\n        \u2514\u2500\u2500 addReferencePaths: 4.66 [ms], run count: 15\n            \u251c\u2500\u2500 updateFuturePossibleLanelets: 0.08 [ms], run count: 8\n            \u2514\u2500\u2500 convertPathType: 4.29 [ms], run count: 8\n
    "},{"location":"common/autoware_debug_tools/#system-usage-monitor","title":"System Usage Monitor","text":"

    The purpose of the System Usage Monitor is to monitor, visualize and publish the CPU usage and memory usage of the ROS processes. By providing a real-time terminal-based visualization, users can easily confirm the cpu and memory usage as in the picture below.

    You can run the program by the following command.

    ros2 run autoware_debug_tools system_usage_monitor\n
    "},{"location":"common/autoware_debug_tools/#system-performance-plotter","title":"System Performance Plotter","text":"

    This script plots the following metrics by each Autoware's module.

    • processing time
    • CPU usage
    • memory usage
    "},{"location":"common/autoware_debug_tools/#usage_1","title":"Usage","text":"

    Run the following commands according to your purpose.

    # plot processing time\nros2 run autoware_debug_tools processing_time_plotter <bag-path>\n\n# plot CPU usage\nros2 run autoware_debug_tools cpu_usage_plotter <bag-path>\n\n# plot memory usage\nros2 run autoware_debug_tools memory_usage_plotter <bag-path>\n

    There are several options.

    • -c:
      • can filter modules in the specific component (e.g. all, planning, system, etc).
    • -n <number>:
      • can pick up top <number> critical modules.
    • -g <text>
      • can filter the modules which include <text>.
    • -y <val>
      • can set the height of the plot to <val>.
    "},{"location":"common/autoware_debug_tools/#examples","title":"Examples","text":"
    ros2 run autoware_debug_tools processing_time_plotter <bag-path> -c planning -g behavior_path -y 300\n
    ros2 run autoware_debug_tools cpu_usage_plotter <bag-path> -n 20\n
    "},{"location":"common/autoware_debug_tools/#rosout-log-reconstructor","title":"Rosout Log Reconstructor","text":"

    This script shows the log from the /rosout topic on the terminal.

    "},{"location":"common/autoware_debug_tools/#usage_2","title":"Usage","text":"
    ros2 run autoware_debug_tools rosout_log_reconstructor\n
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/","title":"Topic Connection Checker","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-connection-checker","title":"Topic Connection Checker","text":"

    The Topic Connection Checker is an advanced diagnostic tool designed to simulate how an Autoware Engineer debugs an Autoware system in the field when certain topics are not functioning as expected. This tool is essential for identifying and resolving issues in the complex topic network of an Autoware system.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#overview","title":"Overview","text":"

    The tool consists of two main components:

    1. Topic Connection Checker
    2. Topic Localizer

    These components work together to provide a comprehensive debugging experience, following a systematic approach to identify and locate problematic topics in the Autoware system.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#debugging-process","title":"Debugging Process","text":"

    The Topic Connection Checker follows a step-by-step process that mimics an experienced Autoware Engineer's debugging approach:

    1. Identify key topics with unexpected output using diagnostic information and major final output topics.
    2. Track the publishing nodes of these blocked output topics.
    3. Investigate the subscribed inputs of these publishing nodes to find upstream blocked topics.
    4. Trace back to the source to identify key topics that are not being published.
    5. Locate the source of lost topics in the code or launching system.

    Steps 1-4 are handled by the Topic Connection Checker, while step 5 is addressed by the Topic Localizer.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-connection-checker_1","title":"Topic Connection Checker","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#usage","title":"Usage","text":"

    To run the Topic Connection Checker, use the following command:

    ros2 run autoware_debug_tools topic_connection_checker\n
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#mechanism","title":"Mechanism","text":"

    The Topic Connection Checker operates as follows:

    1. Subscribes to /diagnostics for three seconds, focusing on hardware_id with topic_state_monitor.
    2. Subscribes to and traces stuck topics and all upstream topics.
    3. Performs multiple iterations to identify topics without publishers.
    4. Reports ERROR in the command line for problematic topics.

    The identified problematic topics can then be used as input for the Topic Localizer.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#topic-localizer","title":"Topic Localizer","text":""},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#usage_1","title":"Usage","text":"

    When launching from the autoware/pilot-auto directory, use the following command:

    ros2 run autoware_debug_tools topic_localizer . $TOPIC1,$TOPIC2\n\n## If we launch from a different directory\nros2 run autoware_debug_tools topic_localizer $AUTOWARE_DIRECTORY $TOPIC1,$TOPIC2\n

    Replace $TOPIC1,$TOPIC2 with the actual topic names you want to localize, separated by commas.

    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#mechanism_1","title":"Mechanism","text":"

    The Topic Localizer employs a two-step approach to find the source of problematic topics:

    1. Direct Search:

      • Scans all HPP/CPP and launch.py files for code snippets containing the exact names of the target topics.
    2. Launch System Analysis:

      • Starts with autoware_launch/launch/autoware.launch.xml using default arguments.
      • Statically traces all XML files in the launch system.
      • Identifies launch parameters or remapped topics matching the names of the target topics.
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#best-practices","title":"Best Practices","text":"
    1. Always start with the Topic Connection Checker to identify problematic topics.
    2. Use the output from the Topic Connection Checker as input for the Topic Localizer.
    3. Pay attention to ERROR messages in the command line output.
    4. When using the Topic Localizer, ensure you're in the correct directory (autoware/pilot-auto).
    5. Keep track of the relationships between topics to understand the flow of data in your Autoware system.
    "},{"location":"common/autoware_debug_tools/autoware_debug_tools/topic_connection_checker/readme/#troubleshooting","title":"Troubleshooting","text":"
    • If the Topic Connection Checker doesn't identify any issues, but you're still experiencing problems, it could be related to the pulishing frequencies. The connection checker marks a topic as \"fine\" if it has a single output in five seconds.
    • If the Topic Localizer doesn't find any matches, it is usually because of the topics are launch using launch.py files with sophisticated construction functions.

    By using these tools effectively, Autoware Engineers can quickly identify and resolve topic-related issues, ensuring smooth operation of the Autoware system.

    "},{"location":"common/mission_planner_rviz_plugin/","title":"mission_planner_rviz_plugin","text":""},{"location":"common/mission_planner_rviz_plugin/#mission_planner_rviz_plugin","title":"mission_planner_rviz_plugin","text":""},{"location":"common/mission_planner_rviz_plugin/#mrmgoaltool","title":"MrmGoalTool","text":"

    This is a copy of rviz_default_plugins::tools::GoalTool. Used together with the RouteSelectorPanel to set the MRM route. After adding the tool, change the topic name to /rviz/route_selector/mrm/goal from the topic property panel in rviz.

    "},{"location":"common/mission_planner_rviz_plugin/#routeselectorpanel","title":"RouteSelectorPanel","text":"

    This panel shows the main and mrm route state in the route_selector and the route states in the mission_planner. Additionally, it provides clear and set functions for each main route and mrm route.

    Trigger Action main route clear button call /planning/mission_planning/route_selector/main/clear_route mrm route clear button call /planning/mission_planning/route_selector/mrm/clear_route /rviz/route_selector/main/goal topic call /planning/mission_planning/route_selector/main/set_waypoint_route /rviz/route_selector/mrm/goal topic call /planning/mission_planning/route_selector/mrm/set_waypoint_route"},{"location":"common/rtc_manager_rviz_plugin/","title":"rtc_manager_rviz_plugin","text":""},{"location":"common/rtc_manager_rviz_plugin/#rtc_manager_rviz_plugin","title":"rtc_manager_rviz_plugin","text":""},{"location":"common/rtc_manager_rviz_plugin/#purpose","title":"Purpose","text":"

    The purpose of this Rviz plugin is

    1. To display each content of RTC status.

    2. To switch each module of RTC auto mode.

    3. To change RTC cooperate commands by button.

    "},{"location":"common/rtc_manager_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/rtc_manager_rviz_plugin/#input","title":"Input","text":"Name Type Description /api/external/get/rtc_status tier4_rtc_msgs::msg::CooperateStatusArray The statuses of each Cooperate Commands"},{"location":"common/rtc_manager_rviz_plugin/#output","title":"Output","text":"Name Type Description /api/external/set/rtc_commands tier4_rtc_msgs::src::CooperateCommands The Cooperate Commands for each planning /planning/enable_auto_mode/* tier4_rtc_msgs::src::AutoMode The Cooperate Commands mode for each planning module"},{"location":"common/rtc_manager_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.

    2. tier4_state_rviz_plugin/RTCManagerPanel and press OK.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/","title":"tier4_automatic_goal_rviz_plugin","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#tier4_automatic_goal_rviz_plugin","title":"tier4_automatic_goal_rviz_plugin","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#purpose","title":"Purpose","text":"
    1. Defining a GoalsList by adding goals using RvizTool (Pose on the map).

    2. Automatic execution of the created GoalsList from the selected goal - it can be stopped and restarted.

    3. Looping the current GoalsList.

    4. Saving achieved goals to a file.

    5. Plan the route to one (single) selected goal and starting that route - it can be stopped and restarted.

    6. Remove any goal from the list or clear the current route.

    7. Save the current GoalsList to a file and load the list from the file.

    8. The application enables/disables access to options depending on the current state.

    9. The saved GoalsList can be executed without using a plugin - using a node automatic_goal_sender.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/tier4_automatic_goal_rviz_plugin/#input","title":"Input","text":"Name Type Description /api/operation_mode/state autoware_adapi_v1_msgs::msg::OperationModeState The topic represents the state of operation mode /api/routing/state autoware_adapi_v1_msgs::msg::RouteState The topic represents the state of route /rviz2/automatic_goal/goal geometry_msgs::msgs::PoseStamped The topic for adding goals to GoalsList"},{"location":"common/tier4_automatic_goal_rviz_plugin/#output","title":"Output","text":"Name Type Description /api/operation_mode/change_to_autonomous autoware_adapi_v1_msgs::srv::ChangeOperationMode The service to change operation mode to autonomous /api/operation_mode/change_to_stop autoware_adapi_v1_msgs::srv::ChangeOperationMode The service to change operation mode to stop /api/routing/set_route_points autoware_adapi_v1_msgs::srv::SetRoutePoints The service to set route /api/routing/clear_route autoware_adapi_v1_msgs::srv::ClearRoute The service to clear route state /rviz2/automatic_goal/markers visualization_msgs::msg::MarkerArray The topic to visualize goals as rviz markers"},{"location":"common/tier4_automatic_goal_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.

    2. Select tier4_automatic_goal_rviz_plugin/AutowareAutomaticGoalPanel and press OK.

    3. Select Add a new tool.

    4. Select tier4_automatic_goal_rviz_plugin/AutowareAutomaticGoalTool and press OK.

    5. Add goals visualization as markers to Displays.

    6. Append goals to the GoalsList to be achieved using 2D Append Goal - in such a way that routes can be planned.

    7. Start sequential planning and goal achievement by clicking Send goals automatically

    8. You can save GoalsList by clicking Save to file.

    9. After saving, you can run the GoalsList without using a plugin also:

      • example: ros2 launch tier4_automatic_goal_rviz_plugin automatic_goal_sender.launch.xml goals_list_file_path:=\"/tmp/goals_list.yaml\" goals_achieved_dir_path:=\"/tmp/\"
        • goals_list_file_path - is the path to the saved GoalsList file to be loaded
        • goals_achieved_dir_path - is the path to the directory where the file goals_achieved.log will be created and the achieved goals will be written to it
    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#hints","title":"Hints","text":"

    If the application (Engagement) goes into ERROR mode (usually returns to EDITING later), it means that one of the services returned a calling error (code!=0). In this situation, check the terminal output for more information.

    • Often it is enough to try again.
    • Sometimes a clearing of the current route is required before retrying.
    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#material-design-icons","title":"Material Design Icons","text":"

    This project uses Material Design Icons by Google. These icons are used under the terms of the Apache License, Version 2.0.

    Material Design Icons are a collection of symbols provided by Google that are used to enhance the user interface of applications, websites, and other digital products.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#license","title":"License","text":"

    The Material Design Icons are licensed under the Apache License, Version 2.0. You may obtain a copy of the License at:

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

    "},{"location":"common/tier4_automatic_goal_rviz_plugin/#acknowledgments","title":"Acknowledgments","text":"

    We would like to express our gratitude to Google for making these icons available to the community, helping developers and designers enhance the visual appeal and user experience of their projects.

    "},{"location":"common/tier4_control_rviz_plugin/","title":"tier4_control_rviz_plugin","text":""},{"location":"common/tier4_control_rviz_plugin/#tier4_control_rviz_plugin","title":"tier4_control_rviz_plugin","text":"

    This package is to mimic external control for simulation.

    "},{"location":"common/tier4_control_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"common/tier4_control_rviz_plugin/#input","title":"Input","text":"Name Type Description /control/current_gate_mode tier4_control_msgs::msg::GateMode Current GATE mode /vehicle/status/velocity_status autoware_vehicle_msgs::msg::VelocityReport Current velocity status /api/autoware/get/engage tier4_external_api_msgs::srv::Engage Getting Engage /vehicle/status/gear_status autoware_vehicle_msgs::msg::GearReport The state of GEAR"},{"location":"common/tier4_control_rviz_plugin/#output","title":"Output","text":"Name Type Description /control/gate_mode_cmd tier4_control_msgs::msg::GateMode GATE mode /external/selected/control_cmd autoware_control_msgs::msg::ControlCommand Control command /external/selected/gear_cmd autoware_vehicle_msgs::msg::GearCommand GEAR"},{"location":"common/tier4_control_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select Panels.

    2. Select tier4_control_rviz_plugin/ManualController and press OK.

    3. Enter velocity in \"Set Cruise Velocity\" and Press the button to confirm. You can notice that GEAR shows D (DRIVE).

    4. Press \"Enable Manual Control\" and you can notice that \"GATE\" and \"Engage\" turn \"Ready\" and the vehicle starts!

    "},{"location":"common/tier4_debug_rviz_plugin/","title":"tier4_debug_rviz_plugin","text":""},{"location":"common/tier4_debug_rviz_plugin/#tier4_debug_rviz_plugin","title":"tier4_debug_rviz_plugin","text":"

    This package is including jsk code. Note that jsk_overlay_utils.cpp and jsk_overlay_utils.hpp are BSD license.

    "},{"location":"common/tier4_debug_rviz_plugin/#plugins","title":"Plugins","text":""},{"location":"common/tier4_debug_rviz_plugin/#float32multiarraystampedpiechart","title":"Float32MultiArrayStampedPieChart","text":"

    Pie chart from tier4_debug_msgs::msg::Float32MultiArrayStamped.

    "},{"location":"common/tier4_debug_tools/","title":"tier4_debug_tools","text":""},{"location":"common/tier4_debug_tools/#tier4_debug_tools","title":"tier4_debug_tools","text":"

    This package provides useful features for debugging Autoware.

    "},{"location":"common/tier4_debug_tools/#usage","title":"Usage","text":""},{"location":"common/tier4_debug_tools/#tf2pose","title":"tf2pose","text":"

    This tool converts any tf to pose topic. With this tool, for example, you can plot x values of tf in rqt_multiplot.

    ros2 run tier4_debug_tools tf2pose {tf_from} {tf_to} {hz}\n

    Example:

    $ ros2 run tier4_debug_tools tf2pose base_link ndt_base_link 100\n\n$ ros2 topic echo /tf2pose/pose -n1\nheader:\n  seq: 13\nstamp:\n    secs: 1605168366\nnsecs: 549174070\nframe_id: \"base_link\"\npose:\n  position:\n    x: 0.0387684271191\n    y: -0.00320360406477\n    z: 0.000276674520819\n  orientation:\n    x: 0.000335221893885\n    y: 0.000122020672186\n    z: -0.00539673212896\n    w: 0.999985368502\n---\n
    "},{"location":"common/tier4_debug_tools/#pose2tf","title":"pose2tf","text":"

    This tool converts any pose topic to tf.

    ros2 run tier4_debug_tools pose2tf {pose_topic_name} {tf_name}\n

    Example:

    $ ros2 run tier4_debug_tools pose2tf /localization/pose_estimator/pose ndt_pose\n\n$ ros2 run tf tf_echo ndt_pose ndt_base_link 100\nAt time 1605168365.449\n- Translation: [0.000, 0.000, 0.000]\n- Rotation: in Quaternion [0.000, 0.000, 0.000, 1.000]\nin RPY (radian) [0.000, -0.000, 0.000]\nin RPY (degree) [0.000, -0.000, 0.000]\n
    "},{"location":"common/tier4_debug_tools/#stop_reason2pose","title":"stop_reason2pose","text":"

    This tool extracts pose from stop_reasons. Topics without numbers such as /stop_reason2pose/pose/detection_area are the nearest stop_reasons, and topics with numbers are individual stop_reasons that are roughly matched with previous ones.

    ros2 run tier4_debug_tools stop_reason2pose {stop_reason_topic_name}\n

    Example:

    $ ros2 run tier4_debug_tools stop_reason2pose /planning/scenario_planning/status/stop_reasons\n\n$ ros2 topic list | ag stop_reason2pose\n/stop_reason2pose/pose/detection_area\n/stop_reason2pose/pose/detection_area_1\n/stop_reason2pose/pose/obstacle_stop\n/stop_reason2pose/pose/obstacle_stop_1\n\n$ ros2 topic echo /stop_reason2pose/pose/detection_area -n1\nheader:\n  seq: 1\nstamp:\n    secs: 1605168355\nnsecs:    821713\nframe_id: \"map\"\npose:\n  position:\n    x: 60608.8433457\n    y: 43886.2410876\n    z: 44.9078212441\n  orientation:\n    x: 0.0\n    y: 0.0\n    z: -0.190261378408\n    w: 0.981733470901\n---\n
    "},{"location":"common/tier4_debug_tools/#stop_reason2tf","title":"stop_reason2tf","text":"

    This is an all-in-one script that uses tf2pose, pose2tf, and stop_reason2pose. With this tool, you can view the relative position from base_link to the nearest stop_reason.

    ros2 run tier4_debug_tools stop_reason2tf {stop_reason_name}\n

    Example:

    $ ros2 run tier4_debug_tools stop_reason2tf obstacle_stop\nAt time 1605168359.501\n- Translation: [0.291, -0.095, 0.266]\n- Rotation: in Quaternion [0.007, 0.011, -0.005, 1.000]\nin RPY (radian) [0.014, 0.023, -0.010]\nin RPY (degree) [0.825, 1.305, -0.573]\n
    "},{"location":"common/tier4_debug_tools/#lateral_error_publisher","title":"lateral_error_publisher","text":"

    This node calculate the control error and localization error in the trajectory normal direction as shown in the figure below.

    Set the reference trajectory, vehicle pose and ground truth pose in the launch file.

    ros2 launch tier4_debug_tools lateral_error_publisher.launch.xml\n
    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/","title":"tier4_logging_level_configure_rviz_plugin","text":""},{"location":"common/tier4_logging_level_configure_rviz_plugin/#tier4_logging_level_configure_rviz_plugin","title":"tier4_logging_level_configure_rviz_plugin","text":"

    This package provides an rviz_plugin that can easily change the logger level of each node.

    This plugin dispatches services to the \"logger name\" associated with \"nodes\" specified in YAML, adjusting the logger level.

    Warning

    It is highly recommended to use this plugin when you're attempting to print any debug information. Furthermore, it is strongly advised to avoid using the logging level INFO, as it might flood the terminal with your information, potentially causing other useful information to be missed.

    Note

    To add your logger to the list, simply include the node_name and logger_name in the logger_config.yaml under the corresponding component or module. If the relevant component or module is not listed, you may add them yourself.

    Note

    As of November 2023, in ROS 2 Humble, users are required to initiate a service server in the node to use this feature. (This might be integrated into ROS standards in the future.) For easy service server generation, you can use the LoggerLevelConfigure utility.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#how-to-use-the-plugin","title":"How to use the plugin","text":"

    In RVIZ2, go to Panels and add LoggingLevelConfigureRVizPlugin. Then, search for the node you're interested in and select the corresponding logging level to print the logs.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#how-to-add-or-find-your-logger-name","title":"How to add or find your logger name","text":"

    Because there are no available ROS 2 CLI commands to list loggers, there isn't a straightforward way to check your logger name. Additionally, the following assumes that you already know which node you're working with.

    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#for-logger-as-a-class-member-variable","title":"For logger as a class member variable","text":"

    If your class doesn't have an rclcpp::Logger member variable, you can start by including one yourself:

    mutable rclcpp::Logger logger_;\n

    If your node already has a logger, it should, under normal circumstances, be similar to the node's name.

    For instance, if the node name is /some_component/some_node/node_child, the logger_name would be some_component.some_node.node_child.

    Should your log not print as expected, one approach is to initially set your logging level in the code to info, like so:

    RCLCPP_INFO(logger_, \"Print something here.\");\n

    This will result in something like the following being printed in the terminal:

    [component_container_mt-36] [INFO 1711949149.735437551] [logger_name]: Print something here. (func() at /path/to/code:line_number)\n

    Afterward, you can simply copy the logger_name.

    Warning

    Remember to revert your code to the appropriate logging level after testing.

    RCLCPP_DEBUG(logger_, \"Print something here.\");\n
    "},{"location":"common/tier4_logging_level_configure_rviz_plugin/#for-libraries","title":"For libraries","text":"

    When dealing with libraries, such as utility functions, you may need to add the logger manually. Here's an example:

    RCLCPP_WARN(\nrclcpp::get_logger(\"some_component\").get_child(\"some_child\").get_child(\"some_child2\"),\n\"Print something here.\");\n

    In this scenario, the logger_name would be some_component.some_child.some_child2.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/","title":"tier4_screen_capture_rviz_plugin","text":""},{"location":"common/tier4_screen_capture_rviz_plugin/#tier4_screen_capture_rviz_plugin","title":"tier4_screen_capture_rviz_plugin","text":""},{"location":"common/tier4_screen_capture_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin captures the screen of rviz.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/#interface","title":"Interface","text":"Name Type Description /debug/capture/video std_srvs::srv::Trigger Trigger to start screen capturing. /debug/capture/video_with_buffer std_srvs::srv::Trigger Trigger to start screen capturing with buffer. /debug/capture/screen_shot std_srvs::srv::Trigger Trigger to capture screen shot."},{"location":"common/tier4_screen_capture_rviz_plugin/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    This is only for debug or analyze. The capture screen button is still beta version which can slow frame rate. set lower frame rate according to PC spec.

    "},{"location":"common/tier4_screen_capture_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select panels/Add new panel.
    "},{"location":"common/tier4_simulated_clock_rviz_plugin/","title":"tier4_simulated_clock_rviz_plugin","text":""},{"location":"common/tier4_simulated_clock_rviz_plugin/#tier4_simulated_clock_rviz_plugin","title":"tier4_simulated_clock_rviz_plugin","text":""},{"location":"common/tier4_simulated_clock_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin allows publishing and controlling the simulated ROS time.

    "},{"location":"common/tier4_simulated_clock_rviz_plugin/#output","title":"Output","text":"Name Type Description /clock rosgraph_msgs::msg::Clock the current simulated time"},{"location":"common/tier4_simulated_clock_rviz_plugin/#how-to-use-the-plugin","title":"How to use the plugin","text":"
    1. Launch planning simulator with use_sim_time:=true.

      ros2 launch autoware_launch planning_simulator.launch.xml map_path:=$HOME/autoware_map/sample-map-planning vehicle_model:=sample_vehicle sensor_model:=sample_sensor_kit use_sim_time:=true\n

      Warning If you launch the planning simulator without adding the tier4_simulated_clock_rviz_plugin, your simulation will not be running. You'll not even be able to place the initial and the goal poses.

    2. Start rviz and select panels/Add new panel.

    3. Select tier4_clock_rviz_plugin/SimulatedClock and press OK.

    4. Use the added panel to control how the simulated clock is published.

      1. Pause button: pause/resume the clock.
      2. Speed: speed of the clock relative to the system clock.
      3. Rate: publishing rate of the clock.
      4. Step button: advance the clock by the specified time step.
      5. Time step: value used to advance the clock when pressing the step button d).
      6. Time unit: time unit associated with the value from e).

      Warning If you set the time step too large, your simulation will go haywire.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/","title":"tier4_string_viewer_rviz_plugin","text":""},{"location":"common/tier4_string_viewer_rviz_plugin/#tier4_string_viewer_rviz_plugin","title":"tier4_string_viewer_rviz_plugin","text":""},{"location":"common/tier4_string_viewer_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin displays the ROS message whose topic type is autoware_internal_debug_msgs::msg::StringStamped in rviz.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    TBD.

    "},{"location":"common/tier4_string_viewer_rviz_plugin/#usage","title":"Usage","text":"
    1. Start rviz and select panels/Add new panel.
    2. Select tier4_string_viewer_rviz_plugin/StringViewerPanel and press OK.
    "},{"location":"common/tier4_target_object_type_rviz_plugin/","title":"tier4_target_object_type_rviz_plugin","text":""},{"location":"common/tier4_target_object_type_rviz_plugin/#tier4_target_object_type_rviz_plugin","title":"tier4_target_object_type_rviz_plugin","text":"

    This plugin allows you to check which types of the dynamic object is being used by each planner.

    "},{"location":"common/tier4_target_object_type_rviz_plugin/#limitations","title":"Limitations","text":"

    Currently, which parameters of which module to check are hardcoded. In the future, this will be parameterized using YAML.

    "},{"location":"control/stop_accel_evaluator/","title":"Stop Accel Evaluator","text":""},{"location":"control/stop_accel_evaluator/#stop-accel-evaluator","title":"Stop Accel Evaluator","text":"

    The role of this node is to evaluate how smooth it is when a vehicle stops by calculating vehicle acceleration just before stopping.

    "},{"location":"control/stop_accel_evaluator/#how-to-use","title":"How to use","text":"
    ros2 launch stop_accel_evaluator stop_accel_evaluator.launch.xml\n

    Then you can see stop_accel_evaluator/stop_accel topic. This topic is published only when a vehicle stops.

    "},{"location":"control/vehicle_cmd_analyzer/","title":"Vehicle Command Analyzer description","text":""},{"location":"control/vehicle_cmd_analyzer/#vehicle-command-analyzer-description","title":"Vehicle Command Analyzer description","text":""},{"location":"control/vehicle_cmd_analyzer/#overview","title":"Overview","text":"

    This is a visualization tool for vehicle commands. You need plotjuggler to plot.

    The following time series data will be plotted on the left side.

    • Velocity
    • Acceleration (acceleration and derivative of velocity)
    • Jerk (derivative of acceleration and second derivative of velocity)
    • Lateral acceleration

    The following data will be plotted on the right side.

    • XY plot of jerk-acceleration

    "},{"location":"control/vehicle_cmd_analyzer/#how-to-use","title":"How to use","text":"
    1. Launch the node.

      ros2 launch vehicle_cmd_analyzer vehicle_cmd_analyzer.launch.xml vehicle_model:=lexus\n
    2. Launch plotjuggler.

      ros2 run plotjuggler plotjuggler\n
    3. Load layout.xml from File->Layout.

    4. Press ok in the confirmation dialog.
    5. Select/vehicle_cmd_analyzer/debug_values.
    "},{"location":"control_data_collecting_tool/","title":"Control data collecting tool","text":""},{"location":"control_data_collecting_tool/#control-data-collecting-tool","title":"Control data collecting tool","text":"

    This package provides tools for automatically collecting data using pure pursuit control within a specified rectangular area.

    "},{"location":"control_data_collecting_tool/#overview","title":"Overview","text":"
    • This package aims to collect a dataset consisting of control inputs (i.e. control_cmd) and observation variables (i.e. kinematic_state, steering_status, etc).
    • The collected dataset can be used as training dataset for learning-based controllers, including smart_mpc.
    • Data collecting approach is as follows:

      • Following the trajectory using a pure pursuit control law.
      • Adding noises to the trajectory and the control command for data diversity, improving the prediction accuracy of learning model.
      • Setting the trajectory from the following types of trajectories ( [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle, along_road] ).

        • COURSE_NAME: eight_course

        • COURSE_NAME: u_shaped_return

        • COURSE_NAME: straight_line_positive or COURSE_NAME: straight_line_negative

          ( Both \"straight_line_positive\" and \"straight_line_negative\" represent straight line courses, but the direction of travel of the course is reversed.)

        • COURSE_NAME: reversal_loop_circle

          Drive within a circle while adding trajectories and collect data.

        • COURSE_NAME: along_road

          Generate trajectories along the road. This is particularly useful when drawing long straight paths along the road.

          In this course, data collection is conducted only on long straight trajectories, while constant velocity, velocity_on_curve, is maintained when driving on sections that include curves.

          The minimum length of these long straight trajectories can be specified using the parameter minimum_length_of_straight_line (These two parameters velocity_on_curve and minimum_length_of_straight_line can be configured in ./config/course_param/along_road_param.yaml).

    "},{"location":"control_data_collecting_tool/#how-to-use","title":"How to Use","text":"
    1. Launch Autoware.

      ros2 launch autoware_launch planning_simulator.launch.xml map_path:=$HOME/autoware_map/sample-map-planning vehicle_model:=sample_vehicle sensor_model:=sample_sensor_kit\n
    2. Set an initial pose, see here.

    3. Add the DataCollectingAreaSelectionTool and DataCollectingGoalPlugin RViz plugins by clicking the \"+\" icon at the top of the RViz window.

    4. Launch control_data_collecting_tool.

      ros2 launch control_data_collecting_tool control_data_collecting_tool.launch.py map_path:=$HOME/autoware_map/sample-map-planning\n

      - If you use the along_road course, please specify the same map for map_path as the one used when launching Autoware. map_path is not necessary when using courses other than along_road.

      - Control data collecting tool automatically records topics included in config/topics.yaml when the above command is executed. Topics will be saved in rosbag2 format in the current directory.

      - The data from /localization/kinematic_state and /localization/acceleration located in the directory (rosbag2 format) where the command is executed will be automatically loaded and reflected in the data count for these topics. (If LOAD_ROSBAG2_FILES in config/param.yaml is set to false, the data is not loaded.)

    5. Add visualization in rviz:

      - /data_collecting_area - Type: Polygon - /data_collecting_trajectory_marker_array - Type: MarkerArray - /data_collecting_lookahead_marker_array - Type: MarkerArray

    6. The following actions differ depending on the selected course. If you select the trajectory from [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle], please proceed to 6.1. If you select the trajectory from [along_road], please proceed to 6.2.

      - 6.1 If you choose the trajectory from [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle], select DataCollectingAreaSelectionTool plugin.

      <img src=\"resource/DataCollectingAreaSelection.png\" width=\"480\">\n\nHighlight the data collecting area by dragging the mouse over it.\n\n<img src=\"resource/select_area.gif\" width=\"480\">\n\n> [!NOTE]\n> You cannot change the data collecting area while driving.\n

      - 6.2 If you choose the trajectory from [along_road], select DataCollectingGoalPose plugin.

        <img src=\"resource/DataCollectingGoalPose.png\" width=\"480\">\n\nBy setting the pose of the goal point, a trajectory is generated on the map.\n\n  <img src=\"resource/set_trajectory_along_road.gif\" width=\"480\">\n\nAs soon as the trajectory is generated, the plot with the map and trajectory drawn on it will be created (please see the following picture).\nIn the sections labeled `velocity = const (velocity_on_curve)` in the legend, the vehicle travels at a constant velocity of `velocity_on_curve`. In the sections labeled `Data collection is conducted`, data collection is performed.\n\n  <img src=\"resource/along_load_plot.png\" width=\"480\">\n\n> [!NOTE]\n> You cannot change the goal pose while driving.\n> In cases where course generation fails, which can happen under certain conditions, please reposition the vehicle or redraw the goal pose.\n
    7. Click the LOCAL button in AutowareStatePanel.

      Then, data collecting starts.

      You can monitor the data collection status in real-time through the window that pops up when this node is launched. (From top to bottom: the speed-acceleration phase diagram, the speed-acceleration heatmap, the speed-steering angle heatmap, the speed-steer rate heatmap, and the speed-jerk heatmap.)

      For the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap, the collection range can be specified by the masks located in the folder config/masks/MASK_NAME where MASK_NAME is a parameter specifying mask name (Please also see config/common_param.yaml). The specified heatmap cells are designed to change from blue to green once a certain amount of data (VEL_ACC_THRESHOLD, VEL_STEER_THRESHOLD, VEL_ABS_STEER_RATE_THRESHOLD ) is collected. It is recommended to collect data until as many cells as possible turn green.

    8. If you want to stop data collecting automatic driving, run the following command

      ros2 topic pub /data_collecting_stop_request std_msgs/msg/Bool \"data: true\" --once\n

      [!NOTE] When the car crosses the green boundary line, a similar stopping procedure will be automatically triggered.

    9. If you want to restart data collecting automatic driving, run the following command

      ros2 topic pub /data_collecting_stop_request std_msgs/msg/Bool \"data: false\" --once\n
    "},{"location":"control_data_collecting_tool/#specify-data-collection-range","title":"Specify data collection range","text":"

    You can create an original mask to specify the data collection range for the heatmap explained in step 7 of the \"How to Use\" section.

    1. Change the MASK_NAME parameter in config/common_param.yaml from its default value of default to any name you prefer.

    2. Modify parameters such as VEL_ACC_THRESHOLD, VEL_STEER_THRESHOLD, and VEL_ABS_STEER_RATE_THRESHOLD to determine the desired amount of data for each cell in the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap.

    3. In the scripts/masks directory, run

      python3 mask_selector.py\n

      then, matplotlib windows for selecting the collection range of the speed-acceleration heatmap, speed-steering angle heatmap, and speed-steer rate heatmap will be displayed, one for each.

      In these windows, you can modify the heatmaps by clicking or dragging within them. Once you've made your changes, pressing Ctrl+C in the terminal will automatically save the updated maps.

      Afterward, rebuild the control_data_collecting_tool using the following command

      colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=\"-w\" --symlink-install --continue-on-error --packages-up-to control_data_collecting_tool\n

      and relaunch the control_data_collecting_tool with

      ros2 launch control_data_collecting_tool control_data_collecting_tool.launch.py map_path:=$HOME/autoware_map/sample-map-planning\n

      This will allow you to see the selected mask applied.

    "},{"location":"control_data_collecting_tool/#trajectory-generation-and-data-collection-logic","title":"Trajectory generation and data collection logic","text":""},{"location":"control_data_collecting_tool/#data-collection-logic-common-to-all-courses","title":"Data collection logic common to all courses","text":"

    In control_data_collection_tool, all courses collect velocity and acceleration data in a similar manner.

    By appropriately adjusting the target_velocity provided to the pure pursuit algorithm, speed and acceleration data are efficiently collected. Data collection consists of four phases: selection of target speed and acceleration, acceleration phase, constant speed phase, the deceleration phase. A general method for collecting speed and acceleration data is described below, though it does not strictly adhere to the outlined steps.

    1. Selection of target speed and acceleration

      In the speed-acceleration heatmap, the speed and acceleration with fewer data points are set as the target speed and acceleration, which are then defined here as target_velocity_on_section and target_acceleration_on_section.

    2. Acceleration phase The vehicle accelerates by setting target_velocity as follows until its speed exceeds target_velocity_on_section.

        # sine_curve is derived from appropriate amplitude and period, defined separately\n  target_velocity = current_velocity + abs(target_acceleration_on_section) / acc_kp + sine_curve\n

      current_velocity is a current velocity of vehicle and acc_kp accel command proportional gain in pure pursuit algorithm. sine_curve is a sine wave added to partially mitigate situations where the vehicle fails to achieve the target acceleration.

    3. Constant speed phase When the vehicle reaches target_velocity_on_section, target_velocity is defined as follows to allow the vehicle to run around the target speed for a certain period of time.

        # sine_curve is derived from appropriate amplitude and period, defined separately\n  target_velocity = target_velocity_on_section + sine_curve + sine_curve\n
    4. Deceleration phase In the deceleration phase, similar to the acceleration phase, target_velocity is defined as follows to ensure the vehicle decelerates.

        # sine_curve is derived from appropriate amplitude and period, defined separately\n  target_velocity = current_velocity - abs(target_acceleration_on_section) / acc_kp + sine_curve\n

      After decelerating to a sufficiently low speed, return to step i.

    "},{"location":"control_data_collecting_tool/#trajectory-generation-and-data-collection-logic-specific-to-reversal_loop_circle","title":"Trajectory generation and data collection logic specific to reversal_loop_circle","text":"

    In the reversal_loop_circle course, sections are sequentially added to the course while collecting various data on speed, acceleration, and steering angle.

    "},{"location":"control_data_collecting_tool/#trajectory-generation-logic-for-reversal_loop_circle","title":"Trajectory generation logic for reversal_loop_circle","text":"

    The reversal_loop_circle aims to generate a trajectory with the largest possible radius of curvature within a radius trajectory_radius, allowing data collection in a confined area without significantly reducing speed.

    The reversal_loop_circle is primarily generated by connecting the following three components, common tangent, circumscribing_circle and boundary as shown in the following picture.

    All the components listed below are available in both clockwise and counterclockwise versions. The rationale for having two versions is to ensure data collection for both right-hand drive and left-hand drive configurations.

    • common tangent

      The common tangent is generated by drawing a common tangent to two inscribed circles. In this section, a sine curve is added in the normal direction to generate a trajectory for collecting data with larger steering angles. The amplitude of the sine curve is determined based on the desired steering angle data.

    • circumscribing_circle

      The circumscribing_circle part is created by drawing the common circumscribed circle of the circles. This section is generated to achieve nearly straight movement within the outer circle while minimizing the increase in curvature.

    • boundary

      The boundary part is used to connect the common tangent and the circumscribing_circle sections.

    "},{"location":"control_data_collecting_tool/#velocity-and-steering-angle-data-collection-logic-for-reversal_loop_circle","title":"Velocity and steering angle data collection logic for reversal_loop_circle","text":"

    Speed and steering angle data are gathered in the common tangent section of the trajectory. The common tangent section is particularly effective for collecting steering angle data because a trajectory with minimal data is intentionally created by adding a sine wave of suitable amplitude to the curvature.

    The following two steps are taken to obtain steering angle data.

    1. Starting from the ego vehicle's current position, the system examines a segment of the trajectory ahead, covering a distance defined by looking_ahead_distance, to identify the point of maximum curvature.

    2. This maximum curvature determines the steering angle the vehicle will use. The vehicle then adjusts its speed toward the speed associated with the sparsest steering angle data.

    "},{"location":"control_data_collecting_tool/#parameter","title":"Parameter","text":"

    There are parameters that are common to all trajectories and parameters that are specific to each trajectory.

    "},{"location":"control_data_collecting_tool/#common-parameters","title":"Common Parameters","text":"

    ROS 2 parameters which are common in all trajectories (/config/common_param.yaml):

    Name Type Description Default value LOAD_ROSBAG2_FILES bool Flag that determines whether to load rosbag2 data or not true COURSE_NAME string Course name [eight_course, u_shaped_return, straight_line_positive, straight_line_negative, reversal_loop_circle, along_road] reversal_loop_circle NUM_BINS_V int Number of bins of velocity in heatmap 10 NUM_BINS_STEER int Number of bins of steer in heatmap 20 NUM_BINS_A int Number of bins of acceleration in heatmap 10 NUM_BINS_ABS_STEER_RATE int Number of bins of absolute value of steer rate in heatmap 5 NUM_BINS_JERK int Number of bins of jerk in heatmap 10 V_MIN double Minimum velocity in heatmap [m/s] 0.0 V_MAX double Maximum velocity in heatmap [m/s] 11.5 STEER_MIN double Minimum steer in heatmap [rad] -0.6 STEER_MAX double Maximum steer in heatmap [rad] 0.6 A_MIN double Minimum acceleration in heatmap [m/s^2] -1.0 A_MAX double Maximum acceleration in heatmap [m/s^2] 1.0 max_lateral_accel double Max lateral acceleration limit [m/s^2] 2.70 ABS_STEER_RATE_MIN double Minimum absolute value of steer rate in heatmap [rad/s] 0.0 ABS_STEER_RATE_MAX double Maximum absolute value of steer rate in heatmap [rad/s] 0.3 JERK_MIN double Minimum jerk in heatmap [m/s^3] -0.5 JERK_MAX double Maximum jerk in heatmap [m/s^3] 0.5 MASK_NAME string Directory name of masks for data collection default VEL_ACC_THRESHOLD int Threshold of velocity-and-acc heatmap in data collection 40 VEL_STEER_THRESHOLD int Threshold of velocity-and-steer heatmap in data collection 20 VEL_ABS_STEER_RATE_THRESHOLD int Threshold of velocity-and-abs_steer_rate heatmap in data collection 20 max_lateral_accel double Max lateral acceleration limit [m/s^2] 2.00 lateral_error_threshold double Lateral error threshold where applying velocity limit [m] 1.50 yaw_error_threshold double Yaw error threshold where applying velocity limit [rad] 0.75 velocity_limit_by_tracking_error double Velocity limit applied when tracking error exceeds threshold [m/s] 1.0 mov_ave_window int Moving average smoothing window size 50 target_longitudinal_velocity double Target longitudinal velocity [m/s] 6.0 pure_pursuit_type string Pure pursuit type (naive or linearized steer control law ) linearized wheel_base double Wheel base [m] 2.79 acc_kp double Accel command proportional gain 1.0 lookahead_time double Pure pursuit lookahead time [s] 2.0 min_lookahead double Pure pursuit minimum lookahead length [m] 2.0 linearized_pure_pursuit_steer_kp_param double Linearized pure pursuit steering P gain parameter 2.0 linearized_pure_pursuit_steer_kd_param double Linearized pure pursuit steering D gain parameter 2.0 stop_acc double Accel command for stopping data collecting driving [m/s^2] -2.0 stop_jerk_lim double Jerk limit for stopping data collecting driving [m/s^3] 5.0 lon_acc_lim double Longitudinal acceleration limit [m/s^2] 1.5 lon_jerk_lim double Longitudinal jerk limit [m/s^3] 0.5 steer_lim double Steering angle limit [rad] 0.6 steer_rate_lim double Steering angle rate limit [rad/s] 0.6

    The following parameters are common to all trajectories but can be defined individually for each trajectory. (/config/course_param/COURSE_NAME_param.yaml):

    Name Type Description Default value COLLECTING_DATA_V_MIN double Minimum velocity for data collection [m/s] 0.5 COLLECTING_DATA_V_MAX double Maximum velocity for data collection [m/s] 8.0 COLLECTING_DATA_A_MIN double Minimum velocity for data collection [m/s^2] 1.0 COLLECTING_DATA_A_MAX double Maximum velocity for data collection [m/s^2] -1.0 longitudinal_velocity_noise_amp double Target longitudinal velocity additional sine noise amplitude [m/s] 0.01 longitudinal_velocity_noise_min_period double Target longitudinal velocity additional sine noise minimum period [s] 5.0 longitudinal_velocity_noise_max_period double Target longitudinal velocity additional sine noise maximum period [s] 20.0 acc_noise_amp double Accel command additional sine noise amplitude [m/ss] 0.01 acc_noise_min_period double Accel command additional sine noise minimum period [s] 5.0 acc_noise_max_period double Accel command additional sine noise maximum period [s] 20.0 steer_noise_amp double Steer command additional sine noise amplitude [rad] 0.01 steer_noise_max_period double Steer command additional sine noise maximum period [s] 5.0 steer_noise_min_period double Steer command additional sine noise minimum period [s] 20.0"},{"location":"control_data_collecting_tool/#course-specific-parameters","title":"Course-Specific Parameters","text":"

    Each trajectory has specific ROS 2 parameters.

    • COURSE_NAME: eight_course
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 4.5 smoothing_window double Width of the window for trajectory smoothing 400
    • COURSE_NAME: u_shaped_return
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 4.5
    • COURSE_NAME: straight_line_positive or COURSE_NAME: straight_line_negative
    Name Type Description Default value stopping_buffer_distance double The safety distance from end of the straight line [m] 10.0
    • COURSE_NAME: reversal_loop_circle
    Name Type Description Default value trajectory_radius double Radius of the circle where trajectories are generated [m] 35.0 enclosing_radius double Radius of the circle enclosing the generated trajectories [m] 40.0 look_ahead_distance double The distance referenced ahead of the vehicle for collecting steering angle data [m] 35.0
    • COURSE_NAME: along_road
    Name Type Description Default value velocity_on_curve double Constant velocity on curve [m/s] 3.5 stopping_buffer_distance double The safety distance from end of the straight line [m] 15.0 course_width double The width of the trajectory [m] 1.5 smoothing_window double Width of the window for trajectory smoothing 100 minimum_length_of_straight_line double The minimum length of straight line for data collection [m] 50.0 longitude double The longitude of the origin specified when loading the map [degree] 139.6503 latitude double The latitude of the origin specified when loading the map [degree] 35.6762"},{"location":"driving_environment_analyzer/","title":"Driving Environment Analyzer","text":""},{"location":"driving_environment_analyzer/#driving-environment-analyzer","title":"Driving Environment Analyzer","text":"

    \u3053\u306e\u30c4\u30fc\u30eb\u306fROSBAG\u306b\u542b\u307e\u308c\u308b\u8d70\u884c\u5c65\u6b74\u3092\u5143\u306b\u8d70\u884c\u74b0\u5883\u306eODD\u3092\u89e3\u6790\u3059\u308b\u30c4\u30fc\u30eb\u3067\u3059\u3002

    "},{"location":"driving_environment_analyzer/#rosbagodd","title":"ROSBAG\u306e\u7279\u5b9a\u6642\u523b\u306b\u304a\u3051\u308b\u5468\u56f2\u306eODD\u3092\u89e3\u6790\u3059\u308b\u5834\u5408","text":"

    \u3053\u306e\u5834\u5408\u306b\u306fRviz\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3042\u308bdriving_environment_analyzer_rviz_panel\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u3092\u304a\u3059\u3059\u3081\u3057\u307e\u3059\u3002

    \u73fe\u5728\u4ee5\u4e0b\u306e\u60c5\u5831\u304c\u51fa\u529b\u53ef\u80fd\u3067\u3059\u3002

    • EGO\u306e\u73fe\u5728\u8eca\u901f
    • \u73fe\u5728\u4f4d\u7f6e\u306e\u52fe\u914d
    • EGO\u306e\u6319\u52d5
    • \u73fe\u5728\u306e\u8eca\u7dda\u60c5\u5831

    \u3053\u3061\u3089\u306e\u30c4\u30fc\u30eb\u306fautoware_launch\u306b\u542b\u307e\u308c\u308blogging_simulator\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002\u307e\u305a\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u304b\u3089\u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u3092\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    ros2 launch autoware_launch logging_simulator.launch.xml map_path:=<MAP> vehicle_model:=<VEHICLE_NAME> sensor_model:=<AIP_NAME> sensing:=false control:=false planning:=false perception:=false localization:=false system:=false

    \u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u8d77\u52d5\u6642\u306b\u5730\u56f3\u3092\u8aad\u307f\u8fbc\u3080\u305f\u3081ROSBAG\u306b\u5730\u56f3\u60c5\u5831\u304c\u542b\u307e\u308c\u3066\u3044\u306a\u304f\u3066\u3082ODD\u306e\u89e3\u6790\u304c\u53ef\u80fd\u3067\u3059\u3002\uff08\u305f\u3060\u3057\u3001\u305d\u306e\u5834\u5408\u306b\u306fROSBAG\u53d6\u5f97\u306e\u969b\u306b\u4f7f\u7528\u3057\u305f\u5730\u56f3\u3092\u6307\u5b9a\u3057\u3066\u30b7\u30df\u30e5\u30ec\u30fc\u30bf\u3092\u8d77\u52d5\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\uff09

    \u6b21\u306b\u672c\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u542b\u307e\u308c\u308b\u89e3\u6790\u30c4\u30fc\u30eb\u3092\u8d77\u52d5\u3057\u307e\u3059\u3002Rviz\u753b\u9762\u5de6\u4e0a\u90e8\u306eAdd New Panel\u304b\u3089DrivingEnvironmentAnalyzerPanel\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u3053\u308c\u3067Rviz\u5de6\u4e0b\u306b\u65b0\u3057\u304f\u64cd\u4f5c\u30d1\u30cd\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u307e\u3059\u3002

    \u672c\u30c4\u30fc\u30eb\u306fROSBAG\u30d5\u30a1\u30a4\u30eb\u6307\u5b9a\u3057\u3066\u30ed\u30fc\u30c9\u3067\u304d\u308b\u4ed6\u3001\u8907\u6570\u306eROSBAG\u30d5\u30a1\u30a4\u30eb\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u308b\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\u305f\u3060\u3057\u3001\u305d\u306e\u5834\u5408\u306b\u306f\u4e8b\u524d\u306b\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3067metadata.yaml\u306e\u751f\u6210\u304c\u5fc5\u8981\u306b\u306a\u308a\u307e\u3059\u3002

    ros2 bag reindex <DIR_PATH> sqlite3

    ROSBAG\u306e\u8aad\u307f\u8fbc\u307f\u304c\u5b8c\u4e86\u3057\u305f\u3089ODD\u3092\u89e3\u6790\u3057\u305f\u3044\u6642\u523b\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002\u6642\u523b\u306e\u6307\u5b9a\u306b\u306fUnix time\u3092\u76f4\u63a5\u6307\u5b9a\u3059\u308b\u307b\u304b\u30b9\u30e9\u30a4\u30c9\u30d0\u30fc\u3082\u4f7f\u7528\u53ef\u80fd\u3067\u3059\u3002\u5de6\u306b\u8868\u793a\u3055\u308c\u3066\u3044\u308b\u65e5\u6642\u3092\u53c2\u8003\u306b\u8abf\u6574\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    \u307e\u305f\u3001\u3053\u306e\u3068\u304dViews\u306eTarget Flame\u3092base_link\u306b\u3057\u3066\u304a\u304f\u3053\u3068\u3067\u3001\u6307\u5b9a\u3057\u305f\u6642\u523b\u306eEGO\u306e\u4f4d\u7f6e\u3068\u5468\u56f2\u306e\u72b6\u6cc1\u3092Rviz\u3067\u53ef\u8996\u5316\u53ef\u80fd\u3067\u3059\u3002

    \u6642\u523b\u306e\u6307\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001Set time stamp\u30dc\u30bf\u30f3\u3092\u62bc\u3057\u3001\u6700\u5f8c\u306bAnalyze dynamic ODD factor\u3092\u62bc\u3059\u3053\u3068\u3067\u89e3\u6790\u304c\u59cb\u307e\u308a\u307e\u3059\u3002

    [rviz2-11] ***********************************************************\n[rviz2-11]                    ODD analysis result\n[rviz2-11] ***********************************************************\n[rviz2-11] Type: TIME SPECIFIED\n[rviz2-11] Time: 2024-04-22 14:48:05\n[rviz2-11]\n[rviz2-11]\n[rviz2-11] - EGO INFO\n[rviz2-11]   [SPEED]                       : 0 [m/s]\n[rviz2-11]   [ELEVATION ANGLE]             : 0.00963597 [rad]\n[rviz2-11]\n[rviz2-11] - EGO BEHAIOVR\n[rviz2-11]   [AVOIDANCE(R)]                : NONE\n[rviz2-11]   [AVOIDANCE(L)]                : NONE\n[rviz2-11]   [LANE_CHANGE(R)]              : NONE\n[rviz2-11]   [LANE_CHANGE(L)]              : NONE\n[rviz2-11]   [START_PLANNER]               : SAFE: true COMMAND: deactivate\n[rviz2-11]   [GOAL_PLANNER]                : NONE\n[rviz2-11]   [CROSSWALK]                   : NONE\n[rviz2-11]   [INTERSECTION]                : NONE\n[rviz2-11]\n[rviz2-11] - LANE INFO\n[rviz2-11]   [ID]                          : 176126\n[rviz2-11]   [WIDTH]                       : 4.24132 [m]\n[rviz2-11]   [SHAPE]                       : STRAIGHT\n[rviz2-11]   [RIGHT LANE NUM]              : 0\n[rviz2-11]   [LEFT LANE NUM]               : 0\n[rviz2-11]   [TOTAL LANE NUM]              : 1\n[rviz2-11]   [SAME DIRECTION LANE]         : NONE\n[rviz2-11]   [OPPOSITE DIRECTION LANE]     : NONE\n[rviz2-11]   [ROAD SHOULDER]               : EXIST\n[rviz2-11]\n[rviz2-11] - SURROUND OBJECT NUM\n[rviz2-11]   [UNKNOWN]                     : 0\n[rviz2-11]   [CAR]                         : 6\n[rviz2-11]   [TRUCK]                       : 0\n[rviz2-11]   [BUS]                         : 3\n[rviz2-11]   [TRAILER]                     : 2\n[rviz2-11]   [MOTORCYCLE]                  : 0\n[rviz2-11]   [BICYCLE]                     : 0\n[rviz2-11]   [PEDESTRIAN]                  : 7\n[rviz2-11] ***********************************************************\n
    "},{"location":"driving_environment_analyzer/#rosbagodd_1","title":"ROSBAG\u5168\u4f53\u306b\u5bfe\u3057\u3066\u7d4c\u8def\u6cbf\u3044\u306eODD\u3092\u89e3\u6790\u3059\u308b\u5834\u5408","text":"

    \u73fe\u5728\u4ee5\u4e0b\u306e\u60c5\u5831\u304c\u51fa\u529b\u53ef\u80fd\u3067\u3059\u3002

    • \u8d70\u884c\u7d4c\u8def\u306e\u9577\u3055
    • \u8d70\u884c\u7d4c\u8def\u306e\u8eca\u7dda\u60c5\u5831
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u30fb\u6700\u5c0f\u52fe\u914d
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u66f2\u7387
    • \u8d70\u884c\u7d4c\u8def\u306e\u6700\u5927\u30fb\u6700\u5c0f\u8eca\u7dda\u5e45
    • \u4ea4\u5dee\u70b9\u306e\u6709\u7121
    • \u4fe1\u53f7\u6a5f\u306e\u6709\u7121
    • \u6a2a\u65ad\u6b69\u9053\u306e\u6709\u7121

    \u8d77\u52d5\u6642\u306bbag_path\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u89e3\u6790\u3057\u305f\u3044ROSBAG\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002\uff08\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u6307\u5b9a\u3082.db3\u30d5\u30a1\u30a4\u30eb\u306e\u76f4\u63a5\u6307\u5b9a\u3082\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u3059\u3002\uff09

    \u89e3\u6790\u306b\u5fc5\u8981\u306atopic\u306f\u4ee5\u4e0b\u306e\u3068\u304a\u308a\u3067\u3059\u3002\uff08\u4eca\u5f8c\u5897\u3048\u308b\u53ef\u80fd\u6027\u3082\u3042\u308a\u307e\u3059\u3002\uff09

    • /planning/mission_planning/route
    • /map/vector_map

    \u4ee5\u4e0b\u306e\u3088\u3046\u306blaunch\u3059\u308b\u3053\u3068\u3067ODD\u306e\u89e3\u6790\u7d50\u679c\u304c\u5f97\u3089\u308c\u307e\u3059\u3002

    ros2 launch driving_environment_analyzer driving_environment_analyzer.launch.xml use_map_in_bag:=true bag_path:=<ROSBAG>

    [component_container-1] [INFO 1708999777.768870564] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.768922452] [driving_environment_analyzer]:  data is ready. start ODD analysis...\n[component_container-1] [INFO 1708999777.768933574] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.768967412] [driving_environment_analyzer]: - Length of total lanes : 2357.50 [m]\n[component_container-1] [INFO 1708999777.769031174] [driving_environment_analyzer]: - Length of lane that has adjacent lane : 2080.43 [m]\n[component_container-1] [INFO 1708999777.769076141] [driving_environment_analyzer]: - Length of lane that has opposite lane : 0.00 [m]\n[component_container-1] [INFO 1708999777.769101793] [driving_environment_analyzer]: - Length of lane that has no adjacent lane : 277.07 [m]\n[component_container-1] [INFO 1708999777.769225729] [driving_environment_analyzer]: - Min lane width: 3.14 [m] Max lane width: 4.94 [m]\n[component_container-1] [INFO 1708999777.769278698] [driving_environment_analyzer]: - Max curvature: 0.007967 [1/m]\n[component_container-1] [INFO 1708999777.769293161] [driving_environment_analyzer]: - Min curve radius: 125.52 [m]\n[component_container-1] [INFO 1708999777.769336094] [driving_environment_analyzer]: - Min elevation angle: -0.033037 [rad] Max elevation angle: 0.026073 [rad]\n[component_container-1] [INFO 1708999777.769403870] [driving_environment_analyzer]: - Min speed limit: 13.89 [m/s] Max speed limit: 16.67 [m/s]\n[component_container-1] [INFO 1708999777.769424648] [driving_environment_analyzer]: - Exist traffic light: true\n[component_container-1] [INFO 1708999777.769435813] [driving_environment_analyzer]: - Exist intersection: true\n[component_container-1] [INFO 1708999777.769620035] [driving_environment_analyzer]: - Exist crosswalk: true\n[component_container-1] [INFO 1708999777.769634980] [driving_environment_analyzer]: ======================================\n[component_container-1] [INFO 1708999777.769642769] [driving_environment_analyzer]:  complete ODD analysis. shutdown.\n[component_container-1] [INFO 1708999777.769650034] [driving_environment_analyzer]: ======================================\n

    \u305f\u3060\u3057\u3001map/vector_map\u306b\u95a2\u3057\u3066\u306fuse_map_in_bag\u3092false\u306b\u3059\u308b\u3053\u3068\u3067\u30ed\u30fc\u30ab\u30eb\u74b0\u5883\u306b\u4fdd\u5b58\u3055\u308c\u3066\u3044\u308b\u5730\u56f3\u3092\u4f7f\u7528\u3057\u3066ODD\u89e3\u6790\u3092\u884c\u3046\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\u305d\u306e\u5834\u5408\u3001map_path\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u5730\u56f3\u306e\u30d1\u30b9\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002

    ros2 launch driving_environment_analyzer driving_environment_analyzer.launch.xml use_map_in_bag:=false map_path:=<MAP> bag_path:=<ROSBAG>

    \u4ee5\u4e0a\u306e\u3088\u3046\u306b\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3067ROSBAG\u306b\u5730\u56f3\u60c5\u5831\u304c\u4fdd\u5b58\u3055\u308c\u3066\u3044\u306a\u304f\u3066\u3082ODD\u89e3\u6790\u304c\u53ef\u80fd\u3067\u3059\u3002

    "},{"location":"evaluation/tier4_metrics_rviz_plugin/","title":"tier4_metrics_rviz_plugin","text":""},{"location":"evaluation/tier4_metrics_rviz_plugin/#tier4_metrics_rviz_plugin","title":"tier4_metrics_rviz_plugin","text":""},{"location":"evaluation/tier4_metrics_rviz_plugin/#purpose","title":"Purpose","text":"

    This plugin panel to visualize planning_evaluator output.

    "},{"location":"evaluation/tier4_metrics_rviz_plugin/#inputs-outputs","title":"Inputs / Outputs","text":"Name Type Description /planning/planning_evaluator/metrics diagnostic_msgs::msg::DiagnosticArray Subscribe planning_evaluator output"},{"location":"evaluation/tier4_metrics_rviz_plugin/#howtouse","title":"HowToUse","text":"
    1. Start rviz and select panels/Add new panel.
    2. Select MetricsVisualizePanel and press OK.
    "},{"location":"localization/deviation_estimation_tools/ReadMe/","title":"deviation_estimation_tools","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#deviation_estimation_tools","title":"deviation_estimation_tools","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#1-quick-start","title":"1. Quick start","text":"

    This repository consists of three main tools implemented on ROS 2.

    1. Deviation Estimator
    2. Deviation Evaluator
    3. Deviation Evaluation Visualizer
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#a-estimation-step","title":"A. Estimation step","text":"

    Here you estimate the following parameters using deviation_estimator.

    • the standard deviation of velocity and yaw rate
    • the bias of velocity and yaw rate

    Launch the node with the following command. Make sure you set the correct parameters (see Sec. 2).

    ros2 launch deviation_estimator deviation_estimator.launch.xml\n

    Then, you need to run either ROS bag or autoware_launch to provide pose and twist to deviation_estimator.

    If you are using rosbag, it should contain the following topics:

    • Raw IMU data (default: /sensing/imu/tamagawa/imu_raw)
    • Raw velocity data (default: /vehicle/status/velocity_status)
    • /localization/pose_estimator/pose_with_covariance
    • /clock
    • /tf_static (that contains transform from base_link to imu_link)

    NOTE that the pose and twist must be estimated with default parameters (see known issues section for detail).

    Play the rosbag in a different terminal:

    ros2 bag play YOUR_BAG # You can also play in a faster rate, e.g. -r 5\n

    You can check the results in the following three output files:

    1. IMU parameters (default: $HOME/imu_corrector.param.yaml)
    2. Velocity parameters (default: $HOME/vehicle_velocity_converter.param.yaml)
    3. Logs (default: $HOME/output.txt)
    sample input (rosbag)

    Files:             localized_sensors_0.db3\nBag size:          9.6 MiB\nStorage id:        sqlite3\nDuration:          76.539s\nStart:             Jul  8 2022 11:21:41.220 (1657246901.220)\nEnd:               Jul  8 2022 11:22:57.759 (1657246977.759)\nMessages:          32855\nTopic information: Topic: /localization/pose_estimator/pose_with_covariance | Type: geometry_msgs/msg/PoseWithCovarianceStamped | Count: 2162 | Serialization Format: cdr\n                   Topic: /clock | Type: rosgraph_msgs/msg/Clock | Count: 57309 | Serialization Format: cdr\n                   Topic: /tf_static | Type: tf2_msgs/msg/TFMessage | Count: 2 | Serialization Format: cdr\n                   Topic: /sensing/imu/tamagawa/imu_raw | Type: sensor_msgs/msg/Imu | Count: 8076 | Serialization Format: cdr\n                   Topic: /vehicle/status/velocity_status | Type: autoware_vehicle_msgs/msg/VelocityReport | Count: 8275 | Serialization Format: cdr\n
    sample output (output.txt)

    # Validation results\n# value: [min, max]\n[OK] coef_vx: [0.99538, 0.99593]\n[OK] stddev_vx: [0.17192, 0.19161]\n[OK] angular_velocity_offset_x: [-0.00742, -0.00727]\n[OK] angular_velocity_offset_y: [-0.00119, -0.00115]\n[OK] angular_velocity_offset_z: [0.00635, 0.00641]\n[OK] angular_velocity_stddev_xx: [0.04151, 0.04258]\n[OK] angular_velocity_stddev_yy: [0.04151, 0.04258]\n[OK] angular_velocity_stddev_zz: [0.04151, 0.04258]\n
    sample output (imu_corrector.param.yaml)
    # Estimated by deviation_estimator\n/**:\n  ros__parameters:\n    angular_velocity_stddev_xx: 0.01798\n    angular_velocity_stddev_yy: 0.01798\n    angular_velocity_stddev_zz: 0.01798\n    angular_velocity_offset_x: -0.00952\n    angular_velocity_offset_y: -0.00095\n    angular_velocity_offset_z: 0.00607\n

    sample output (vehicle_velocity_converter.param.yaml)
    # Estimated by deviation_estimator\n/**:\n  ros__parameters:\n    speed_scale_factor: 0.99507\n    velocity_stddev_xx: 0.16708\n    velocity_stddev_xx: 0.1 # Default value\nframe_id: base_link # Default value\n

    unit tool If you build normally, a binary will be generated under `install/deviation_estimator/lib/`.
    colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release --packages-up-to deviation_estimator\nsource ~/autoware/install/setup.bash\n~/autoware/install/deviation_estimator/lib/deviation_estimator/deviation_estimator_unit_tool <path_to_rosbag>\n

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#b-evaluation-step","title":"B. Evaluation step","text":"

    Here, you can evaluate the estimated standard deviation and bias using a package deviation_evaluator. Execute the following command:

    ros2 launch deviation_evaluator deviation_evaluator.launch.xml map_path:=MAP_PATH rviz:=true in_imu:=YOUR_IMU_TOPIC_NAME in_wheel_odometry:=YOUR_VELOCITY_TOPIC_NAME\nros2 bag play YOUR_BAG\n
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#c-visualization-step","title":"C. Visualization step","text":"

    After the evaluation, run the following command to generate the final results in $HOME/deviation_evaluator_sample.

    pip3 install -r requirements.txt\nros2 launch deviation_evaluator deviation_evaluation_visualizer.launch.xml\n

    Done!

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#2-description-of-deviation-estimator","title":"2. Description of Deviation Estimator","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#overview","title":"Overview","text":"

    The Deviation Estimator estimates the standard deviation and bias for velocity and yaw bias, by comparing the velocity and gyro observations with ground truth poses (e.g. from LiDAR-based localization).

    Here are some assumptions made for input data:

    • The data should have accurate localization results. It doesn't need to be strictly precise, but data that is obviously incorrect should be avoided. In case of NDT in Autoware, it should not have any TP or NVTL warnings from the ndt_scan_matcher.
    • The data should cover a reasonable duration of driving. A few minutes of data is sufficient. It is desirable to have a distance of approximately 500 meters. (For example, around 2 minutes at a speed of 15 km/h).
    • The data should include sections of driving in a straight line. This is necessary for estimating velocity-related parameters. Having at least one minute of straight line driving is enough.
    • The data should cover the expected speed range during operation.
    • [Optional] Ideally, the data should be recorded as recently as possible. Especially in cases where IMU or tire replacement has occurred, data recorded before those changes may not provide accurate estimations.
    • [Optional] The data should cover various driving behaviors expected during operation, such as right turns, left turns, acceleration, and deceleration.
    "},{"location":"localization/deviation_estimation_tools/ReadMe/#launch","title":"Launch","text":"

    The deviation_estimator can be launched with the following command.

    ros2 launch deviation_estimator deviation_estimator.launch.xml\nros2 bag play YOUR_BAG # You can also play in a faster rate, e.g. -r 5\n

    The parameters and input topic names can be seen in the deviation_estimator.launch.xml file. YOUR_BAG should include all the required inputs written below.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#input","title":"Input","text":"Name Type Description in_pose_with_covariance |geometry_msgs::msg::PoseWithCovarianceStamped` Input pose in_imu sensor_msgs::msg::Imu Input IMU data in_wheel_odometry autoware_vehicle_msgs::msg::VelocityReport Input wheel odometry"},{"location":"localization/deviation_estimation_tools/ReadMe/#output","title":"Output","text":"Name Type Description /estimated_stddev_vx std_msgs::msg::Float64 estimated standard deviation of vx /estimated_stddev_angular_velocity geometry_msgs/msg/Vector3 estimated standard deviation of angular velocity /estimated_coef_vx std_msgs::msg::Float64 coef of vx /estimated_bias_angular_velocity geometry_msgs/msg/Vector3 bias of angular velocity"},{"location":"localization/deviation_estimation_tools/ReadMe/#parameters-for-deviation-estimator","title":"Parameters for deviation estimator","text":"Name Type Description Default value show_debug_info bool Flag to display debug info true t_design double Maximum expected duration of dead-reckoning [s] 10.0 x_design double Maximum expected trajectory length of dead-reckoning [m] 30.0 time_window double Estimation period [s] 4.0 results_dir string Text path where the estimated results will be stored \"$(env HOME)\" gyro_estimation.only_use_straight bool Flag to use only straight sections for gyro estimation true gyro_estimation.only_use_moving bool Flag to use only moving sections for gyro estimation true gyro_estimation.only_use_constant_velocity bool Flag to use only constant velocity sections for gyro estimation true velocity_estimation.only_use_straight bool Flag to use only straight sections for velocity estimation true velocity_estimation.only_use_moving bool Flag to use only moving sections for velocity estimation true velocity_estimation.only_use_constant_velocity bool Flag to use only constant velocity sections for velocity estimation true"},{"location":"localization/deviation_estimation_tools/ReadMe/#functions","title":"Functions","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#bias-estimation","title":"Bias estimation","text":"

    By assuming that the pose information is a ground truth, the node estimates the bias of velocity and yaw rate.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#standard-deviation-estimation","title":"Standard deviation estimation","text":"

    The node also estimates the standard deviation of velocity and yaw rate. This can be used as a parameter in ekf_localizer. Note that the final estimation takes into account the bias.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#3-description-of-deviation-evaluator","title":"3. Description of Deviation Evaluator","text":"

    You can use deviation_evaluator for evaluating the estimated standard deviation parameters. This can be run with the following command:

    ros2 launch deviation_evaluator deviation_evaluator.launch.xml map_path:=MAP_PATH rviz:=true in_imu:=YOUR_IMU_TOPIC_NAME in_wheel_odometry:=YOUR_VELOCITY_TOPIC_NAME\nros2 bag play YOUR_BAG\n

    All the ros2bag and config files will be stored in $HOME/deviation_evaluator_sample (you can change this with save_dir parameter in the launch file).

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#features","title":"Features","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#a-visualization-of-confidence-ellipse","title":"A. Visualization of confidence ellipse","text":"

    deviation_evaluator supports rviz visualization. To use this feature, set rviz:=true and map_path:=/path/to/map_folder.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#b-check-the-compatibility-with-a-threshold-in-localization_error_monitor","title":"B. Check the compatibility with a threshold in localization_error_monitor","text":"

    The deviation_evaluator also checks the compatibility of the estimated parameters and the threshold in localization_error_monitor.

    Concretely, it checks if the two following statement holds:

    1. localization_error_monitor would NOT diagnose the system as WARN nor ERROR as long as the NDT is available.
    2. localization_error_monitor detects the anomaly with a recall over 0.99.

    Given the result of this validation, the users can verify that the estimated parameters in deviation_estimator can be safely applied to Autoware.

    Here, note that the localization_error_monitor treat the system as an anomaly if either of error along long-axis of confidence ellipse or error along lateral direction is over threshold. Please refer to the package in autoware.universe for detail.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#architecture-of-deviation_evaluator","title":"Architecture of deviation_evaluator","text":"

    The architecture of deviation_evaluator is shown below. It launches two ekf_localizer, one for ground truth estimation and one for (partially) dead reckoning estimation. Outputs of both ekf_localizer will be recorded and analyzed with deviation_evaluation_visualizer.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#inputs-outputs_1","title":"Inputs / Outputs","text":""},{"location":"localization/deviation_estimation_tools/ReadMe/#input_1","title":"Input","text":"Name Type Description in_ndt_pose_with_covariance geometry_msgs::msg::PoseWithCovarianceStamped Input pose in_ekf_dr_odom nav_msgs::msg::Odometry dead-reckoning EKF outputs in_ekf_gt_odom nav_msgs::msg::Odometry ground-truth EKF outputs"},{"location":"localization/deviation_estimation_tools/ReadMe/#output_1","title":"Output","text":"Name Type Description out_pose_with_covariance_dr geometry_msgs::msg::PoseWithCovarianceStamped Output pose (for dead reckoning ekf_localizer) out_pose_with_covariance_gt geometry_msgs::msg::PoseWithCovarianceStamped Output pose (for ground truth ekf_localizer) out_initial_pose_with_covariance geometry_msgs::msg::PoseWithCovarianceStamped Output initial pose (for both ekf_localizer)"},{"location":"localization/deviation_estimation_tools/ReadMe/#parameters-for-deviation-evaluator","title":"Parameters for deviation evaluator","text":"Name Type Description Default value rviz bool Show rviz if true false map_path string Path to the directory where map data (OpenStreetMap or .osm data) is saved \"\" save_dir string Output directory where figures, parameter files, and scores are saved \"$(env HOME)/deviation_evaluator_sample\" period double [s] Duration of cycle 10 (in config/deviation_evaluator.yaml) cut double [s] Duration of ndt-cut-off 9 (in config/deviation_evaluator.yaml)"},{"location":"localization/deviation_estimation_tools/ReadMe/#4-reflect-the-estimated-parameters-in-autoware","title":"4. Reflect the estimated parameters in Autoware","text":"

    The results of deviation_estimator is stored in two scripts:

    • imu_corrector param file (default: $HOME/imu_corrector.param.yaml)
    • vehicle_velocity_converter param file (default: $HOME/vehicle_velocity_converter.param.yaml)

    Please modify your Autoware configuration so that it will launch using the above two parameter files.

    "},{"location":"localization/deviation_estimation_tools/ReadMe/#5-known-issues","title":"5. Known issues","text":"
    • The plot of deviation_evaluator.png generated by deviation_evaluation_visualizer may diverge, possibly due to the large covariance caused by a failure in localization.
    • ekf_localizer in deviation_evaluator may not start properly. As for now, please launch deviation_evaluator first and then run ros2 bag play to provide pose and twist data.
    "},{"location":"map/autoware_lanelet2_map_utils/","title":"autoware_lanelet2_map_utils","text":""},{"location":"map/autoware_lanelet2_map_utils/#autoware_lanelet2_map_utils","title":"autoware_lanelet2_map_utils","text":"

    This package is for preprocessing the lanelet map.

    "},{"location":"map/autoware_lanelet2_map_validator/","title":"autoware_lanelet2_map_validator","text":""},{"location":"map/autoware_lanelet2_map_validator/#autoware_lanelet2_map_validator","title":"autoware_lanelet2_map_validator","text":"

    autoware_lanelet2_map_validator is a tool to validate Lanelet2 maps to ensure that Autoware can work properly with it.

    This validation tool is an extension of lanelet2_validation so that Autoware specific rules can be applied. As you can see from the codes in the src/validators directory, the group of validators belong to this tool inherits the lanelet::validation::MapValidator class from the original lanelet2_validation. Therefore, we believe that reading the source code of the lanelet2_validation will help you understand this tool better.

    Note that this validator is still on construction that there are only a few rules and a template to define those rules.

    The official Autoware requirements for lanelet2 maps are described in Vector Map creation requirement specifications (in Autoware Documentation).

    "},{"location":"map/autoware_lanelet2_map_validator/#design-concept","title":"Design concept","text":"

    The autoware_lanelet2_map_validator is designed to validate .osm map files by using and extending the lanelet2_validation package for Autoware.

    autoware_lanelet2_map_validator takes the lanelet2 map (.osm file) and requirement set (JSON file, optional) as the input, and output validation results to the console.

    If a requirement set is given, autoware_lanelet2_map_validator also outputs validation results reflecting the input requirement set. See \"Run with a requirement set\" for further information, \"Input file\" to understand the input format, and \"Output file\" to understand the output format.

    "},{"location":"map/autoware_lanelet2_map_validator/#how-to-use","title":"How to use","text":"

    Basically, you can use the following command to execute autoware_lanelet2_map_validator. However, note that autoware_lanelet2_map_validator is a ROS/rclcpp free tool, so you can just run the built executable whatever way.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-all-validators","title":"Run ALL validators","text":"

    You can use autoware_lanelet2_map_validator with the following command. This will run all validators including the default built-in validators in the lanelet2_validation.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-a-specific-validator","title":"Run a specific validator","text":"

    autoware_lanelet2_map_validator consists of multiple small validators in order to realize complex requirements with a combination of them. If you want to call a few validators, you can select them with the --validator, -v option.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --validator mapping.traffic_light.missing_regulatory_elements\n

    You can get a list of available validators with the --print option. (-p is for --projection)

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --print\n
    "},{"location":"map/autoware_lanelet2_map_validator/#run-with-a-requirement-set","title":"Run with a requirement set","text":"

    autoware_lanelet2_map_validator can manage to run a group of validators by a list of validator names. autoware_lanelet2_map_validator will scan through the input JSON file given by the --input_requirements, -i option, and output the validation results to the directory given by the --output_directory, -o option. The output filename will be lanelet2_validation_results.json.

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --input_requirements autoware_requirements_set.json --output_directory ./\n

    (Short version)

    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator -m path/to_your/lanelet2_map.osm -p mgrs -i autoware_requirements_set.json -o ./\n
    "},{"location":"map/autoware_lanelet2_map_validator/#input-file","title":"Input file","text":"

    The JSON file input should follow the structure like this example.

    {\n\"requirements\": [\n{\n\"id\": \"vm-02-02\",\n\"validators\": [\n{\n\"name\": \"mapping.stop_line.missing_regulatory_elements\"\n}\n]\n},\n{\n\"id\": \"vm-04-01\",\n\"validators\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n},\n{\n\"name\": \"mapping.crosswalk.regulatory_element_details\",\n\"prerequisites\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n}\n]\n}\n]\n},\n{\n\"id\": \"vm-05-01\",\n\"validators\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n},\n{\n\"name\": \"mapping.traffic_light.regulatory_element_details\",\n\"prerequisites\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n}\n]\n}\n]\n}\n]\n}\n
    • MUST have a single requirements field.
    • The requirements field MUST be a list of requirements. A requirement MUST have
      • id : The id of the requirement. Its name is arbitrary.
      • validators : A list of validators that structures the requirement.
        • A validator MUST be given with its name on the name field.
        • The name list of available validators can be obtained from the --print option.
        • You can add a list of prerequisites to each validator. Then, the validator will only be run when the prerequisites pass the validation.
        • In the prerequisites field, you can add forgive_warnings: true in order to run the validator even if the prerequisites output warning issues. (Error issues from prerequisites will still skip the validation.). Note that NOT writing the forgive_warnings field and writing forgive_warnings: false means the same.
    • The user can write any other field (like version) besides requirements.
    "},{"location":"map/autoware_lanelet2_map_validator/#output-file","title":"Output file","text":"

    When the input_requirements is thrown to autoware_lanelet2_map_validator, it will output a lanelet2_validation_results.json file which looks like the following example.

    {\n\"requirements\": [\n{\n\"id\": \"vm-02-02\",\n\"passed\": true,\n\"validators\": [\n{\n\"name\": \"mapping.stop_line.missing_regulatory_elements\",\n\"passed\": true\n}\n]\n},\n{\n\"id\": \"vm-04-01\",\n\"passed\": false,\n\"validators\": [\n{\n\"issues\": [\n{\n\"id\": 163,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 164,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 165,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 166,\n\"message\": \"No regulatory element refers to this crosswalk.\",\n\"primitive\": \"lanelet\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\",\n\"passed\": false\n},\n{\n\"issues\": [\n{\n\"id\": 0,\n\"message\": \"Prerequisites didn't pass\",\n\"primitive\": \"primitive\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.crosswalk.regulatory_element_details\",\n\"passed\": false,\n\"prerequisites\": [\n{\n\"name\": \"mapping.crosswalk.missing_regulatory_elements\"\n}\n]\n}\n]\n},\n{\n\"id\": \"vm-05-01\",\n\"passed\": false,\n\"validators\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\",\n\"passed\": true\n},\n{\n\"issues\": [\n{\n\"id\": 9896,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9918,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9838,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n},\n{\n\"id\": 9874,\n\"message\": \"Regulatory element of traffic light must have a stop line(ref_line).\",\n\"primitive\": \"regulatory element\",\n\"severity\": \"Error\"\n}\n],\n\"name\": \"mapping.traffic_light.regulatory_element_details\",\n\"passed\": false,\n\"prerequisites\": [\n{\n\"name\": \"mapping.traffic_light.missing_regulatory_elements\"\n}\n]\n}\n]\n}\n]\n}\n
    • lanelet2_validation_results.json inherits the JSON file of input_requirements and add results to it.
      • So additional input information not related to this validator also remains in the output.
    • autoware_lanelet2_map_validator adds a boolean passed field to each requirement. If all validators of the requirement have been passed, the passed field of the requirement will be true (false if not).
    • The passed field is also given to each validator. If the validator found any issues the passed field will turn to be false (true if not), and adds an issues field which is a list of issues found. Each issue contains information of severity, primitive, id, and message.
    "},{"location":"map/autoware_lanelet2_map_validator/#available-command-options","title":"Available command options","text":"option description -h, --help Explains about this tool and show a list of options --print Print all available checker without running them -m, --map_file Path to the map to be validated -i, --input_requirements Path to the JSON file where the list of requirements and validations is written -o, --output_directory Directory to save the list of validation results in a JSON format -v, --validator Comma separated list of regexes to filter the applicable validators. Will run all validators by default. Example: mapping.* to run all checks for the mapping -p, --projector Projector used for loading lanelet map. Available projectors are: mgrs, utm, and transverse_mercator. -l, --location Location of the map (for instantiating the traffic rules), e.g. de for Germany --participants Participants for which the routing graph will be instantiated (default: vehicle) --lat latitude coordinate of map origin. This is required for the transverse mercator and utm projector. --lon longitude coordinate of map origin. This is required for the transverse mercator and utm projector."},{"location":"map/autoware_lanelet2_map_validator/#available-validators","title":"Available validators","text":"

    Since there will be hundreds of validators in the future, the documents for each validator should categorized in the docs file. The directory structure should be the same to that of the src/validators directory.

    "},{"location":"map/autoware_lanelet2_map_validator/#stop-line","title":"Stop Line","text":"
    • mapping.stop_line.missing_regulatory_elements
    "},{"location":"map/autoware_lanelet2_map_validator/#traffic-light","title":"Traffic Light","text":"
    • mapping.traffic_light.missing_regulatory_elements
    • mapping.traffic_light.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/#crosswalk","title":"Crosswalk","text":"
    • mapping.crosswalk.missing_regulatory_elements
    • mapping.crosswalk.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/#how-to-add-a-new-validator","title":"How to add a new validator","text":"

    If you want to contribute to autoware_lanelet2_map_validator, please check out the how_to_contribute first.

    "},{"location":"map/autoware_lanelet2_map_validator/#relationship-between-requirements-and-validators","title":"Relationship between requirements and validators","text":"

    This is a table describing the correspondence between the validators that each requirement consists of. The \"Validators\" column will be blank if it hasn't be implemented.

    ID Requirements Validators vm-01-01 Lanelet basics vm-01-02 Allowance for lane changes vm-01-03 Linestring sharing vm-01-04 Sharing of the centerline of lanes for opposing traffic vm-01-05 Lane geometry vm-01-06 Line position (1) vm-01-07 Line position (2) vm-01-08 Line position (3) vm-01-09 Speed limits vm-01-10 Centerline vm-01-11 Centerline connection (1) vm-01-12 Centerline connection (2) vm-01-13 Roads with no centerline (1) vm-01-14 Roads with no centerline (2) vm-01-15 Road shoulder vm-01-16 Road shoulder Linestring sharing vm-01-17 Side strip vm-01-18 Side strip Linestring sharing vm-01-19 Walkway vm-02-01 Stop line alignment (Not detectable) vm-02-02 Stop sign mapping.stop_line.missing_regulatory_elements vm-03-01 Intersection criteria vm-03-02 Lanelet's turn direction and virtual vm-03-03 Lanelet width in the intersection vm-03-04 Lanelet creation in the intersection vm-03-05 Lanelet division in the intersection vm-03-06 Guide lines in the intersection vm-03-07 Multiple lanelets in the intersection vm-03-08 Intersection Area range mapping.intersection.intersection_area_validity, mapping.intersection.intersection_area_segment_type vm-03-09 Range of Lanelet in the intersection vm-03-10 Right of way (with signal) vm-03-11 Right of way (without signal) vm-03-12 Right of way supplements vm-03-13 Merging from private area, sidewalk vm-03-14 Road marking vm-03-15 Exclusive bicycle lane vm-04-01 Traffic light basics mapping.traffic_light.missing_regulatory_elements, mapping.traffic_light.regulatory_element_details, mapping.traffic_light.missing_referrers vm-04-02 Traffic light position and size mapping.traffic_light.correct_facing (Undone) vm-04-03 Traffic light lamps vm-05-01 Crosswalks across the road mapping.crosswalk.missing_regulatory_elements, mapping.crosswalk.regulatory_element_details vm-05-02 Crosswalks with pedestrian signals vm-05-03 Deceleration for safety at crosswalks vm-05-04 Fences vm-06-01 Buffer Zone vm-06-02 No parking signs vm-06-03 No stopping signs vm-06-04 No stopping sections vm-06-05 Detection area vm-07-01 Vector Map creation range vm-07-02 Range of detecting pedestrians who enter the road vm-07-03 Guardrails, guard pipes, fences vm-07-04 Ellipsoidal height"},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/","title":"How to contribute to `autoware_lanelet2_map_validator`","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#how-to-contribute-to-autoware_lanelet2_map_validator","title":"How to contribute to autoware_lanelet2_map_validator","text":"

    Your contribution is welcome to achieve a broad view of validation for lanelet2 maps. This document gives you the instructions on how to add a validator to autoware_lanelet2_map_validator. Please take a look at the Design Concept and follow the Contribution Guide.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#design-concept","title":"Design Concept","text":"

    The main goal of autoware_lanelet2_map_validator is to validate whether the lanelet2 map matches the vector map requirements for Autoware. autoware_lanelet2_map_validator achieves this by running a list of small validators. In other words, each vector map requirement will be validated by one or more validators. It is recommended to keep validators small and they don't have to be unique to a specific requirement so that we can broaden the expression of map requirements. (It doesn't mean that a validator should output only one kind of error!)

    The list of small validators will be defined as a JSON file (see autoware_requirement_set.json for an example), and the output will also be a JSON file that appends validation results to a copy of the input. See How to use autoware_lanelet2_map_validator for further information about how the input and output are processed.

    Please note that the validators are categorized according to the vector map requirements written in the Autoware Documentation. If there are any suggestions for new categories please let the pull request (PR) reviewers know. The available categories as of now are

    • Lane
    • Stop line
    • Intersection
    • Traffic light
    • Crosswalk
    • Area
    • Others
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#contribution-guide","title":"Contribution Guide","text":"

    This section is aimed at contributors who want to add their own validators. If you want to change the core process of autoware_lanelet2_map_validator, please open a PR and discuss it with the maintainers.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#1-implement-your-validator","title":"1. Implement your validator","text":"

    autoware_lanelet2_map_validator is based on the Lanelet2 library provided by fzi-forschungszentrum-informatik.

    Contributors are encouraged to make their validators by following the class structure shown in validator_template.cpp and validator_template.hpp. Looking at other implementations may also be helpful.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-path-structure","title":"Restrictions for path structure","text":"
    • The source file (.cpp) must belong to src/validators/\\<CATEGORY\\>/
    • Avoid source file names that are the same as those in other categories.
    • The header file (.hpp) must belong to src/include/lanelet2_map_validator/validators/\\<CATEGORY\\>/
    • Currently, there are no naming rules for source and header files, but the pair of source and header files should have the same name.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-validator-class-implementation","title":"Restrictions for validator class implementation","text":"
    • Define the name of the validator in the header file (.hpp file).
      • The name must follow the structure aaa.bbb.ccc
        • The first part (aaa) must be either mapping, routing or rule
        • The second part (bbb) should be either general, lane, stop_line, intersection, traffic_light, crosswalk, area, others.
        • The third part can be anything, as long as it is not hard to recognize the validator's feature.
      • The issue code of the validator will be generated from this name. It removes the first part of the name, converts it to upper camel case, and adds a number for classification. (e. g. Bbb.Ccc-001)
    • Write your implementation in the operator() function that outputs an Issues (a.k.a vector\\<Issue>) object. Not all of the implementation has to be written in the operator; you can privately define and use functions in your validator class.
    • Since autoware_lanelet2_map_validator outputs issue codes, please add an issue code prefix with square brackets on top of your issue message.
      • You may use the append_issue_code_prefix function to generate the issue code prefix.
      • Even if the validator only detects a single type of issue, please include the number 001 to your issue code.
      • The issue code must correspond to the issue message one-to-one.
    • Currently, there are no rules to decide the severity of the issue. If you're not confident about your severity decisions please discuss them with your PR reviewers.
    • Other coding rules are mentioned in the Autoware Documentation. However, this coding rule doesn't hold if it conflicts with the Lanelet2 library.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#2-write-a-test-code","title":"2. Write a test code","text":"

    Contributors must also provide test codes to ensure your validator is working properly and be able to be tested again when changes occur to the validator in the future.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-path-structure_1","title":"Restrictions for path structure","text":"
    • The source code (.cpp) must belong to test/src/.
      • The test codes are not categorized because there are few codes, but they might be categorized in the future.
    • The source code name should be test_<ORIGINAL_SOURCE_NAME>.cpp
    • The maps (.osm) for testing must belong to test/data/map/\\<CATEGORY\\>/
    • The JSON files (.json) for testing must belong to test/data/json/
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#restrictions-for-test-code-implementation","title":"Restrictions for test code implementation","text":"
    • Tests should be executable by colcon test. It is strongly recommended to use the gtest (googletest) format.
    • If possible, the MapValidationTester class may be useful to inherit common map loading process.
    • The test code must contain the following.
      • A test function that checks whether the validator is available.
      • A test function for each unique issue the validator can detect. It is recommended to create a small lanelet2 map for each unique issue.
        • In this test, please also check that the issue code is emitted as expected.
      • A test function ensuring that no issues occur when validating test/data/map/sample_map.osm. If sample_map.osm violates the validation or doesn't contain the primitive to validate, please fix or add the primitives to it.
    • Add the test code to CMakeLists.txt using the add_validation_test function.
      • Currently, this part must be added to CMakeLists.txt manually. Automation is expected in the future.
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#3-test-the-entire-validator","title":"3. Test the entire validator","text":"

    Please check that the autoware_lanelet2_map_validator works perfectly.

    1. Execute colcon test --packages-select autoware_lanelet2_map_validator --event-handlers console_cohesion+ and confirm that all tests pass.
    2. Execute the following command and confirm that no issues appear.
    ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator -p mgrs -m <PATH_TO_sample_map.osm> -i <PATH_TO_autoware_requirement_set.json> -o ./\n
    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#4-write-a-document","title":"4. Write a document","text":"

    Contributors must provide documentation to explain what the validator can do. The document must explain the following.

    • The validator's name
    • Feature of the validator
    • The source code where the validator is implemented
    • A table of issues that the validator can detect. The following details are required.
      • Issue Code
      • Message
      • Severity
      • Primitive
      • Description of the issue
      • Approach to fix the issue

    In addition, add a link of the document to the table Relationship between requirements and validators in the main README.md to let the users know which map requirement your validator relates with.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/how_to_contribute/#5-submit-a-pull-request","title":"5. Submit a pull request","text":"

    Submit a pull request to the autowarefoundation/autoware_tools repository.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/","title":"missing_regulator_elements_for_crosswalk","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#missing_regulator_elements_for_crosswalk","title":"missing_regulator_elements_for_crosswalk","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#validator-name","title":"Validator name","text":"

    mapping.crosswalk.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#feature","title":"Feature","text":"

    This validator checks whether each crosswalk subtype lanelet has a relevant regulatory element. Required information for a crosswalk is written in the Autoware documentation.

    The output issue marks \"lanelet\" as the primitive, and the lanelet ID is written together as ID.

    Issue Code Message Severity Description Approach Crosswalk.MissingRegulatoryElements-001 \"No regulatory element refers to this crosswalk.\" Error There is a crosswalk subtype lanelet that hasn't been referred to any regulatory element. Create a crosswalk subtype regulatory element and refer to the crosswalk lanelet."},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/missing_regulatory_elements_for_crosswalk/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_crosswalk.hpp
    • missing_regulatory_elements_for_crosswalk.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/","title":"regulatory_element_details_for_crosswalks","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#regulatory_element_details_for_crosswalks","title":"regulatory_element_details_for_crosswalks","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#validator-name","title":"Validator name","text":"

    mapping.crosswalk.regulatory_element_details

    "},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#feature","title":"Feature","text":"

    This validator checks whether the details in the crosswalk subtype regulatory elements are valid. Required information for a crosswalk is written in the Autoware documentation. This validator checks eight types of issues.

    The output issue marks \"lanelet\", \"linestring\" or \"regulatory_element\" as the primitive, and the regulatory element ID is written together as ID.

    Issue Code Message Severity Primitive Description Approach Crosswalk.RegulatoryElementDetails-001 \"Regulatory element of crosswalk must have lanelet of crosswalk(refers).\" Error regulatory element There is a crosswalk subtype regulatory element that has no referses. Write refers referring to a crosswalk subtype lanelet in the regulatory element Crosswalk.RegulatoryElementDetails-002 \"Regulatory element of crosswalk must have only one lanelet of crosswalk(refers).\" Error regulatory element There is a crosswalk subtype regulatory element that has multiple referses. A crosswalk subtype regulatory element can have only one refers. Remove the refers that is not a crosswalk lanelet. Crosswalk.RegulatoryElementDetails-003 \"Regulatory element of crosswalk does not have stop line(ref_line).\" Info regulatory element There is a crosswalk subtype regulatory element that has no ref_lines Generally, there should be a stop line for the crosswalk. Be sure that the stop line exists or doesn't. Crosswalk.RegulatoryElementDetails-004 \"Regulatory element of crosswalk is nice to have crosswalk_polygon.\" Warning regulatory element There is a crosswalk subtype regulatory element that has no crosswalk_polygons. It is recommended to surround a crosswalk with a crosswalk_polygon. Create one and add a crosswalk_polygon role member to the regulatory element with the polygon ID. Crosswalk.RegulatoryElementDetails-005 \"Regulatory element of crosswalk must have only one crosswalk_polygon.\" Error regulatory element There is a crosswalk subtype regulatory element that has multiple crosswalk_polygons. Only one crosswalk_polygon is allowed per crosswalk. Remove the unnecessary ones. Crosswalk.RegulatoryElementDetails-006 \"Refers of crosswalk regulatory element must have type of crosswalk.\" Error lanelet There is a crosswalk subtype regulatory element whose refers is not a crosswalk subtype lanelet. Check that the refers is a crosswalk subtype lanelet Crosswalk.RegulatoryElementDetails-007 \"ref_line of crosswalk regulatory element must have type of stopline.\" Error linestring There is a crosswalk subtype regulatory element whose ref_line is not a stop_line type linestring. Check that the ref_line is a stop_line type linestring Crosswalk.RegulatoryElementDetails-008 \"Crosswalk polygon of crosswalk regulatory element must have type of crosswalk_polygon.\" Error polygon There is a crosswalk subtype regulatory element whose crosswalk_polygon is not a crosswalk_polygon type polygon. Check that the crosswalk_polygon mentioned in the regulatory element refers to a crosswalk_polygon type area."},{"location":"map/autoware_lanelet2_map_validator/docs/crosswalk/regulatory_element_details_for_crosswalks/#related-source-codes","title":"Related source codes","text":"
    • regulatory_element_details_for_crosswalks.hpp
    • regulatory_element_details_for_crosswalks.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/","title":"intersection_area_segment_type","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#intersection_area_segment_type","title":"intersection_area_segment_type","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#validator-name","title":"Validator name","text":"

    mapping.intersection.intersection_area_segment_type

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#feature","title":"Feature","text":"

    This validator check whether each intersection_area type polygon is made from points that belong to road_border type linestrings or the starting/ending edge of a lanelet.

    This is achieved by the following procedure.

    1. Create a 2D bounding box that circumscribes the polygon.
    2. Collect road_border type linestrings within or intersecting the 2D bounding box.
    3. Collect starting/ending edges of lanelets within or intersecting the 2D bounding box.
    4. Examine each point that constitutes the polygon whether it belongs to the collection above.

    The validator outputs the following issue with the corresponding ID of the primitive.

    Issue Code Message Severity Primitive Description Approach Intersection.IntersectionAreaSegmentType-001 \"This intersection area is not made by points from road_border linestrings or lanelet edges. (Point ID: \\<POINT ID LIST>)\" Error Polygon The intersection_area polygon has points that doesn't belong to road_border type linestrings or lanelet edges. The violating points are listed up at \\<POINT ID LIST>. Ensure that the intersection_area is formed ONLY by road_border linestrings and lanelet edges."},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#supplementary-information","title":"Supplementary information","text":"

    Note that this validator only examines what type of linestring the points constituting the polygon belongs to, and doesn't examine they have a valid connection. Use the mapping.intersection.intersection_area_validity to check whether the polygon is boost::geometry::is_valid().

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_segment_type/#related-source-codes","title":"Related source codes","text":"
    • intersection_area_segment_type.hpp
    • intersection_area_segment_type.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/","title":"intersection_area_validity","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#intersection_area_validity","title":"intersection_area_validity","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#validator-name","title":"Validator name","text":"

    mapping.intersection.intersection_area_validity

    "},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#feature","title":"Feature","text":"

    This validator check whether each intersection_area type polygon satisfies boost::geometry::is_valid.

    The validator outputs the following issue with the corresponding ID of the primitive.

    Issue Code Message Severity Primitive Description Approach Intersection.IntersectionAreaValidity-001 \"This intersection_area doesn't satisfy boost::geometry::is_valid (reason: \\<MESSAGE>) Error Polygon The intersection_area polygon didn't satisfy boost::geometry::is_valid. There are several reasons expected and it is written in \"(reason: \\<MESSAGE>)\". The \\<MESSAGE> is a copy of the output message defined in the boost::geometry library."},{"location":"map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_validity/#related-source-codes","title":"Related source codes","text":"
    • intersection_area_validity.hpp
    • intersection_area_validity.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/","title":"missing_regulator_elements_for_stop_lines","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#missing_regulator_elements_for_stop_lines","title":"missing_regulator_elements_for_stop_lines","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#validator-name","title":"Validator name","text":"

    mapping.stop_line.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#feature","title":"Feature","text":"

    This validator checks whether each stop_line type linestring has a relevant regulatory element. Required information for a stop line is written in the Autoware documentation.

    The output issue marks \"linestring\" as the primitive, and the linestring ID is written together as ID.

    Issue Code Message Severity Description Approach StopLine.MissingRegulatoryElements-001 \"No regulatory element refers to this stop line.\" Error There is a stop_line type linestring that hasn't been referred to any regulatory element. Create a regulatory element that refers to this stop line."},{"location":"map/autoware_lanelet2_map_validator/docs/stop_line/missing_regulatory_elements_for_stop_lines/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_stop_line.cpp
    • missing_regulatory_elements_for_stop_line.hpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/","title":"missing_referrers_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#missing_referrers_for_traffic_lights","title":"missing_referrers_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.missing_referrers

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light type regulatory element has been referred by at least one lanelet.

    Issue Code Message Severity Primitive Description Approach TrafficLight.MissingReferrers-001 Regulatory element of traffic light must be referred by at least one lanelet. Error Regulatory Element There is a traffic_light type regulatory element that hasn't been referred by any lanelet. The lanelet that might be controlled by the traffic light must refer this regulatory element."},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_referrers_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • missing_referrers_for_traffic_lights.cpp
    • missing_referrers_for_traffic_lights.hpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/","title":"missing_regulator_elements_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#missing_regulator_elements_for_traffic_lights","title":"missing_regulator_elements_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.missing_regulatory_elements

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light type linestring has a relevant regulatory element. Required information for traffic lights is written in the Autoware documentation.

    The output issue marks \"linestring\" as the primitive, and the linestring ID is written together as ID.

    Issue Code Message Severity Description Approach TrafficLight.MissingRegulatoryElements-001 \"No regulatory element refers to this traffic light.\" Error There is a traffic_light type linestring that hasn't been referred to any regulatory element. Create a traffic_light subtype regulatory element that refers to this linestring"},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/missing_regulatory_elements_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • missing_regulatory_elements_for_traffic_light.hpp
    • missing_regulatory_elements_for_traffic_light.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/","title":"regulatory_element_details_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#regulatory_element_details_for_traffic_lights","title":"regulatory_element_details_for_traffic_lights","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.regulatory_element_details

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#feature","title":"Feature","text":"

    This validator checks whether the details in the traffic_light subtype regulatory elements are valid. Required information for traffic lights is written in the Autoware documentation. This validator checks four types of issues.

    The output issue marks \"linestring\" or \"regulatory element\" as the primitive, and the lanelet ID is written together as ID.

    Issue Code Message Severity Primitive Description Approach TrafficLight.RegulatoryElementDetails-001 \"Regulatory element of traffic light must have a stop line(ref_line).\" Error regulatory element There is a traffic_light subtype regulatory element that has no ref_lines Add ref_line to the regulatory element that refers to the id of the stop line linestring. TrafficLight.RegulatoryElementDetails-002 \"Refers of traffic light regulatory element must have type of traffic_light.\" Error linestring There is a traffic_light subtype regulatory element whose refers is not a traffic_light type linestring. Check that the refers in the regulatory element is a traffic_light type linestring. TrafficLight.RegulatoryElementDetails-003 \"ref_line of traffic light regulatory element must have type of stop_line.\" Error linestring There is a traffic_light subtype regulatory element whose ref_line is not a stop_line type linestring. Check that the ref_line in the regulatory element is a stop_line type linestring"},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/regulatory_element_details_for_traffic_lights/#related-source-codes","title":"Related source codes","text":"
    • regulatory_element_details_for_traffic_lights.hpp
    • regulatory_element_details_for_traffic_lights.cpp
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/","title":"traffic_light_facing","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#traffic_light_facing","title":"traffic_light_facing","text":""},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#validator-name","title":"Validator name","text":"

    mapping.traffic_light.correct_facing

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#recommended-prerequisite-validators","title":"Recommended prerequisite validators","text":"
    • mapping.traffic_light.missing_referrers
    • mapping.traffic_light.regulatory_element_details
    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#feature","title":"Feature","text":"

    This validator checks whether each traffic_light linestring is drawn with the correct direction, because the linestring direction describes the facing of the traffic_light. If the traffic light is facing to the viewer, the traffic light linestring must be drawn from the left point to the right point seen from the viewer. Note that this validator only check traffic lights whose subtype are red_yellow_green. This validator checks five types of issues. The former three issues are related to prerequisites to perform correct validation rather than direct validation results of the traffic light facing. The latter two issues mention to the traffic light facing.

    All output issues specify the traffic_light \"linestring\" or the traffic_light \"regulatory_element\" as the primitive, and the primitive ID will be specified as the ID.

    Issue Code Message Severity Primitive Description Approach TrafficLight.CorrectFacing-001 \"Lanelets referring this traffic_light have several divergent starting lines\" Info Linestring A traffic_light subtype regulatory element may be referred by multiple lanelets. This warning appears when the starting line of those lanelets (which tends to be the same or similar) diverge too much. This hardly happens, but maybe the referring lanelet is completely wrong or the traffic light cannot be seen from the starting edge of the referring lanelet. TrafficLight.CorrectFacing-002 \"The linestring direction seems to be wrong.\" Error Linestring This traffic_light type linestring is drawn with the wrong direction. Fix the traffic light linestring so that it is drawn from the left to the right seen from the stop line. TrafficLight.CorrectFacing-003 \"The linestring direction has been judged as both correct and wrong.\" Warning Linestring The validator cannot judge whether the direction of this traffic_light type linestring is correct. (Mostly they are correct.) This occurs from special regulatory element definitions and technical issues written below. This occurs in the Difficult Case written below. This validator currently cannot determine that the traffic light facing is correct in this case, so please recheck it by yourself and please ignore it if it is correct."},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#procedure","title":"Procedure","text":"

    This flow chart shows the simplified procedure how the validation is done.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#difficult-cases","title":"Difficult cases","text":"

    Currently, this validator assumes that all traffic lights in the same regulatory element has the same facing. However, there might be cases that this assumption doesn't hold, and this is only when traffic lights on the other side of the road is in the same regulatory element. It is hard to tell that this traffic light is for this road or the opposite road since the facing of the traffic light is unknown yet, so this validator keeps its ambiguity for now. This kind of traffic light will be judged as correct from the this side but not from the other side, and it will be misjudged oppositely if the traffic light linestring id drawn wrong. This validator will throws a warning for this case and tells the user to check it by their own.

    We assume that this kind of traffic light could be found only a few, but if you feel this concerning you can remove the traffic light on the other road from the regulatory element. This workaround affects nothing if your planning module doesn't utilize the information that the traffic light on the other road has the same timing of lighting.

    "},{"location":"map/autoware_lanelet2_map_validator/docs/traffic_light/traffic_light_facing/#related-source-codes","title":"Related source codes","text":"
    • traffic_light_facing.hpp
    • traffic_light_facing.cpp
    "},{"location":"map/autoware_pointcloud_divider/","title":"autoware_pointcloud_divider","text":""},{"location":"map/autoware_pointcloud_divider/#autoware_pointcloud_divider","title":"autoware_pointcloud_divider","text":"

    This is a tool for processing pcd files, and it can perform the following functions:

    • Dividing point clouds
    • Downsampling point clouds
    • Generating metadata to efficiently handle the divided point clouds
    "},{"location":"map/autoware_pointcloud_divider/#supported-data-format","title":"Supported Data Format","text":"

    Currently, only pcl::PointXYZ and pcl::PointXYZI are supported. Any PCD will be loaded as those two types.

    This tool can be used with files that have data fields other than XYZI (e.g., XYZRGB) and files that only contain XYZ.

    • Data fields other than XYZI are ignored during loading.
    • When loading XYZ-only data, the intensity field is assigned 0.
    "},{"location":"map/autoware_pointcloud_divider/#installation","title":"Installation","text":"
    cd <PATH_TO_pilot-auto.*> # OR <PATH_TO_autoware>\ncd src/\ngit clone git@github.com:autowarefoundation/autoware_tools.git\ncd ..\ncolcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --catkin-skip-building-tests --symlink-install --packages-up-to autoware_pointcloud_divider\n
    "},{"location":"map/autoware_pointcloud_divider/#usage","title":"Usage","text":"
    • Select directory, process all files found with find $INPUT_DIR -name \"*.pcd\".

      ros2 launch autoware_pointcloud_divider pointcloud_divider.launch.xml input_pcd_or_dir:=<INPUT_DIR> output_pcd_dir:=<OUTPUT_DIR> prefix:=<PREFIX>\n
      Name Description INPUT_DIR Directory that contains all PCD files OUTPUT_DIR Output directory name PREFIX Prefix of output PCD file name

    INPUT_DIR and OUTPUT_DIR should be specified as absolute paths.

    NOTE: The folder OUTPUT_DIR is auto generated. If it already exists, all files within that folder will be deleted before the tool runs. Hence, users should backup the important files in that folder if necessary.

    "},{"location":"map/autoware_pointcloud_divider/#parameters","title":"Parameters","text":"Name Type Description Default Range use_large_grid boolean Pack small segments to larger folders false N/A leaf_size float Resolution in meter for downsampling the output segments. Setting to negative to get the raw output PCDs. 0.2 N/A grid_size_x float The x size in meter of the output segments 20 N/A grid_size_y float The y size in meter of the output segments 20 N/A input_pcd_or_dir string The path to the folder containing the input PCD files N/A output_pcd_dir string The path to the folder containing the output PCD files N/A prefix string The prefix for the name of the output PCD files N/A point_type string Type of the point when processing PCD files. Could be point_xyz or point_xyzi point_xyzi N/A

    How the point cloud is processed.

    How the PCD file is named

    "},{"location":"map/autoware_pointcloud_divider/#parameter-example","title":"Parameter example","text":"
    1. Dividing point clouds without downsampling

      use_large_grid: false\nleaf_size: -1.0 # any negative number\ngrid_size_x: 20\ngrid_size_y: 20\n
    2. Dividing and downsampling point clouds

      use_large_grid: false\nleaf_size: 0.2\ngrid_size_x: 20\ngrid_size_y: 20\n
    "},{"location":"map/autoware_pointcloud_divider/#metadata-yaml-format","title":"Metadata YAML Format","text":"

    The metadata file should be named metadata.yaml. It contains the following fields:

    • x_resolution: The resolution along the X-axis.
    • y_resolution: The resolution along the Y-axis.

    Additionally, the file contains entries for individual point cloud files (.pcd files) and their corresponding grid coordinates. The key is the file name, and the value is a list containing the X and Y coordinates of the lower-left corner of the grid cell associated with that file. The grid cell's boundaries can be calculated using the x_resolution and y_resolution values.

    For example:

    x_resolution: 100.0\ny_resolution: 150.0\nA.pcd: [1200, 2500] # -> 1200 <= x <= 1300, 2500 <= y <= 2650\nB.pcd: [1300, 2500] # -> 1300 <= x <= 1400, 2500 <= y <= 2650\nC.pcd: [1200, 2650] # -> 1200 <= x <= 1300, 2650 <= y <= 2800\nD.pcd: [1400, 2650] # -> 1400 <= x <= 1500, 2650 <= y <= 2800\n
    "},{"location":"map/autoware_pointcloud_divider/#license","title":"LICENSE","text":"

    Parts of files grid_info.hpp, pcd_divider.hpp, and pcd_divider.cpp are copied from MapIV's pointcloud_divider and are under BSD-3-Clauses license. The remaining code are under Apache License 2.0

    "},{"location":"map/autoware_pointcloud_merger/","title":"autoware_pointcloud_merger","text":""},{"location":"map/autoware_pointcloud_merger/#autoware_pointcloud_merger","title":"autoware_pointcloud_merger","text":"

    This is a tool for processing pcd files, and it can perform the following functions:

    • Merging multiple PCD files to a single PCD file
    • Downsampling point clouds
    "},{"location":"map/autoware_pointcloud_merger/#supported-data-format","title":"Supported Data Format","text":"

    Currently, only pcl::PointXYZ and pcl::PointXYZI are supported. Any PCD will be loaded as those two types .

    This tool can be used with files that have data fields other than XYZI (e.g., XYZRGB) and files that only contain XYZ.

    • Data fields other than XYZI are ignored during loading.
    • When loading XYZ-only data, the intensity field is assigned 0.
    "},{"location":"map/autoware_pointcloud_merger/#installation","title":"Installation","text":"
    cd <PATH_TO_pilot-auto.*> # OR <PATH_TO_autoware>\ncd src/\ngit clone git@github.com:autowarefoundation/autoware_tools.git\ncd ..\ncolcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --catkin-skip-building-tests --symlink-install --packages-up-to autoware_pointcloud_merger\n
    "},{"location":"map/autoware_pointcloud_merger/#usage","title":"Usage","text":"
    • Merger all PCD files from the input directory into a single output PCD

      ros2 launch autoware_pointcloud_merger pointcloud_merger.launch.xml input_pcd_dir:=<INPUT_DIR> output_pcd:=<OUTPUT_PCD>\n
      Name Description INPUT_DIR Directory that contains all input PCD files OUTPUT_PCD Name of the output PCD file

    INPUT_DIR and OUTPUT_PCD should be specified as absolute paths.

    "},{"location":"map/autoware_pointcloud_merger/#parameter","title":"Parameter","text":"Name Type Description Default Range leaf_size float Resolution in meter for downsampling the output PCD. Setting to negative to get the raw output PCD. -0.1 N/A input_pcd_dir string The path to the folder containing the input PCD files N/A output_pcd string The path to the merged PCD file N/A point_type string Type of the point when processing PCD files. Could be point_xyz or point_xyzi point_xyzi N/A"},{"location":"map/autoware_pointcloud_merger/#license","title":"LICENSE","text":"

    Parts of files pcd_merger.hpp, and pcd_merger.cpp are copied from MapIV's pointcloud_divider and are under BSD-3-Clauses license. The remaining code are under Apache License 2.0

    "},{"location":"planning/autoware_planning_data_analyzer/","title":"Planning Data Analyzer","text":""},{"location":"planning/autoware_planning_data_analyzer/#planning-data-analyzer","title":"Planning Data Analyzer","text":""},{"location":"planning/autoware_planning_data_analyzer/#usage","title":"Usage","text":"
    ros2 launch autoware_planning_data_analyzer behavior_analyzer.launch.xml bag_path:=<ROSBAG>\n
    "},{"location":"planning/autoware_planning_data_analyzer/#output","title":"Output","text":"Name Type Description ~/output/manual_metrics tier4_debug_msgs::msg::Float32MultiArrayStamped Metrics calculated from the driver's driving trajectory. ~/output/system_metrics tier4_debug_msgs::msg::Float32MultiArrayStamped Metrics calculated from the autoware output. ~/output/manual_score tier4_debug_msgs::msg::Float32MultiArrayStamped Driving scores calculated from the driver's driving trajectory. ~/output/system_score tier4_debug_msgs::msg::Float32MultiArrayStamped Driving scores calculated from the autoware output."},{"location":"planning/autoware_route_client/","title":"Route Client","text":""},{"location":"planning/autoware_route_client/#route-client","title":"Route Client","text":"

    This package contains a tool to send request to set route.

    "},{"location":"planning/autoware_route_client/#usage","title":"Usage","text":""},{"location":"planning/autoware_route_client/#prepare-a-route-file","title":"Prepare a route file","text":"

    Prepare a YAML file containing route information. The file format is like following:

    goal:\nposition:\nx: 0.0\ny: 0.0\nz: 0.0\norientation:\nx: 0.0\ny: 0.0\nz: 0.0\nw: 0.0\nsegments:\n- preferred:\nid: 0\ntype: lane\nalternatives:\n- id: 1\ntype: lane\n- preferred:\nid: 2\ntype: lane\nalternatives: []\n- preferred:\nid: 3\ntype: lane\nalternatives:\n- id: 4\ntype: lane\n
    "},{"location":"planning/autoware_route_client/#send-request-to-set-route","title":"Send request to set route","text":"

    Execute following command.

    ros2 run autoware_route_client route_client.py <path_to_yaml_file>\n
    "},{"location":"planning/autoware_rtc_replayer/","title":"rtc_replayer","text":""},{"location":"planning/autoware_rtc_replayer/#rtc_replayer","title":"rtc_replayer","text":""},{"location":"planning/autoware_rtc_replayer/#purpose","title":"Purpose","text":"

    The current issue for RTC commands is that service is not recorded to rosbag, so it's very hard to analyze what was happened exactly. So this package makes it possible to replay rtc commands service from rosbag rtc status topic to resolve that issue.

    "},{"location":"planning/autoware_rtc_replayer/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"planning/autoware_rtc_replayer/#input","title":"Input","text":"Name Type Description /debug/rtc_status tier4_rtc_msgs::msg::CooperateStatusArray CooperateStatusArray that is recorded in rosbag"},{"location":"planning/autoware_rtc_replayer/#output","title":"Output","text":"Name Type Description /api/external/set/rtc_commands tier4_rtc_msgs::msg::CooperateCommands CooperateCommands that is replayed by this package"},{"location":"planning/autoware_rtc_replayer/#inner-workings-algorithms","title":"Inner-workings / Algorithms","text":""},{"location":"planning/autoware_rtc_replayer/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    This package can't replay CooperateCommands correctly if CooperateStatusArray is not stable. And this replay is always later one step than actual however it will not affect much for behavior.

    "},{"location":"planning/autoware_rtc_replayer/#future-extensions-unimplemented-parts","title":"Future extensions / Unimplemented parts","text":"

    tbd.

    "},{"location":"planning/planning_debug_tools/","title":"Planning Debug Tools","text":""},{"location":"planning/planning_debug_tools/#planning-debug-tools","title":"Planning Debug Tools","text":"

    This package contains several planning-related debug tools.

    • Trajectory analyzer: visualizes the information (speed, curvature, yaw, etc) along the trajectory
    • Closest velocity checker: prints the velocity information indicated by each modules
    • Perception reproducer: generates detected objects from rosbag data in planning simulator environment
    • processing time checker: displays processing_time of modules on the terminal
    • logging level updater: updates the logging level of the planning modules.
    "},{"location":"planning/planning_debug_tools/#trajectory-analyzer","title":"Trajectory analyzer","text":"

    The trajectory_analyzer visualizes the information (speed, curvature, yaw, etc) along the trajectory. This feature would be helpful for purposes such as \"investigating the reason why the vehicle decelerates here\". This feature employs the OSS PlotJuggler.

    "},{"location":"planning/planning_debug_tools/#stop-reason-visualizer","title":"Stop reason visualizer","text":"

    This is to visualize stop factor and reason. see the details

    "},{"location":"planning/planning_debug_tools/#how-to-use","title":"How to use","text":"

    please launch the analyzer node

    ros2 launch planning_debug_tools trajectory_analyzer.launch.xml\n

    and visualize the analyzed data on the plot juggler following below.

    "},{"location":"planning/planning_debug_tools/#setup-plotjuggler","title":"setup PlotJuggler","text":"

    For the first time, please add the following code to reactive script and save it as the picture below! (Looking for the way to automatically load the configuration file...)

    You can customize what you plot by editing this code.

    in Global code

    behavior_path = '/planning/scenario_planning/lane_driving/behavior_planning/path_with_lane_id/debug_info'\nbehavior_velocity = '/planning/scenario_planning/lane_driving/behavior_planning/path/debug_info'\nmotion_avoid = '/planning/scenario_planning/lane_driving/motion_planning/path_optimizer/trajectory/debug_info'\nmotion_smoother_latacc = '/planning/scenario_planning/motion_velocity_smoother/debug/trajectory_lateral_acc_filtered/debug_info'\nmotion_smoother = '/planning/scenario_planning/trajectory/debug_info'\n

    in function(tracker_time)

    PlotCurvatureOverArclength('k_behavior_path', behavior_path, tracker_time)\nPlotCurvatureOverArclength('k_behavior_velocity', behavior_velocity, tracker_time)\nPlotCurvatureOverArclength('k_motion_avoid', motion_avoid, tracker_time)\nPlotCurvatureOverArclength('k_motion_smoother', motion_smoother, tracker_time)\n\nPlotVelocityOverArclength('v_behavior_path', behavior_path, tracker_time)\nPlotVelocityOverArclength('v_behavior_velocity', behavior_velocity, tracker_time)\nPlotVelocityOverArclength('v_motion_avoid', motion_avoid, tracker_time)\nPlotVelocityOverArclength('v_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotVelocityOverArclength('v_motion_smoother', motion_smoother, tracker_time)\n\nPlotAccelerationOverArclength('a_behavior_path', behavior_path, tracker_time)\nPlotAccelerationOverArclength('a_behavior_velocity', behavior_velocity, tracker_time)\nPlotAccelerationOverArclength('a_motion_avoid', motion_avoid, tracker_time)\nPlotAccelerationOverArclength('a_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotAccelerationOverArclength('a_motion_smoother', motion_smoother, tracker_time)\n\nPlotYawOverArclength('yaw_behavior_path', behavior_path, tracker_time)\nPlotYawOverArclength('yaw_behavior_velocity', behavior_velocity, tracker_time)\nPlotYawOverArclength('yaw_motion_avoid', motion_avoid, tracker_time)\nPlotYawOverArclength('yaw_motion_smoother_latacc', motion_smoother_latacc, tracker_time)\nPlotYawOverArclength('yaw_motion_smoother', motion_smoother, tracker_time)\n\nPlotCurrentVelocity('localization_kinematic_state', '/localization/kinematic_state', tracker_time)\n

    in Function Library

    function PlotValue(name, path, timestamp, value)\n  new_series = ScatterXY.new(name)\n  index = 0\n  while(true) do\n    series_k = TimeseriesView.find( string.format( \"%s/\"..value..\"[%d]\", path, index) )\n    series_s = TimeseriesView.find( string.format( \"%s/arclength[%d]\", path, index) )\n    series_size = TimeseriesView.find( string.format( \"%s/size\", path) )\n\n    if series_k == nil or series_s == nil then break end\n\n    k = series_k:atTime(timestamp)\n    s = series_s:atTime(timestamp)\n    size = series_size:atTime(timestamp)\n\n    if index >= size then break end\n\n    new_series:push_back(s,k)\n    index = index+1\n  end\nend\n\nfunction PlotCurvatureOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"curvature\")\nend\n\nfunction PlotVelocityOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"velocity\")\nend\n\nfunction PlotAccelerationOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"acceleration\")\nend\n\nfunction PlotYawOverArclength(name, path, timestamp)\n  PlotValue(name, path, timestamp,\"yaw\")\nend\n\nfunction PlotCurrentVelocity(name, kinematics_name, timestamp)\n  new_series = ScatterXY.new(name)\n  series_v = TimeseriesView.find( string.format( \"%s/twist/twist/linear/x\", kinematics_name))\n  if series_v == nil then\n    print(\"error\")\n    return\n  end\n  v = series_v:atTime(timestamp)\n  new_series:push_back(0.0, v)\nend\n

    Then, run the plot juggler.

    "},{"location":"planning/planning_debug_tools/#how-to-customize-the-plot","title":"How to customize the plot","text":"

    Add Path/PathWithLaneIds/Trajectory topics you want to plot in the trajectory_analyzer.launch.xml, then the analyzed topics for these messages will be published with TrajectoryDebugINfo.msg type. You can then visualize these data by editing the reactive script on the PlotJuggler.

    "},{"location":"planning/planning_debug_tools/#requirements","title":"Requirements","text":"

    The version of the plotJuggler must be > 3.5.0

    "},{"location":"planning/planning_debug_tools/#closest-velocity-checker","title":"Closest velocity checker","text":"

    This node prints the velocity information indicated by planning/control modules on a terminal. For trajectories calculated by planning modules, the target velocity on the trajectory point which is closest to the ego vehicle is printed. For control commands calculated by control modules, the target velocity and acceleration is directly printed. This feature would be helpful for purposes such as \"investigating the reason why the vehicle does not move\".

    You can launch by

    ros2 run planning_debug_tools closest_velocity_checker.py\n

    "},{"location":"planning/planning_debug_tools/#trajectory-visualizer","title":"Trajectory visualizer","text":"

    The old version of the trajectory analyzer. It is written in Python and more flexible, but very slow.

    "},{"location":"planning/planning_debug_tools/#for-other-use-case-experimental","title":"For other use case (experimental)","text":"

    To see behavior velocity planner's internal plath with lane id add below example value to behavior velocity analyzer and set is_publish_debug_path: true

    crosswalk ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/crosswalk/debug_info'\nintersection ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/intersection/debug_info'\ntraffic_light ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/traffic_light/debug_info'\nmerge_from_private ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/merge_from_private/debug_info'\nocclusion_spot ='/planning/scenario_planning/lane_driving/behavior_planning/behavior_velocity_planner/debug/path_with_lane_id/occlusion_spot/debug_info'\n
    PlotVelocityOverArclength('v_crosswalk', crosswalk, tracker_time)\nPlotVelocityOverArclength('v_intersection', intersection, tracker_time)\nPlotVelocityOverArclength('v_merge_from_private', merge_from_private, tracker_time)\nPlotVelocityOverArclength('v_traffic_light', traffic_light, tracker_time)\nPlotVelocityOverArclength('v_occlusion', occlusion_spot, tracker_time)\n\nPlotYawOverArclength('yaw_crosswalk', crosswalk, tracker_time)\nPlotYawOverArclength('yaw_intersection', intersection, tracker_time)\nPlotYawOverArclength('yaw_merge_from_private', merge_from_private, tracker_time)\nPlotYawOverArclength('yaw_traffic_light', traffic_light, tracker_time)\nPlotYawOverArclength('yaw_occlusion', occlusion_spot, tracker_time)\n\nPlotCurrentVelocity('localization_kinematic_state', '/localization/kinematic_state', tracker_time)\n
    "},{"location":"planning/planning_debug_tools/#perception-reproducer","title":"Perception reproducer","text":"

    This script can overlay the perception results from the rosbag on the planning simulator synchronized with the simulator's ego pose.

    "},{"location":"planning/planning_debug_tools/#how-it-works","title":"How it works","text":"

    Whenever the ego's position changes, a chronological reproduce_sequence queue is generated based on its position with a search radius (default to 2 m). If the queue is empty, the nearest odom message in the rosbag is added to the queue. When publishing perception messages, the first element in the reproduce_sequence is popped and published.

    This design results in the following behavior:

    • When ego stops, the perception messages are published in chronological order until queue is empty.
    • When the ego moves, a perception message close to ego's position is published.
    "},{"location":"planning/planning_debug_tools/#available-options","title":"Available Options","text":"
    • -b, --bag: Rosbag file path (required)
    • -d, --detected-object: Publish detected objects
    • -t, --tracked-object: Publish tracked objects
    • -r, --search-radius: Set the search radius in meters (default: 1.5m). If set to 0, always publishes the nearest message
    • -c, --reproduce-cool-down: Set the cool down time in seconds (default: 80.0s)
    • -p, --pub-route: Initialize localization and publish a route based on poses from the rosbag
    • -n, --noise: Apply perception noise to objects when publishing repeated messages (default: True)
    • -f, --rosbag-format: Specify rosbag data format (default: \"db3\")
    • -v, --verbose: Output debug data
    "},{"location":"planning/planning_debug_tools/#how-to-use_1","title":"How to use","text":"

    First, launch the planning simulator, and put the ego pose. Then, run the script according to the following command.

    By designating a rosbag, perception reproducer can be launched.

    ros2 run planning_debug_tools perception_reproducer.py -b <bag-file>\n

    You can designate multiple rosbags in the directory.

    ros2 run planning_debug_tools perception_reproducer.py -b <dir-to-bag-files>\n

    Instead of publishing predicted objects, you can publish detected/tracked objects by designating -d or -t, respectively.

    The --pub-route option enables automatic route generation based on the rosbag data. When enabled, the script:

    1. Extracts the initial and goal poses from the beginning and end of the rosbag file
    2. Initializes the localization system with the initial pose
    3. Generates and publishes a route to the goal pose

    Example usage with route publication:

    ros2 run planning_debug_tools perception_reproducer.py -b <bag-file> -p\n
    "},{"location":"planning/planning_debug_tools/#perception-replayer","title":"Perception replayer","text":"

    A part of the feature is under development.

    This script can overlay the perception results from the rosbag on the planning simulator.

    In detail, this script publishes the data at a certain timestamp from the rosbag. The timestamp will increase according to the real time without any operation. By using the GUI, you can modify the timestamp by pausing, changing the rate or going back into the past.

    "},{"location":"planning/planning_debug_tools/#how-to-use_2","title":"How to use","text":"

    First, launch the planning simulator, and put the ego pose. Then, run the script according to the following command.

    By designating a rosbag, perception replayer can be launched. The GUI is launched as well with which a timestamp of rosbag can be managed.

    ros2 run planning_debug_tools perception_replayer.py -b <bag-file>\n

    You can designate multiple rosbags in the directory.

    ros2 run planning_debug_tools perception_replayer.py -b <dir-to-bag-files>\n

    Instead of publishing predicted objects, you can publish detected/tracked objects by designating -d or -t, respectively.

    "},{"location":"planning/planning_debug_tools/#processing-time-checker","title":"Processing time checker","text":"

    The purpose of the Processing Time Subscriber is to monitor and visualize the processing times of various ROS 2 topics in a system. By providing a real-time terminal-based visualization, users can easily confirm the processing time performance as in the picture below.

    You can run the program by the following command.

    ros2 run planning_debug_tools processing_time_checker.py -f <update-hz> -m <max-bar-time>\n

    This program subscribes to ROS 2 topics that have a suffix of processing_time_ms.

    The program allows users to customize two parameters via command-line arguments:

    • --max_display_time (or -m): This sets the maximum display time in milliseconds. The default value is 150ms.
    • --display_frequency (or -f): This sets the frequency at which the terminal UI updates. The default value is 5Hz.

    By adjusting these parameters, users can tailor the display to their specific monitoring needs.

    "},{"location":"planning/planning_debug_tools/#logging-level-updater","title":"Logging Level Updater","text":"

    The purpose of the Logging Level Updater is to update the logging level of the planning modules via ROS 2 service. Users can easily update the logging level for debugging.

    ros2 run planning_debug_tools update_logger_level.sh <module-name> <logger-level>\n

    <logger-level> will be DEBUG, INFO, WARN, or ERROR.

    When you have a typo of the planning module, the script will show the available modules.

    "},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/","title":"Doc stop reason visualizer","text":""},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/#stop_reason_visualizer","title":"stop_reason_visualizer","text":"

    This module is to visualize stop factor quickly without selecting correct debug markers. This is supposed to use with virtual wall marker like below.

    "},{"location":"planning/planning_debug_tools/doc-stop-reason-visualizer/#how-to-use","title":"How to use","text":"

    Run this node.

    ros2 run planning_debug_tools stop_reason_visualizer_exe\n

    Add stop reason debug marker from rviz.

    Note: ros2 process can be sometimes deleted only from killall stop_reason_visualizer_exe

    Reference

    "},{"location":"simulator/simulator_compatibility_test/","title":"simulator_compatibility_test","text":""},{"location":"simulator/simulator_compatibility_test/#simulator_compatibility_test","title":"simulator_compatibility_test","text":""},{"location":"simulator/simulator_compatibility_test/#purpose","title":"Purpose","text":"

    Test procedures (e.g. test codes) to check whether a certain simulator is compatible with Autoware

    "},{"location":"simulator/simulator_compatibility_test/#overview-of-the-test-codes","title":"Overview of the test codes","text":"

    File structure

    • test_base
    • test_sim_common_manual_testing
    • test_morai_sim
    1. test_base provides shared methods for testing. Other test codes are created based on functions defined here.
    2. test_sim_common_manual_testing provides the most basic functions. Any simulator can be tested using codes here. However, to make these codes usable with any simulators, the codes do not include any features for test automation.
    3. test_morai_sim is an automated version of test_sim_common_manual_testing for MORAI SIM: Drive. Thus it includes 'MORAI SIM: Drive'-specific codes. Users of the other simulators may create similar version for their simulator of interest.
    "},{"location":"simulator/simulator_compatibility_test/#test-procedures-for-test_sim_common_manual_testing","title":"Test Procedures for test_sim_common_manual_testing","text":""},{"location":"simulator/simulator_compatibility_test/#build-process-before-test","title":"Build process before test","text":"
    source install/setup.bash\ncolcon build --packages-select simulator_compatibility_test\ncd src/universe/autoware.universe/tools/simulator_test/simulator_compatibility_test/test_sim_common_manual_testing\n

    To run each test case manually

    "},{"location":"simulator/simulator_compatibility_test/#test-case-1","title":"Test Case #1","text":"
    1. Run your simulator
    2. Load a map and an ego vehicle for the test
    3. Run the test using the following command

      python -m pytest test_01_control_mode_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle control mode is changed into Manual (If the simulator has a GUI for this one, it should display the ego is in Manual)
      • Ego vehicle control mode is changed into Auto (If the simulator has a GUI for this one, it should display the ego is in Auto)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-2","title":"Test Case #2","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_02_change_gear_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle gear mode is changed into \"P\" (If the simulator has a GUI for this one, it should display the gear mode is in \"P\")
      • Ego vehicle gear mode is changed into \"N\" (If the simulator has a GUI for this one, it should display the gear mode is in \"N\")
      • Ego vehicle gear mode is changed into \"R\" (If the simulator has a GUI for this one, it should display the gear mode is in \"R\")
      • Ego vehicle gear mode is changed into \"D\" (If the simulator has a GUI for this one, it should display the gear mode is in \"D\")
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-3","title":"Test Case #3","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_03_longitudinal_command_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle longitudinal velocity is greater than 10 kph (If the simulator has a GUI for this one, it should display the longitudinal velocity is greater than 10 kph)
      • Ego vehicle longitudinal velocity is going below 10 kph. This is an ego vehicle initialize process to ensure the following acceleration is made by longitudinal.acceleration value (If the simulator has a GUI for this one, it should display the longitudinal velocity is less than 10 kph)
      • Ego vehicle longitudinal velocity is greater than 10 kph (If the simulator has a GUI for this one, it should display the longitudinal velocity is greater than 10 kph)
      • Ego vehicle longitudinal velocity is going below 10 kph. This is an ego vehicle reset process to tear down this test case.
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-4","title":"Test Case #4","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_04_lateral_command_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle steering and/or tire value is greater than 0 degree (If the simulator has a GUI for this one, it should display the steering and/or tire is greater than 0 degree)
      • Ego vehicle steering and/or tire value is 0 degree. This is a reset process. (If the simulator has a GUI for this one, it should display the steering and/or tire is 0 degree)
      • Ego vehicle steering and/or tire value is less than 0 degree (If the simulator has a GUI for this one, it should display the steering and/or tire is less than 0 degree)
      • Ego vehicle steering and/or tire value is 0 degree. This is a reset process. (If the simulator has a GUI for this one, it should display the steering and/or tire is 0 degree)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-5","title":"Test Case #5","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_05_turn_indicators_cmd_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle left turn indicator is turned on (If the simulator has a GUI for this one, it should display the left turn indicator is turned on)
      • Ego vehicle right turn indicator is turned on (If the simulator has a GUI for this one, it should display the right turn indicator is turned on)
      • Ego vehicle both turn indicators are turned off. This is a reset process. (If the simulator has a GUI for this one, it should display both left and right turn indicators are turned off)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-case-6","title":"Test Case #6","text":"
    1. Run your simulator (If the simulator is already running, skip this part)
    2. Load a map and an ego vehicle for the test (If a map and an ego are loaded already, skip this part)
    3. Run the test using the following command

      python -m pytest test_06_hazard_lights_cmd_and_report.py\n
    4. Check if expected behavior is created within the simulator

      • Ego vehicle hazard lights are turned on (If the simulator has a GUI for this one, it should display the hazard lights are turned on or blinking)
      • Ego vehicle hazard lights are turned off. This is a reset process. (If the simulator has a GUI for this one, it should display the hazard lights are turned off)
    5. Check if pytest output is passed or failure
    "},{"location":"simulator/simulator_compatibility_test/#test-procedures-for-test_morai_sim","title":"Test Procedures for test_morai_sim","text":""},{"location":"simulator/simulator_compatibility_test/#build-process-before-test_1","title":"Build process before test","text":"
    source install/setup.bash\ncolcon build --packages-select simulator_compatibility_test\ncd src/universe/autoware.universe/tools/simulator_test/simulator_compatibility_test/test_morai_sim\n

    Detailed process

    (WIP)

    "},{"location":"simulator/simulator_compatibility_test/#inner-workings-algorithms","title":"Inner-workings / Algorithms","text":""},{"location":"simulator/simulator_compatibility_test/#inputs-outputs","title":"Inputs / Outputs","text":""},{"location":"simulator/simulator_compatibility_test/#input","title":"Input","text":"Name Type Description /vehicle/status/control_mode autoware_vehicle_msgs::msg::ControlModeReport for [Test Case #1] /vehicle/status/gear_status autoware_vehicle_msgs::msg::GearReport for [Test Case #2] /vehicle/status/velocity_status autoware_vehicle_msgs::msg::VelocityReport for [Test Case #3] /vehicle/status/steering_status autoware_vehicle_msgs::msg::SteeringReport for [Test Case #4] /vehicle/status/turn_indicators_status autoware_vehicle_msgs::msg::TurnIndicatorsReport for [Test Case #5] /vehicle/status/hazard_lights_status autoware_vehicle_msgs::msg::HazardLightsReport for [Test Case #6]"},{"location":"simulator/simulator_compatibility_test/#output","title":"Output","text":"Name Type Description /control/command/control_cmd autoware_control_msgs/Control for [Test Case #3, #4] /control/command/control_mode_cmd autoware_vehicle_msgs/ControlModeCommand for [Test Case #1] /control/command/gear_cmd autoware_vehicle_msgs/GearCommand for [Test Case #2] /vehicle/status/steering_status autoware_vehicle_msgs/TurnIndicatorsCommand for [Test Case #5] /control/command/turn_indicators_cmd autoware_vehicle_msgs/HazardLightsCommand for [Test Case #6]"},{"location":"simulator/simulator_compatibility_test/#parameters","title":"Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#node-parameters","title":"Node Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#core-parameters","title":"Core Parameters","text":"

    None.

    "},{"location":"simulator/simulator_compatibility_test/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    None.

    "},{"location":"system/rqt_diagnostic_graph_monitor/","title":"System diagnostic monitor","text":""},{"location":"vehicle/calibration_adapter/","title":"calibration_adapter","text":""},{"location":"vehicle/calibration_adapter/#calibration_adapter","title":"calibration_adapter","text":""},{"location":"vehicle/calibration_adapter/#purpose","title":"Purpose","text":"

    This package relay topic to Float32Stamped type of \"autoware_calibration_msgs\" to generalize calibration topics.

    "},{"location":"vehicle/calibration_adapter/#details","title":"Details","text":"
    • calibration_adapter_node_base This node has general calibration topics for all vehicle interface
    • calibration_adapter This node has vehicle specific or temporary topics to calibrate and this node inherit calibration_adapter_node_base.
    "},{"location":"vehicle/calibration_adapter/#assumptions-known-limits","title":"Assumptions / Known limits","text":"

    TBD.

    "},{"location":"vehicle/parameter_estimator/","title":"ParameterEstimation","text":""},{"location":"vehicle/parameter_estimator/#parameterestimation","title":"ParameterEstimation","text":"

    This parameter estimation node estimates a default parameters from inputs for steer offset,wheel base and gear ratio.

    "},{"location":"vehicle/parameter_estimator/#io","title":"I/O","text":""},{"location":"vehicle/parameter_estimator/#input","title":"input","text":"

    The following topics are used to estimate the parameters.

    • /sensing/imu/imu_data: used as vehicle angular velocity
    • /vehicle/status/twist: used as vehicle velocity
    • /vehicle/status/steering: used as vehicle steering angle (Only used in Steer Offset Estimator & Wheel Base Estimator)
    • /calibration/vehicle/handle_status: used as vehicle handle angle (Only used in Gear Estimator)
    • /vehicle/engage: used to check the driving operation status
    "},{"location":"vehicle/parameter_estimator/#output","title":"output","text":"

    The following topics are the output

    • /vehicle/status/gear_ratio
    • /vehicle/status/steering_offset
    • /vehicle/status/wheel_base

    For users, the EstimationResult.msg output contains the following items:

    • result: Estimated result.
    • result_mean: Average value of result.
    • result_stddev: Standard deviation value of the estimated parameter
    • absolute_error: Absolute error of the estimated parameters
    • mean_absolute_error: Mean absolute error of the estimated parameters
    • stddev_absolute_error: Standard Deviation of absolute error of the estimated parameters
    "},{"location":"vehicle/parameter_estimator/#these-values-can-be-confirmed-in-plot_juggler","title":"These values can be confirmed in plot_juggler","text":"
    • To display in the plot juggler, you need to drag the result into the table, currently plot juggler cannot auto display the value
    "},{"location":"vehicle/parameter_estimator/#how-to-run-parameter-estimator","title":"How to Run Parameter Estimator","text":"

    Note: You need to build the Autoware beforehand.

    The following command will start the parameter estimation node.

    ros2 launch parameter_estimator parameter_estimator.launch.xml vehicle_model:=lexus\n
    • The following arguments are using to select the estimator, default is true
      • select_gear_ratio_estimator
      • select_steer_offset_estimator
      • select_wheel_base_estimator
    • To deselect the specific estimator, you need to set estimator to false
    • Example, the following command will only launch gear ratio estimator
    ros2 launch parameter_estimator parameter_estimator.launch.xml vehicle_model:=lexus select_steer_offset_estimator:=false select_wheel_base_estimator:=false\n

    If you want to launch with Rviz, use the following launch file. Currently unavailable

    # Launch parameter Estimator with the Autoware\n$ ros2 launch parameter_estimator parameter_estimator_with_simulation.launch.xml map_path:=.../kashiwanoha2/ vehicle_model:=jpntaxi sensor_model:=aip_xx1 rviz:=true\n
    "},{"location":"vehicle/parameter_estimator/#how-to-check-the-estimated-parameters","title":"How to check the estimated parameters","text":"

    The necessary information is plotted in the plot_juggler, which displays the following information from top to bottom.

    • First row: Estimation results confirmation
    • Second row: error for estimation

    You need to adjust the value of (valid_min_) or (valid_max_). according to the standard deviation to determine the validity of the data.

    "},{"location":"vehicle/parameter_estimator/#estimation-results-confirmation","title":"Estimation results confirmation","text":"

    Check the estimation results.

    • result : parameter estimated at each step
    • result_mean : Average of the parameters
    • result_stddev : Standard deviation of the estimated parameters

    It is preferable to use the _mean for the calibration results.

    The parameters estimation starts when enough data is stored. The output value is zero until it is ready.

    "},{"location":"vehicle/parameter_estimator/#error-for-parameters-estimation","title":"Error for parameters estimation","text":"

    Check the statistics of the errors in the input/output data after the parameter estimation.

    • absolute_error : absolute error of measured and estimated of the parameters estimation
    • mean_absolute_error : Mean of the absolute error calculated in each estimation step
    • stddev_absolute_error : Standard deviation of the absolute error calculated in each estimation step

    If these values are large, the model needs to be reconsidered.

    "},{"location":"vehicle/parameter_estimator/#data-preprocessing","title":"Data preprocessing","text":""},{"location":"vehicle/parameter_estimator/#examine-the-results-of-processing-the-input-data","title":"Examine the results of processing the input data","text":"

    Data that do not satisfy the following conditions are considered invalid and will not be used for estimation.

    • Data variation (evaluated by standard deviation) is smaller than the threshold
    • The car is not in automatic operation mode (judged from Autoware's Engage, Vehicle's Engage, etc.)
    "},{"location":"vehicle/pitch_checker/","title":"pitch checker","text":""},{"location":"vehicle/pitch_checker/#pitch-checker","title":"pitch checker","text":"

    The role of this node is to visualize pitch of driving route. The source of pitch is tf (map->base_link).

    "},{"location":"vehicle/pitch_checker/#how-to-visualize","title":"How to visualize","text":""},{"location":"vehicle/pitch_checker/#collect-data","title":"Collect data","text":""},{"location":"vehicle/pitch_checker/#launch-data-collector-node","title":"launch data collector node","text":"
    ros2 launch pitch_checker pitch_checker.launch.xml\n
    "},{"location":"vehicle/pitch_checker/#save-file-to-data","title":"save file to data","text":"
    ros2 service call /pitch_checker/save_flag std_srvs/srv/Trigger {}\n

    (The pitch data is saved at <YOUR WORKSPACE>/install/pitch_checker/share/pitch_checker/pitch.csv)

    "},{"location":"vehicle/pitch_checker/#visualize-data","title":"Visualize data","text":"
    ros2 launch pitch_checker view_pitch.launch.xml\n

    The view_pitch.launch loads the data stored in the default path and visualize it is as below. The pitch angle [rad] is shown on the left plot, the value of the z-coordinate [m] on the right plot.

    "},{"location":"vehicle/time_delay_estimator/","title":"TimeDelayEstimation","text":""},{"location":"vehicle/time_delay_estimator/#timedelayestimation","title":"TimeDelayEstimation","text":"

    This delay estimation node estimates a time delay from inputs to outputs for accel, brake, and steer.

    "},{"location":"vehicle/time_delay_estimator/#input-response","title":"Input / Response","text":"

    The following topics are used to estimate the delay.

    • /vehicle/raw_vehicle_cmd: used as accel/brake target value
    • /control/control_cmd: used as steer target value
    • /calibration/vehicle/accel_status: used as accel observed value
    • /calibration/vehicle/brake_status: used as brake observed value
    • /vehicle/status/steering: used as steer observed value
    • /calibration/vehicle/is_engage: used to check the driving operation status

    output.

    For users, the TimeDelay.msg output contains the following items:

    • time_delay: Estimated time delay.
    • mean: Mean value of the estimated time delay
    • stddev: Standard deviation of the estimated time delay
    • is_valid_data: Validity determination of the current data
    • first_order_model_coefficients\uff1asize 2 array of model coefficients(b,k,t)
    • second_order_model_coefficients\uff1asize 2 array of model coefficients(m,b,k,t)

    In addition, the following items are output for developers.

    • Mean average error of delay estimation
    • Standard deviation of the mean error of delay estimation

    These values can be confirmed in rqt_multiplot, described below.

    "},{"location":"vehicle/time_delay_estimator/#how-to-run-time-delay-estimator","title":"How to Run Time Delay Estimator","text":"

    Note: You need to build the Autoware beforehand.

    The following command will start the delay estimation node.

    ros2 launch time_delay_estimator time_delay_estimator.launch.xml is_showing_debug_graph:=true\n

    "},{"location":"vehicle/time_delay_estimator/#change-the-estimator-type","title":"Change the estimator type","text":"

    You can decide the estimator_type with the following parameters

    • \"cc\" : Cross Correlation
    • \"ls\" : Least Squared
    • \"ls2\" : Least Squared Second

    Note: Only \"cc\" Cross Correlation will display the debug graph

    "},{"location":"vehicle/time_delay_estimator/#how-to-check-the-estimated-delay","title":"How to check the estimated delay","text":"

    The necessary information is plotted in the rqt_multiplot, which displays the following information from top to bottom.

    • First row: Input data processing results examination
    • Second row: Estimation results confirmation
    • Third row: The confidence level of the estimation results
    • Fourth row: Input/output error after delay compensation
    "},{"location":"vehicle/time_delay_estimator/#input-data-processing-results-examination","title":"Input data processing results examination","text":"

    Check the input and output data. It is also used to adjust parameters of the estimation logic.

    • input raw : input data
    • response raw : response data
    • input processed : input data after compensation (*)
    • response processed : response data after compensation (*)
    • data stddev : standard deviation of the data used for estimation (used to determine validity)
    • is valid data : Whether the data is valid or not
      • 0.0 : invalid because the standard deviation is less than the threshold (*_min_stddev_threshold).
      • 1.0 : valid because the standard deviation is greater than the threshold (*_min_stddev_threshold).

    (*) Smoothing, normalization, and resampling are applied as preprocessing.

    You need to adjust the value of *_min_stddev_threshold according to the standard deviation to determine the validity of the data.

    "},{"location":"vehicle/time_delay_estimator/#estimation-results-confirmation","title":"Estimation results confirmation","text":"

    Check the estimation results.

    • delay : Time delay estimated at each step
    • average : Average of the time delays
    • stddev : Standard deviation of the estimated delay

    It is preferable to use the average for the calibration results.

    The delay estimation starts when enough data is stored. The output value is zero until it is ready.

    "},{"location":"vehicle/time_delay_estimator/#confidence-level-of-the-estimation-results","title":"Confidence level of the estimation results","text":"

    The reliability of the estimated time delay can be analyzed by the correlation coefficient.

    • correlation peak : correlation coefficient between input and output (if this value is low (about 0.7 or less), the estimation may not be successful)
    • detection result : Whether the cross-correlation resulted in a good estimation or not.
      • 0.00 : Invalid estimation due to low correlation (output the previous value)
      • 0.50 : Estimation has not started yet or received invalid data
      • 1.00 : Estimation has been done properly

    "},{"location":"vehicle/time_delay_estimator/#inputoutput-error-after-delay-compensation","title":"Input/output error after delay compensation","text":"

    Check the statistics of the errors in the input/output data after the time delay compensation.

    • mae raw : Mean absolute error of input/output after the delay compensation
    • mae mean : Mean of the mean absolute error calculated in each estimation step
    • mae stddev : Standard deviation of mean absolute error

    If these values are large, the input/output model needs to be reconsidered.

    "},{"location":"vehicle/time_delay_estimator/#data-preprocessing","title":"Data preprocessing","text":""},{"location":"vehicle/time_delay_estimator/#examine-the-results-of-processing-the-input-data","title":"Examine the results of processing the input data","text":"

    Data that do not satisfy the following conditions are considered invalid and will not be used for estimation.

    • Data variation (evaluated by standard deviation) is smaller than the threshold
    • The car is not in automatic operation mode (judged from Autoware's Engage, Vehicle's Engage, etc.)
    "},{"location":"vehicle/time_delay_estimator/#visualization-of-delay-estimation-results","title":"Visualization of delay estimation results","text":"

    Before running the node, you need to set the is_showing_debug_info parameter in the yaml file to true for a visualization. Then the internal values of accel/brake/steer/test are plotted on the python visualization tool. If the superposition of input and response is good, we can say that we have a good estimation.

    "},{"location":"vehicle/time_delay_estimator/#test-wip","title":"Test WIP","text":"

    Execute the following command to perform an estimation on the sample data. This test should be used to see the characteristics when the parameters are changed.

    roslaunch time_delay_estimator test_time_delay_estimator.launch\n
    "}]} \ No newline at end of file diff --git a/latest/sitemap.xml.gz b/latest/sitemap.xml.gz index b62b3315464ff9fd2e925fde250c25e027f86f21..f50cbe43214d6d764dfd06c8c3077a21c42e485e 100644 GIT binary patch delta 15 WcmZ3=zLcF!zMF%?Q(`0Ad}aV2=>yXM delta 15 WcmZ3=zLcF!zMF&NHtR;V`OE+!_5@M@