From 67b04a4522d4470578923f167374ad5e5f73ecc3 Mon Sep 17 00:00:00 2001 From: Ahp06 Date: Sun, 20 Jan 2019 11:42:08 +0100 Subject: [PATCH] Added some console commands --- sumo_project/config.py | 4 +- sumo_project/emissions.py | 4 +- sumo_project/files/imgs/runner_example.PNG | Bin 3619 -> 3619 bytes sumo_project/files/imgs/runner_help.PNG | Bin 15286 -> 20732 bytes sumo_project/runner.py | 68 +++++++++++++++------ 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/sumo_project/config.py b/sumo_project/config.py index 236f408..21ba604 100644 --- a/sumo_project/config.py +++ b/sumo_project/config.py @@ -93,7 +93,7 @@ class Config: sumo_binary = os.path.join(os.environ['SUMO_HOME'], 'bin', self._SUMOCMD) self.sumo_cmd = [sumo_binary, "-c", self._SUMOCFG] - def init_logger(self, save_logs=False): + def init_logger(self, dump_name, save_logs=False): """ Init the application logger :param save_logs: If save_logs is True, it will save the logs into the logs directory @@ -105,7 +105,7 @@ class Config: if not os.path.exists('files/logs'): os.makedirs('logs') - log_filename = f'files/logs/sumo_logs_{current_date}_{self.config_filename}.log' + log_filename = f'files/logs/{dump_name}_{current_date}.log' logger = logging.getLogger("sumo_logger") logger.setLevel(logging.INFO) diff --git a/sumo_project/emissions.py b/sumo_project/emissions.py index 8bfd259..7cf265b 100644 --- a/sumo_project/emissions.py +++ b/sumo_project/emissions.py @@ -113,7 +113,7 @@ def get_reduction_percentage(ref, total): return (ref - total) / ref * 100 -def export_data_to_csv(config, grid): +def export_data_to_csv(config, grid,dump_name): """ Export all Emission objects as a CSV file into the csv directory :param config: The simulation configuration @@ -126,7 +126,7 @@ def export_data_to_csv(config, grid): now = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S") - with open(f'files/csv/{now}.csv', 'w') as f: + with open(f'files/csv/{dump_name}_{now}.csv', 'w') as f: writer = csv.writer(f) # Write CSV headers writer.writerow(itertools.chain(('Step',), (a.name for a in grid))) diff --git a/sumo_project/files/imgs/runner_example.PNG b/sumo_project/files/imgs/runner_example.PNG index fd427142f1dc93455fb48986d22d29314d40e5bd..639ce844a3c0072c39b1b5de7f7e23f1ebc7f677 100644 GIT binary patch literal 3619 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 literal 3619 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 Vt{ZKR0>0H1crfHZ)xPt${uiEuQhWda diff --git a/sumo_project/files/imgs/runner_help.PNG b/sumo_project/files/imgs/runner_help.PNG index 9bae82935c08f28395d418c5eafb530d519d4b32..3eeee9d77ea097ca66605e1c92998fe48d87b2e0 100644 GIT binary patch literal 20732 zcmdRWcT|&Iwp$bAk z=^zOmsiBvIme3}=-`qPhYu2o}-~2aOi*5eQeQJ$~3J~8y5 zqPpRE_H%B^8t6+!^*sLRW5t)gX6xzUUaPVUkMfZ?b@ivW?%swS^*)^CcRTm=dA8MP zokwpv@&|KxH1Ewr!&BpveHzMiR8&IQ*Up;1g&&p9+PC>PY0sVgk`W zLCyT72Rowki>9Rg{o_OO*d-UugBF3ryNKlJ=FOmAk1m-9LAt6S=7SD&O@eHwpyM@@ z&3m%mD#i36<*$2fgWAw(S3^6%wX-hgN9=wZ7ODlKo81}RF?pT zHGDx$(dn`QF`!QIT2EN}yV0SJrVJ7mA`@VW6s1h8Yt@?kYVd?%!#o zwl{0ke;p?P>RemrR1UrxwoTJlEO({EdOw=eDk%mF7RNYg^qAIs29ov3W*)C4cirgi zhfoMEamWMGN#g;WyQUM~+&lr4*3&a|h;3ez;K~jgoeS{gZai+nKAWkkd1Q{CVL2n4 zSyS!tsW47;pda)g-0|rKOIAx~$2@0CgEQyp`bMUr83du`XiaYKCu2^tuAinw31N*c z`_sUFvJ)%z4YPH@YC2SsrpgUiQi9v^$jhdgjj`lnoafF{Pr**u!Zm6h4>_)Us>8mzL4ym{>KspP0ETh8|Ii7G7 zZ(oXQv&?d;r_K#}uaz!~9m@Be%nVm)FRc`D3{Ww#QQ6CCK$1_~+%1sUl^+^wfYz}| z-@An8Nu0lr#C9ydb(cx{MB*0lr9o7WshPxYBStR{u2M^>O8>QY813P70z_-=A$;kx z{30ThQi}SWew=(WO)ilhnO<)&m#I|^A0}VX|#gou-f6{5tR5Kp`Ca!9k9AN&@t9nx_a0B z6{4dn!GW!@xuUAljed`%&i?4u{Lp*bajS0*o^yBFeEEL;9NGI;f)Jxaq}+2a?wg#w zvwRE1$U7&cTJw>9CgFQZg`Q{$gU-*yQ?tJ}Ald{=-c_d%GC49T?5BB4%BeCreb96+6 zg3T-zM;s$NZWBT4sK0YYq6!;yh(K(VVPVOu0pTy>=Hp#I`CtI_K)PD>n?Oc;M;z~= zO+(E3P`;yj8raVnPi7_$7p$vXf#?n9VI3?DYvgd_$t?{)x zy3nsQ#?Evt@w=XAq|ydc0EZBpZ%x+3sthS_lZ7y4bhoPK4maQ_U%^O5H`^f}hq(~1 z*}f9caO&Pw`+5ZF#ZZTCWb>nExM*ST)pMDhVh*}DJ_~PHnBL7`sIi9s1uZYkRMx7Y zgmJ?}LvjA+hC*1GWC3y)F1d_*AU}z-(T|yIYnfGU8a!CD=kw;IjSvIII%ny)opg<2 zQHK!d2+-pAd-5QJB&!glnP~=Oty>i$xQ?-#YTysnR(wgjH&SO|ncIwy=#a(AG)>fU zE_#&?m&B(Z32jq zPdOS)H#t$zlhd!pM3=M<_|#O@EJPGY_Sq@(rlWT^K8@(TaqDCYstfyc@(aUJpNF)$ z;@r3bX!L!xroP`^EcV-fc-SzwxNmhfm%;-R@^MnA1;lv@v^{CvBc)74xjoBRa-U^e z8{26_U#kB`qv(jTs!uF&Xb-vlr9yAszV0`{+v3_9;of4u}4{ zXs?9emR{mFYQqS9rxQTq_LTKPUV?xkZyq9fzU1P=|gtb}EMuEQf^R8bVspzA=6yu$7w!tb1=qIsPOI!tqc!}+A zIYh=s!CT6ozO#}Z%zq#Cquww#b*5Gekv8T z_2%W}w2}->Qy#sJ~O?1UwUnjwmI^nYi()eY|fB?-{jEmvSc8^V6pnC zgI6I*v{+ntgOH+d_>6NX8L7s&MV7zu#(8P+>3*i)q#4_e4yLug+En@5GhVZwmR>7T z4|2%!Xr60O^EEbntW(r?9DT{Lvw4w;jSjhEZpXPNpU+6Q__~tjZ=Lp{#ITuNjWEwm zTa0v_*sDc@aY&)&JCC_xrA^>l+H6-q)y<;~`BssjS{53oLFu%vd@@H2@dV8W{Ht$q z?6azB(G97dk(B|O=;qtqMs^<0UUI#rBOSY8`d(_`iuWtPJn@ted+-wS(`^bYRq7bm zd;*{KI+|*ljh#5YdLYn5e9#EKl;3wCcS(E3dHcL{l;B0z5v6M8#*4JZB-V=VM$T)} zG)~SYqr4BS0!Sz5(f!y)I_LE){zjhJOTe)IyHoR@Ue9arNl`8~=qcogJ7p|rce6vq zVf}>dFw6_ixN(|Zi)w-8&aj@!$6|302$Os;g3DL5^wj)_;GeR?NB74xcKRBxg-{X8 zLS{N~hqj#am(8PMSStEX)o&u$&b9kgg@*1VY+};$`eI<9bM9+Yf6Csk3(ZL;G@wZL zN7ZJ8I4Z)LEB63pwjO^V`%28`yYa3TnTlXK#OE8UiJX&@U-B903FC^~LV|n2L19+A zIz2W@!AFOOsggKQ=b_9BGJucv+@eRVXg@FVQqQwrlYtMlfq?m%U|GHApw1a**UmCT z-v??EK7hj*G|m!qJyKHb*yF*xWO94NphNtmK{trc}FTOx~Y5iBJIHcA#- zd&ddy9yjTgPc7mP5Rb#+f-QI`9?7mA8?~c;0ygHM$S>K@wooyc5qNV$NBi4m=zt<% z+A><&Kf4W#_9J7qKTTD^M+d4XBq$y}7zkX$`}I2aP*o%4oHaxS3Ky9_Ernzhv0-rK{x&x;$e~Pv7)MQb`vDgk*_GA>J$V0*$|MimB(JZ&yPN2p z#S&*Zg#IAB`2FR1_lxy#2earP>u8-Zip>QVYnN>ktRUsyHKJ`YtRFiZ0#n@l#Zt2> zZf?X+Px8>JboC(FzTaaBx{9|?6Zn<3{q9zu?tIF7>nQpv8Ky~4*;1G8JxP%rhe>v| z-O+;RFE0b8A9gU4+scO@Wbmc?9H3`)CHBb4kcQ)Mkx^dQz z>}Mzc9`@Wb6YC^@3gP3n*?A=em6>eqSDyPBm6N)ABb~)9cISX>cyd^Ea{OYu z!?hISm(b0zn$uIpljLV<@4;Uey`U|Q(p#z9{hz3Z2zIz5$ES^L($w+X@X~{q(T(sn z;CXDdP_H`o9%4z$^Li?xFJYq7(xOz%qndzcC^OhTG1>XGD|~d_ihg<=ku)(GM4_DS zuEoM_tzR9|YSn4LQad@VioM6)PGl4Q)%&AOHX4fhHuMCecGCwx>oUT(-+3{zQAab1 zo0)Z6w@)5SEtMVNSVcXePhn3WHQGZE_q5^?ZT?8cxV8>wk^KtC&nZyu;$|bR=9*^++RYzD$6tIx#{4cYF=WQ<+ zY$)8+eyJe0`w1*qWN^BfTvcsu*Phnl%5f0(`KY3}p|4U(jjgSdc~L*_D{*!r#tTIG zeEd7{NuG4%)o$*&EiY>$2lHfLfD$z`^Xiu+PU6?q6LrK@?dp~Ak2r$gX2xo-4St4K zgcGk)jRd5n?yvHv!cIMa|2s5{|is1oFVDuY#Bx%wv9mpTageDto1qdgYGNx~nb( z9LLL6yN((b-s%xk76z9f;xO&69YwwN8UgbYA}Xb&zQ7bz9n)-pA4NaJAf1~J*aeL9 zAIDtPinvP~=c94t4~`wTT9!|~Z#(EeNKHFOYg#EN37du>G*KLLOJk*jqt}+xOXA0w z3+_}6E&t5}o3QVIP5k`CQrUd;|K2ohg+F7sLT|Sg?J^iB(!nf)vcHINFOE$ONG*zr zBo3$=v0(`LN&1$>_v5vG8|5z)fbXR{%!PWvYq)e5RYyEBV6t+d|6&COz+1e;YYF5T zL4>~J=BxTP(IeX4X*hwU${4oU^5HKL&Cb{8?)to_XKl#XUbVX~*&5i+HM)AmW?_YL zcjEtY>(kALN$+UJ(Y>OtR}AGWi@FkGk&=VnrA>!~mT?^l7I?93$8qJvOww2mELPa3 z3Ch!K)*kh{2Bm-ZL%sR?I(#$Y3Ch7w#UeAM@fyI&esZ**wZN zYw5>FZL;3_A5~JrPta`tXOQGS{fRR)a#55xcg1Ta> z3mp__aZ;Ub%4;x|uFxH^23=>t>%cjo?RV8hGWK#*6WltNMUeu)Q2ntJJ(`+;IOTn3 z)69hq1$x5!dMNuM*Po6pEp%3!Waq5f)ra7IZwWOgnz!}0C=Q4Cw&+9#!RFfH{VC^I zK>pZx$H@<-)SPox+G~fMHC4Mb4m<(EnI&L3D@y(O|JK&0inS z6fZ^*^cDA>*SRfq%C|Cyv!qIGZ+iqCgtm4P`Zh6OxfP~9><6KvAp+DwKW0L3!3{Xr z;rfSBIJNR|k7<8SC*Ev=NG+DP=N8F1A~Mdg`qeQ`e}4PYf3D_%u@JOi?A()GkWW|M zrjCA#5qYMoZ({@hEWaDJuYzU%72TnI?>3;P=mt0YvXB_x?_Z#VU**Z%HaTH>W>XGq~{fFNUO(t)cmE}HR4Kqq!eRWfbra#VkHQAv@* zr!nuBM<$@ocQIhO?`83Tret6heYtFq<;b3WCcOkJxG6jynEDM zgw<^7@{`K-Z`@lmF~*auS&CbG`Vi~ah08-fx>Hw2jfxgJI5cMqzyqrfdZJ6$5w$K2 z#=#Rq62})h%qy0J&GS=<-`A;Jea`5$2AyY}rYimF5vt0Yhn@IPHkr4v5d9;?RB_tL zaZLWHhZDWxpGS}9s~MMvS|xp!}f5j)4EC#fZ;|2D13rUKCLtee!-z2OYm{KYmPZ2U@G`4!X7jsJ7J4 zsG(>WHNRwWpjSP_%eY-I(dk>Y4nJ;C^!5qX-dolgKlgXz?A$oG@CLS8zFTs=CiAGE zrA(C*Zs^ zj<~sb_?g;I>UZshvu@|IT_G;xf&;w3_tYGe7hoElT1rGj37f7`o{+(Z7RMT{ymri{ zL|ZUJeAMCb$)SEdcm}^I)SY|Oy{QB9B(`z6#ML`+jF-evK$m-wpva?6#=JU(R&zpbO!PBsMt{G(5jY*EYElm?1)COEc4ibGv*~FI%^o73b(Euyl_dNQ-kqN_lWI>&hH%>#KPV3U>Kc8vG zX#n%yX`b-vC=86_SU{w`9YP7_BdOT-H2 zDMFo9puWqM1*6~8==|UVnHgWm_ABffvMhc2X+JFQ`v)q#AjUtMa7c9tcazwlTy)WbolMcQobM#t2CEivJ{Teqw8 zwgs^-Bs-}GPP|Iusr@WOH|#W|T1UoK&t?_4MJqn9dWCH@V57h?3CxfO8>?l7TAuN4i(eEA93D0(7X0M@TAEA z$n1fLUejgIA^*sslL<1X`f={@%v1RWMKeD&$Pd2>5D>vwz%fKR%D+{vZ4o6W(K!rj zQO>3^3m23R_mOv%_MLHbMldpQ&J!(=t?WLwarOPY7aDHp_}j;T!!saK)No2=_Fzq(IaLJ=F+>_$xtwQ#6}czoVLw3;SQc zPtoS~R{w1e>57i0b3Od4iTf5EQj-?W|V*?R}CH{f$tOg$K$)@=JC{~uxx{3kI%Al zutBxG%`qlGeFG9lNslqf`sIXkP^E=X2r|D~t{kYJRd+SI*IC1isw&)2kn&cL1wK5fc-?Qct&)^E^+C0kwQv?K(;&a$6Mtv`}MsOO+EymV!PvyB)M@wo~KIqz(>?~K}Y(Zz45knhI0rwoChkI;B)Q5)LX)U%X;(+B z7t!H1u$r^FQ5L_nYZvQA{JNRh=}|Kr>cz>!0N63*|NIb5B+pTN>%ec zYKyXktg5mp8Mk+VC5*2{NbgFz#A<-E)EXIhAG?U)?!{aZ3OEVRt`(U{cFJswD0idYp=^V)Q84`AvBT*IJNct3H#<4M<3wX3o9Uau(}ZI8b$W9Tn=cdkBhU5 zVkI~1x}#j^>OXtk`T%*!bWuCftiX%?_JYJ8BRG^v&r`gn< zE*=J~&OmNZQEfyDHe8xPt>KwXDZ)Bb4!%E~&bk3VPu1`sd#kG0<*q`>-$C9B6UeYl z-R)bfpbn}nw|^s94UFD#Jtx>a0X`)+?(Rkg`aD4%na`SYxwv2L4dqJAqC|sS!HjCm zV1Q)fTj92Klsj!mgYU;592!G-3G-2vn3mBv==ncog>lfWnUAe%Kl2`xfzbm@^!VkU zE$5L}Wb~A{Q|V-=fiZ%CAV+dSJ;^Eq%yob3OC0phpEC5nMkTtYjx@ZggqQy2J-#$~ z;P}cxcg#=i^kyGU9h*p}ogIvxD&|-egP^o89FYzq7Ij8T+g7eEUZ2W)h84Rl8MQog z|3kDv`&Y8_nxBwIC^)9Kfm+@!k(L|eS$rK}p%f%rp?VxX-qnYZ1VPT_1|Yr4fkz-5lR zkv328PvLrVPS3EvU_+ca+p(=8tH70%9Yn6AO?E0jE6h*59dl{L;GXube%tIIm+lf% zmtM1PsAtB!O)Y2k)@{%gP65+Psb57bn&HW(aN*|h<{KK|nMKrX6nv z$(fgWR&6mDz3lX{V{P&g+|kIB`9C1J+V-)egVyEplH5oY?Tnj!hMza_DPXZ(v19o^ z+i)5F!`r)PV8z&iIS}jD-DeR!qae-_9R%`5Q_Qdo_?c7)w6ZxU4l8wk)--ELw`^BDsl(cC^ENt&i9Zn2kJa! ztkwjZ9XwjRBD2W(ZHD^B;v?>ynDm}tkEn#cDbme?JlbYDHWlm&oD!1)-$mkROxMcszg?vLFg1nqj6A=Zzswml zY;;Ah-3Xx)jbwv7c}q>Y?fa@ndu2n8>CB-m+1*T=yJP8_YzJ^;>u74I~gva%Y6RFeKQkg+c@pn zKUgx4B*IkB3y8Be}SM*9k%1&#={ie&0n6RBJu^(*yO`>TmDQ`;}* zF~tU4`&s#g6%)00;Nmz=NC?H$np7QS8QY59$(lu{prCU&rWffwRcf9YO?n;G*Acrm zS^Wxz4)^m)M(mu_cPCwerqAcU@y$ErmsUIC+C3HRa2gOFiu^_CRD#ze-2*cZEkCi` z(;pcW3-4x4sdSa1bBf+DYO3Xz%_z{`QhPDa%H5=U`oWSt(DYz9=F49j}L) zIm`EGJk-6H2%$FiA zylx?b51wPy#A^yFW~rttl0)5q8?pMu6~{8&SzAurehrw?ZG+CWT?=EIO}yijl}1{= znTwQ-3C)qbVS_5sM&7LaL?|N71wTR+hD&gopj7hUZ0!$Hf;{0x?avbMCvhlY>^k-p zht8?B2GriWXWxV7AJSMttUS~%<3=@`I&ZY*p^7UiL@RNF%(!rJL1`I$4QLsnnY>e1 zy`EuhLW!WCFAqKTV87=X6S#&5b^TjM>IyAtedNp)8#4Eu@s+I55!dFvRqw&pXM7z@)6NC!FtpFPuX%;XR`^}* zNx{5alWpmvfNxaY+4{^cQ^CxcmCx^_HkJ2gwDy}m)BTXQtP8n#qb@|=`O(Ub(>`eK zoAI+?BP2gUSvjksYII=**GHH}E%*fFTlbs2aV~Ij!C1b|V7-^l0*~1bcxbcsQ@s~w zuM$1u>$PVz)Q8~W{JUjTvG=+|Ae0FpMWL)N1oF}Hg}LDFGWJza&j(nYPTA_ke;Hw< znNC4t1~b3@+IZ?z^wUk+U%0A);@rDR6+7ER?+DN4I2>alee{{IBpmG6`}4#3&5TY{ zF4&V$PLLqsSfABkw{b!t*Bp2oSuG`MqjMEiZ9y=QN#L9@5KwM+0?M;^U@ z?11l;Rer&vw8mt7O2(W+&uB1R1bNO~UFWBq?Ed`SD&OJxyOSmoo~z%QH@3jhg{zS9 ze<}7RGw%HkL$A?G`F6#W9;jK(C6Un`op@tW8f6((MIT|O>xi$h?QFQDHHMUIMaf!a zz6={atlEN&pJNl;N0|N=`Q-o*ppb5wq1wbqR-yUIpmIhcGY|kGrN!LE0_@_Bxz6p6 zu_Js9kISpLMtLGp=2zfYdmOzf$E1ECI9eR za+|4=atkO0n*_E5v~nYKDbP37fh}d5XkfrA?gwrSH$aq<+cW&--0O#O$V(3%oxy*u z4=EWO{vpS>FtGWAot6MxZ*--hmnBHvYKV_yQso*Ze>zcBpuPPkAK8qWO0nX}k0sfv zYXd1WU80P%ehz|PwK?y4cCT5diU6? z{R37;-an;@ykc5^6Q*ZaNWn4R-k=;ai36~<*(bqk^M1+(l7%ob&X>EKA5t|SQJ^yC zkUF{K?0FLK4kHo`rmSm!#?#^v_2~2~77mBF!@A$Hw{gRO>DibvWY@}FiQj;FW-_JU z5(VoO{Za&&UsPjxxrVba59ZqP7{f?4X+b|LoiU(r#<~YQxEQS$HvEcsJ<_qH4P$i6 zBrro-02$D%Z5wxv>b1as@6-T;w$0RcHla0f2H2j{c(XiZXXvPHeSOP%khFfx^0>;G zIM489(Jy)xtbiX0>p9d2v0=A*MB7nC^R_HG^pC_ZP6DLbA+|7j9Gk63P4)KwrTF-N z%d1hnwJT;MNfWcU_pW14&fT;@Euh;2UB8v6T=|TspR?mINTLaV!fG$;;bk$-@Wjwu{$H3^B zI`H#;TgSgAU@eV$v5VzsDdl?0l^ygMY0@l?QqH49=GeRS{?&>Zow<>_$!zT z%)e&0f$zCZEe;+CsPX`9N6i|NuZ?0Wx`y_MX(`y_zc@ysmnU|#iM02zcL?_alkT^j-S(d%$%WC>8F%4 zC#i18Jh%GQnr||&bXk=1K~rg1y3|;j*5`sBS0&z<@p!6ZCazh!QOsOquVP!pzo*yF ze*0RylZi+FK}YZY;r?O$y!pc#3`8uc>Z;NBaP=@weLtb4q$)a{X-K{~0!KRuI1vLm z#d@0ICcZ#IIUGj0>`8{<&u_IUr1Ydlas0x!m1=2x^EFO9c;ErEkrjZd1NS_<6e|Sk z%05yc^;|HOlp=FR*aO~Q{KSwp7Jl^ek0JN&(pLSU3-Txp(4SNzbCog_x!9xDP!mk;dgM4wvNbvf8~9^B6B3%_ zgQ^l7O(KTo;*r(siJlBxW?c(UuWLUms($lw=Lzn`k_RucNMt{tZZjr{2U^VsrIF)1B-4}~rdV=v#({9|)EJHb_`mOCTHS&nGnLx9X<*$M!q6YjwSS63Cd|Tk#z?Rk7x{=eB3o z<eGx?)oEO}Tad^c@wpv~bzY^_sU|;~* z;hb*@Vs`lAcB|S3I@g$OQB>4Ic%a$>HpnH8)?ZW= zV0=YN>%BhW4*T?c`n;R`F4$A1GHbMplrmQ9B-}{ZosXDX3lH8WOKDQllQW%~H>oBV zbS?|rIBA^<>Y!XsQ%n?4kg|naIf`BG(7M>2r}}XrQ<2)2iE{fL+fhju4_? zr#iJQ?s$L?cBL=JpnSsZvecA1+t>TGFwcCt^A-*24QbYbgB z1fy43K@|5+g|qN%X)dl{Wp22-@sA<t7#vy8x!pq1+S-NCvSphbkiV}F{%XWZv_ z!YDVIg|b7Z6b$W0yg3W+V?>O*_#Y9!9Q>5xQc}5ady9}_56E5XwfIKlkVzirat(uL zIg}&6I$YxR*=UiKNN;RdR@N401&q`1ZVc2Oe{`#i!W3E8ui;J0zB|~+j>@N?8L6fi zD9BuM{O9QEc$e?K8ZhFhW=40#HMWlpAK6kzPm}JK*F33VuQC;1Ogy>}BiuCGlH4(y zB-Vp_w&iUV=It+yjE55Hh8J&EC=Rm=?q_C1^xgyd8o1A^4x`Du*te31i^>bTd_ z`aGx71gL{UHPLhwEEN;7@>wEhLW?fAA#eDI#e}kfIwuV%Zo-p~t#rSnn#cS7#I8m5 z)D=#0*?luB_&Ram;!u3G-j?tGO$^u*l#; z4+;@0j&EK+_TQKRj)coxCDtBXAe@MKIs6JM3fx-MY&qg80v`0*lxg1!P^-*W0rv@3 zd3k|7D=o9iU>9dMq*;ArVg?*me7zjaS3_e{EkLXkC;LYB7O2%a`fkK~7v5Rix|hc6KNZ%*Nb|xwu!mnG}GI;^$w{Ie2trKK;u^ z_S|3SmZtf@jxVX9KHXL5qa4+mGBY@4i%qiq#$V+^kh=3G-Ki}t_`)m$)#0^}z7{rZ z+B-ikT${GH*$k3z^%|I<1NRQDhSGq1${ne30^fcgX<rgZRNWRBX}aZoZL68}rF^%PGzrlcIGXthdN>V_+DK>JxIGJCKi9 ztRY^f4U@+#*WBWv>!CLM0*%p{WJl2Pd=Qks-W;BAv*z}u&!@P_W@)@jn}cupIwOX4 zTFa3DaV1PEztbk<-zUG}xlFpjO>L)}wmj0Ka;eK`xn*@Ho^h_1&w3!r?zNNl>5uyi z7A3t3r&mX(eymJ(Yz6Yb-R^PI9(gesoVwSLnd60Xy>S(pZPI9PglsD~^T6G(*=6X_cmMyP_d=%2#^DCxn5= z({!TBkJ#VvY~gyx+E%P}39}*o_J*5$qn2~v9iS1o+e1Z3+&Z^9nV&+SVJ{n)Yfw#D z(8DZLWhU)Bos=q@!LlK45!Vs9|;5%0lW%qMFMAT%z>NX)kJJqN}Vhf{n)*kpiq#S5p>4)E0U%MB3QUF>=EH{cTJ@tg6sxh?Hj8l8s^^U9z zxB9Vapf89&33n!(@%@>Pup3pYG&^<+p})Q96FnR|G+DP9+&Vi@*pvRO3Kgc!vXt|_ z6o>9$HjaNj;p;Z!rI2e#<`EqZNHuNU>u*t(s?l&_Y4%!ff~u#*rsHu~_$e&1{&^=1 z+>V}cS1^0l3EWj&E1eAT^-a$SmReKs)9SIv< z5IX;f+OQM(9-BfoIyOl{RpBJOa7z=}dBl%ktuRCeY+S+@#y@Yc>qt8t>}b}9r<`a% z$DIfMe33mi;I!Y4D2!d+_(yhDv-DO^rk!c8aOw(iSvVGbcO-I;7kkuVy=%`kjS63; zG4@punwt6U5i-tpa6sOz`m`Ij!%WI@j$>PU71fa*}f(Wo3I9#fQF9s>3yO2(F>UEa{ERjjih+TN!`494$R?db^(ur#S-}@@~;W zBDQcA>nPK+4D}gc#FxD#ZZHl1J$3KAuiP0#LM1{e+&%M2|D9^PnboHmmv?#QwdcZ- zQ7?nCW1-yR0V_rab*Lk+nbl?^a)ZRYDlM8ayC|p5f&WzT757-|eW3Z>6&I(XKq-%X zu^+AbGohOSF;>dt2F`g^5+Y=RLPN?2!9WF<;frWB!=laB9_RP06WlGL_)PF7HCm_1 znoo+-ho6tOFW0xoS8iw0f~T1^QG$jf{}lQcacSuCZI4nHH8s%Azzia$L9EbSiD|y{ zSt@T8*ysHO@7Y+hSc+4(PN`$A%{J_0giqgRH$36!sg>zp8M1Jwyw{`IeMK|QIH=zF z39|l?a~vmS$o?Y=YTzzaq*x*27X9c%(rxVWfi+*fP>K|tJq+ZVZb}^R<*XmS=;Tp6 z-;>_o$+Bv8~WK4adM@vLO!95;8vo8arQb|7F6f9Ldd=3j`+HD{yI9l>1=%T!%Q z`8v(#f4;Ij0dGt$tSx!4Kh4*hkbnZpc%^>h?kB{Wr=OAG5-!;AR*RTr`~D?OP|X!u z&z;eCht*VBSziV&E_mN9Sn-hSq<5#(lKsu4IAeueD?R*AhAwwPBWecd_M|vuhO5l} zT-o9&k9c;EXxm5 zmyBP`B^nq_SM!Qx_ALhErW9{Wu{tN8F+%}Z;Z(n^&#@kHkFFVWgW1jqr$SH+_$~jF zXSKTIwEBmfiY&F7zYp|nXgI}q0Y-tXV|&i~(s8Am06{VEvjdH0vP1x6=y z7H}<5Qv1*94ajB-MiuTm=;YPJcSz`fNkJGz-?NJ~7rG zN_FDo-v_)0BH&Yf8`Oq{eN}M1SufPG=d*N|-&03dzn;5A?{k@j=wlFioj zfz98klASoh1T_hMa7;c(OZyq`!)uawf4ZHfmg)>P{Z8|kC^iM^1lTDI;Z;3ei)|M;|-N3z9_Lmvp;OhQce8u@Sura(>K=nRW z48?ieDow0#p}tc;>#*9RRIljV{t|B!iwO$}x;J;PVE4-`h-xSmo>IR}Q~prT{w89o=~IRJ?wP)EK>tqt7)( z9O>XgY&_+E$e$7L14vk(-C#t{Q*|-2`mnPQZ_^}LM{NbX8xnx@`%M3`<8cLy3#<%P zDPUGvfg7RHc~g@4#%n>OF;n{Tx6-k#eNMpN&=pyq=Ted#$MSciSa)#4vkMD7fqD<^ zkb6#pf9Ru4%fTV*$^reneRQtp&fMK=K*HcEYtVrejjj9lKMYB=R|cZW9yU+iOk}+0 z^STb_fk|c1oWoYazJV3Sp;nVOAOh9tINtG9y;KF#NFI^}Tx?>FLo4edQ*OaCQj4m; zbR!;pF=|kqn`-TQ<22f=UGGq|651-_b+WVeyO0F<>-jHU0qga^h@Uq0!CVF0FWoLY ze78cT4q30*Ewg1<{@oJj7VL=ng-~$I_}`Y`9NOTuAxwfR4`kTnI`-`pP>v84Xq#?l46L-%N2Ngw7aq-K3^Zqa#@O5qWj>j=1O{KUNRAc^N zsu=62XX4C$0n|d)#diiqL`tFCV!D#fMNTLF6*1{@gXsEXj?W}5giY>>O<1kjL+x)B zWw~|9p`l>Y@nJZ2B)4N7h~`^ek&o+B_*%8MIiz>&R=FCAErp-huDf@xo;Ue$mQnKM zZTj-{Zh%bbm&FaShO3mVPPL_R#Jx&R*OX2_;J&!*^_KWgq}JCiX*6*rFMxuwNnym-w6@-%gp?DpZh%b-t*^q&UwG{z2|)A zUB2J@Dz05LP5Wl+gu%oGw`GWe);A2o^_8%ct4j@-MO)3u$FHb3?fvx-(!KI3HjRA* zki0&jfql%~h3&hmZo}ixs3N;+`uhy$9FKKwFk#rjH7#q#Jo7LOI631xzl7E~ZKzTrbQq)!P%D-3q{>Yx|A1-G<4( z7rhTJXH8eM^Iat!@&4T(qyFlhUrwJhl_EwQx$SuQXRFvUCv(b}evN}K}509_(~>b9(BuIwV^0Yxw#MQ zCMdgB>t~zisWa(qj(?#P>=tn+ zO|g_P)YVy>B~JxdsVM~~df*!m*-!A_Qz zITle`>bfs?lFY^^E~eTYU&OdbU0Qk=_<19?iE{YBO%L*%AWg6FV<#@Qv2lZ(h@WR4SkUnQF^AXokM$OTVbZ4rPn`MdQ{K1 zGse2Jr0OnXT`5b?I7eLPR;->gHlPwflieJfA!n_Hfr8MWM@Ez&;K>+dpj2zqgu4xW zL^^m15`Nm>q}d*=RZDU$BU-do*AJFoZgqc*)TIjt-uZ;-z)1y-x{n29-t1O2Oi37t z-Gp=&R!R5i;!5hG7N0Q{p;DdH*Epvf`ahh)umu1Jmk^hG;r!G)dq}AQz5S8d9eI;{ zE39Se;$&=UvWs-J%yqahNOF#by34qTjVULCFtPQ4z&rh}HTx|Af3;o_gT1{N0|*@! z?PRVttltJc{`=n5tS%CD?FK=5p5{ozl@l`^o#z$IdU_kpXcYEB}k;q`DF+ z-Xr8I^yBQ^N0t*u%Nhh{MeT0oW|Z3^XiclAWd$}SUZX8!X49-$mBBhNEr3~xr8+6A zjp+aR_sT?<#ZHorSK``s^~X0P+)#$iR|ok0uEn$pUNOVwU%*4QN8oFv`24Ia)hZ0FeT_j>G>xxBq#Fd#g6Cy6RDQjDm@2=UQq&Gg#n}%4grNc zpzp+?6_n<94d~?+ivWS2%1W{$7)749Pkz#n@;)Ax!uo2)D|+}9F?Y^zEDr8&=5Z4g z4?WA#?q5E6U+grH63MggDxDs?UV)5n6^n9R1W~@-$wL~xnaU%h{dr93Ittfobrv-F z3f@KndmKgBPmIQnKpef$5@~e@puP!)c_5~R$1_V!(iYVVK*h*P9WNmmiM8z<9ZSye z#A;W4MXKBO%vWL9;f$JW&&2&5w-Z2KtO<}Of3rbZt59EJdaN086_f8F>AoZbNQ$Yy z{F}-9^#W6ZMJzRnUw#N}gupABN&_7&86Dq0I4u~OaT)9t9F6_^?QvNVv zi&$N`J=m5x!UF&VhpSvi1acya_aTgcXkm<0KIMt)zn~f#bhwPBtFCna(Ffh^tG$@^y6)JD}jc zNF{>guL<_Vlb>hSfZ>haj6F?XN@goEr4Dwr55lTVa~{%$BnG!-3t|gtl{N@-UWBjD zo5J@D(`=!U3xewu1-wZpOXeyy{ zA|&02Gdh@#M<4RjCnVrg{-ydUK(FzAcQ1R1v0cDfd2@-9#S2)YIFEtmMn@Vv4H`$2h1%hYlU z5TogcW_ZYA)fxp|{wN&Ks!(0fOTDu-cWm%;CA8@S@xzDb(wb7wYUJ3+E-UVoEl<`X zJpim`h0|Kg%HP0C%?L${KaeaLN;A@xE$bg`pic!#S=Y=AX9lVz3HKcwry7q9QkY;< z@Lu%0-k-R-vfaonmn!@*4)4t&fjNSCwY%6ss)8(h#Xs@688qjU8f%@%82t|S_Jn+! zb-czU(7EmD9jG@{-6!skhnd+Gl@#eK-MXXtM}mOzazKtxt_ICC6)L4;Pm;a#vpy$N zP!7x!Z;kW)`)xTkqV42v88ICA7!m>adr#15FF2l5YbUp(hWe6#jY!!T4SS+9K)SBY zRr{^ht|zQYV=h)UWmJaYRmR9Bx@GCjloj1Nbm$jASA0Ku_$*YY)kv(D+&h|oUWkM7 zk6v7HwYZO>E4*p8u_`kaR{X1v_B>m^5_=K~(d~iW(?3&fPsF%D!%`RCQQ+~Z2@-KCh Bt8oAT literal 15286 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 YJ<6ralee{nU5ebiW_q>c%EQ0^9~K=xT>t<8 diff --git a/sumo_project/runner.py b/sumo_project/runner.py index 2fc2b44..9c1cf7f 100644 --- a/sumo_project/runner.py +++ b/sumo_project/runner.py @@ -33,10 +33,22 @@ def add_options(parser): help='Save the logs into the logs folder') parser.add_argument("-csv", "--csv", action="store_true", help="Export all data emissions into a CSV file") + + parser.add_argument("-steps", "--steps", type=int, default=200, required=False, + help='Choose the simulated time (in seconds)') + parser.add_argument("-ref", "--ref", action="store_true", + help='Launch a reference simulation (without acting on areas)') + parser.add_argument("-gui", "--gui", action="store_true", + help="Set GUI mode") def create_dump(config_file, dump_name): - + """ + Create a new dump with config file and dump_name chosen + :param config_file: The configuration file + :param dump_name: The dump name + :return: + """ config = Config() config.import_config_file(config_file) config.check_config() @@ -62,27 +74,32 @@ def create_dump(config_file, dump_name): traci.close(False) -def run(data : Data, config : Config, logger): +def run(data : Data, logger): + """ + Run a data set + :param data: The data instance + :param logger: The logger instance + """ try: - traci.start(config.sumo_cmd) + traci.start(data.config.sumo_cmd) for area in data.grid: traci.polygon.add(area.name, area.rectangle.exterior.coords, (255, 0, 0)) # Add polygon for UI - logger.info(f'Loaded simulation file : {config._SUMOCFG}') + logger.info(f'Loaded simulation file : {data.config._SUMOCFG}') logger.info('Loading data for the simulation') start = time.perf_counter() logger.info('Simulation started...') step = 0 - while step < config.n_steps: + while step < data.config.n_steps: traci.simulationStep() vehicles = emissions.get_all_vehicles() - emissions.get_emissions(data.grid, vehicles, step, config, logger) + emissions.get_emissions(data.grid, vehicles, step, data.config, logger) step += 1 - print(f'step = {step}/{config.n_steps}', end='\r') + print(f'step = {step}/{data.config.n_steps}', end='\r') finally: traci.close(False) @@ -99,28 +116,41 @@ def main(args): args = parser.parse_args(args) if args.new_dump is not None: - create_dump(args.new_dump[0], args.new_dump[1]) + create_dump(args.new_dump[0], args.new_dump[1]) # (config_file, dump_name) if args.run is not None: dump_path = f'files/dump/{args.run}.json' if os.path.isfile(dump_path): with open(dump_path, 'r') as f: data = jsonpickle.decode(f.read()) - config = data.config - logger = config.init_logger(save_logs=args.save) + + data.config.init_traci() + logger = data.config.init_logger(dump_name=args.run, save_logs=args.save) + + if args.gui: + data.config._SUMOCMD = "sumo-gui" + + if args.ref: + data.config.without_actions_mode = True + logger.info(f'Reference simulation') + + if args.steps: + data.config.n_steps = args.steps + + data.config.check_config() + logger.info(f'Running simulation dump {args.run}...') start = time.perf_counter() - run(data, config, logger) - + run(data, logger) + simulation_time = round(time.perf_counter() - start, 2) + logger.info(f'End of the simulation ({simulation_time}s)') + if args.csv: - emissions.export_data_to_csv(config, data.grid) + emissions.export_data_to_csv(data.config, data.grid, dump_name=args.run) logger.info(f'Exported data into the csv folder') - simulation_time = round(time.perf_counter() - start, 2) - logger.info(f'End of the simulation ({simulation_time}s)') - # 1 step is equal to one second simulated - logger.info(f'Real-time factor : {config.n_steps / simulation_time}') + logger.info(f'Real-time factor : {data.config.n_steps / simulation_time}') total_emissions = Emission() for area in data.grid: @@ -128,8 +158,8 @@ def main(args): logger.info(f'Total emissions = {total_emissions.value()} mg') - if not config.without_actions_mode: # If it's not a simulation without actions - ref = config.get_ref_emissions() + if not data.config.without_actions_mode: # If it's not a simulation without actions + ref = data.config.get_ref_emissions() if not (ref is None): # If a reference value exist (add yours into config.py) global_diff = (ref.value() - total_emissions.value()) / ref.value()