v2sim 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. v2sim-1.3.0/.gitignore +39 -0
  2. v2sim-1.3.0/LICENSE +29 -0
  3. v2sim-1.3.0/PKG-INFO +73 -0
  4. v2sim-1.3.0/README.md +48 -0
  5. v2sim-1.3.0/pyproject.toml +39 -0
  6. v2sim-1.3.0/v2sim/__init__.py +21 -0
  7. v2sim-1.3.0/v2sim/gui/cmpbox/__init__.py +152 -0
  8. v2sim-1.3.0/v2sim/gui/cmpbox/_lang/en_US.lang +14 -0
  9. v2sim-1.3.0/v2sim/gui/cmpbox/_lang/zh_CN.lang +14 -0
  10. v2sim-1.3.0/v2sim/gui/com_no_vx.py +33 -0
  11. v2sim-1.3.0/v2sim/gui/common.py +5 -0
  12. v2sim-1.3.0/v2sim/gui/evtq.py +100 -0
  13. v2sim-1.3.0/v2sim/gui/langhelper.py +34 -0
  14. v2sim-1.3.0/v2sim/gui/mainbox/__init__.py +991 -0
  15. v2sim-1.3.0/v2sim/gui/mainbox/_lang/en.lang +157 -0
  16. v2sim-1.3.0/v2sim/gui/mainbox/_lang/zh_CN.lang +157 -0
  17. v2sim-1.3.0/v2sim/gui/mainbox/controls/__init__.py +9 -0
  18. v2sim-1.3.0/v2sim/gui/mainbox/controls/_lang/en.lang +34 -0
  19. v2sim-1.3.0/v2sim/gui/mainbox/controls/_lang/zh_CN.lang +34 -0
  20. v2sim-1.3.0/v2sim/gui/mainbox/controls/lipad.py +57 -0
  21. v2sim-1.3.0/v2sim/gui/mainbox/controls/network.py +710 -0
  22. v2sim-1.3.0/v2sim/gui/mainbox/controls/pdfe.py +65 -0
  23. v2sim-1.3.0/v2sim/gui/mainbox/controls/prope.py +82 -0
  24. v2sim-1.3.0/v2sim/gui/mainbox/controls/rle.py +82 -0
  25. v2sim-1.3.0/v2sim/gui/mainbox/controls/scrtv.py +290 -0
  26. v2sim-1.3.0/v2sim/gui/mainbox/controls/sfe.py +79 -0
  27. v2sim-1.3.0/v2sim/gui/mainbox/controls/sid.py +48 -0
  28. v2sim-1.3.0/v2sim/gui/mainbox/controls/utils.py +40 -0
  29. v2sim-1.3.0/v2sim/gui/mainbox/cscsveditor.py +80 -0
  30. v2sim-1.3.0/v2sim/gui/mainbox/cseditor.py +375 -0
  31. v2sim-1.3.0/v2sim/gui/mainbox/loadingbox.py +33 -0
  32. v2sim-1.3.0/v2sim/gui/mainbox/plugin.py +68 -0
  33. v2sim-1.3.0/v2sim/gui/mainbox/utils.py +42 -0
  34. v2sim-1.3.0/v2sim/gui/parabox/__init__.py +172 -0
  35. v2sim-1.3.0/v2sim/gui/parabox/_lang/en.lang +51 -0
  36. v2sim-1.3.0/v2sim/gui/parabox/_lang/zh_CN.lang +51 -0
  37. v2sim-1.3.0/v2sim/gui/parabox/lgb.py +78 -0
  38. v2sim-1.3.0/v2sim/gui/parabox/pareditor.py +53 -0
  39. v2sim-1.3.0/v2sim/gui/parabox/utils.py +33 -0
  40. v2sim-1.3.0/v2sim/gui/plgbox/__init__.py +150 -0
  41. v2sim-1.3.0/v2sim/gui/plgbox/_lang/en_US.lang +19 -0
  42. v2sim-1.3.0/v2sim/gui/plgbox/_lang/zh_CN.lang +19 -0
  43. v2sim-1.3.0/v2sim/gui/progbox/__init__.py +45 -0
  44. v2sim-1.3.0/v2sim/gui/v2sim.png +0 -0
  45. v2sim-1.3.0/v2sim/gui/viewerbox/__init__.py +465 -0
  46. v2sim-1.3.0/v2sim/gui/viewerbox/_lang/en_US.lang +95 -0
  47. v2sim-1.3.0/v2sim/gui/viewerbox/_lang/zh_CN.lang +95 -0
  48. v2sim-1.3.0/v2sim/gui/viewerbox/gridpage.py +89 -0
  49. v2sim-1.3.0/v2sim/gui/viewerbox/optbox.py +46 -0
  50. v2sim-1.3.0/v2sim/gui/viewerbox/plotpad.py +45 -0
  51. v2sim-1.3.0/v2sim/gui/viewerbox/plotpage.py +225 -0
  52. v2sim-1.3.0/v2sim/gui/viewerbox/srd.py +39 -0
  53. v2sim-1.3.0/v2sim/gui/viewerbox/statepage.py +104 -0
  54. v2sim-1.3.0/v2sim/gui/viewerbox/trips.py +284 -0
  55. v2sim-1.3.0/v2sim/gui/welcomebox/__init__.py +225 -0
  56. v2sim-1.3.0/v2sim/gui/welcomebox/_lang/en_US.lang +22 -0
  57. v2sim-1.3.0/v2sim/gui/welcomebox/_lang/zh_CN.lang +22 -0
  58. v2sim-1.3.0/v2sim/gui/welcomebox/v2sim.png +0 -0
  59. v2sim-1.3.0/v2sim/locale/__init__.py +1 -0
  60. v2sim-1.3.0/v2sim/locale/lang.py +264 -0
  61. v2sim-1.3.0/v2sim/locale/zh_CN.py +207 -0
  62. v2sim-1.3.0/v2sim/osmhelper/__init__.py +1 -0
  63. v2sim-1.3.0/v2sim/osmhelper/osmBuild.py +140 -0
  64. v2sim-1.3.0/v2sim/osmhelper/osmGet.py +324 -0
  65. v2sim-1.3.0/v2sim/osmhelper/osmWebWizard.py +551 -0
  66. v2sim-1.3.0/v2sim/osmhelper/ptlines2flows.py +610 -0
  67. v2sim-1.3.0/v2sim/osmhelper/readme.md +2 -0
  68. v2sim-1.3.0/v2sim/osmhelper/tileGet.py +283 -0
  69. v2sim-1.3.0/v2sim/osmhelper/typemap/navteqPolyconvert.typ.xml +9 -0
  70. v2sim-1.3.0/v2sim/osmhelper/typemap/opendriveNetconvert.typ.xml +35 -0
  71. v2sim-1.3.0/v2sim/osmhelper/typemap/opendriveNetconvertBicycle.typ.xml +3 -0
  72. v2sim-1.3.0/v2sim/osmhelper/typemap/opendriveNetconvertPedestrians.typ.xml +3 -0
  73. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvert.typ.xml +45 -0
  74. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertAerialway.typ.xml +5 -0
  75. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertAirport.typ.xml +9 -0
  76. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertBicycle.typ.xml +6 -0
  77. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertBidiRail.typ.xml +7 -0
  78. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertExtraRail.typ.xml +5 -0
  79. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertPedestrians.typ.xml +10 -0
  80. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertPedestriansNES.typ.xml +11 -0
  81. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertRailUsage.typ.xml +17 -0
  82. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertShips.typ.xml +5 -0
  83. v2sim-1.3.0/v2sim/osmhelper/typemap/osmNetconvertUrbanDe.typ.xml +13 -0
  84. v2sim-1.3.0/v2sim/osmhelper/typemap/osmPolyconvert.typ.xml +66 -0
  85. v2sim-1.3.0/v2sim/osmhelper/typemap/osmPolyconvertRail.typ.xml +50 -0
  86. v2sim-1.3.0/v2sim/osmhelper/typemap/visumPolyconvert.typ.xml +8 -0
  87. v2sim-1.3.0/v2sim/osmhelper/webWizard/SimpleWebSocketServer.py +716 -0
  88. v2sim-1.3.0/v2sim/osmhelper/webWizard/__init__.py +17 -0
  89. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/bicycle.png +0 -0
  90. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/bus.png +0 -0
  91. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/favicon.ico +0 -0
  92. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/generate.png +0 -0
  93. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/map.png +0 -0
  94. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/motorcycle.png +0 -0
  95. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/passenger.png +0 -0
  96. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/pedestrian.png +0 -0
  97. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/rail.png +0 -0
  98. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/rail_urban.png +0 -0
  99. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/road.png +0 -0
  100. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/ship.png +0 -0
  101. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/tram.png +0 -0
  102. v2sim-1.3.0/v2sim/osmhelper/webWizard/images/truck.png +0 -0
  103. v2sim-1.3.0/v2sim/osmhelper/webWizard/index.html +138 -0
  104. v2sim-1.3.0/v2sim/osmhelper/webWizard/jquery-3.5.1.min.js +2 -0
  105. v2sim-1.3.0/v2sim/osmhelper/webWizard/lib.js +62 -0
  106. v2sim-1.3.0/v2sim/osmhelper/webWizard/script.js +540 -0
  107. v2sim-1.3.0/v2sim/osmhelper/webWizard/style.css +214 -0
  108. v2sim-1.3.0/v2sim/plotkit/__init__.py +2 -0
  109. v2sim-1.3.0/v2sim/plotkit/example.txt +16 -0
  110. v2sim-1.3.0/v2sim/plotkit/plot.py +728 -0
  111. v2sim-1.3.0/v2sim/plotkit/reader.py +251 -0
  112. v2sim-1.3.0/v2sim/plugins/__init__.py +9 -0
  113. v2sim-1.3.0/v2sim/plugins/base.py +278 -0
  114. v2sim-1.3.0/v2sim/plugins/ocur.py +94 -0
  115. v2sim-1.3.0/v2sim/plugins/pdn.py +182 -0
  116. v2sim-1.3.0/v2sim/plugins/pool.py +158 -0
  117. v2sim-1.3.0/v2sim/plugins/v2g.py +91 -0
  118. v2sim-1.3.0/v2sim/probtable/duration_of_parking/H.csv +96 -0
  119. v2sim-1.3.0/v2sim/probtable/duration_of_parking/H_spr.csv +96 -0
  120. v2sim-1.3.0/v2sim/probtable/duration_of_parking/H_spr_weekday.csv +96 -0
  121. v2sim-1.3.0/v2sim/probtable/duration_of_parking/H_spr_weekend.csv +96 -0
  122. v2sim-1.3.0/v2sim/probtable/duration_of_parking/O_spr.csv +96 -0
  123. v2sim-1.3.0/v2sim/probtable/duration_of_parking/O_spr_weekday.csv +96 -0
  124. v2sim-1.3.0/v2sim/probtable/duration_of_parking/O_spr_weekend.csv +96 -0
  125. v2sim-1.3.0/v2sim/probtable/duration_of_parking/R_spr.csv +96 -0
  126. v2sim-1.3.0/v2sim/probtable/duration_of_parking/R_spr_weekday.csv +96 -0
  127. v2sim-1.3.0/v2sim/probtable/duration_of_parking/R_spr_weekend.csv +96 -0
  128. v2sim-1.3.0/v2sim/probtable/duration_of_parking/W_spr.csv +96 -0
  129. v2sim-1.3.0/v2sim/probtable/duration_of_parking/W_spr_weekday.csv +96 -0
  130. v2sim-1.3.0/v2sim/probtable/duration_of_parking/W_spr_weekend.csv +96 -0
  131. v2sim-1.3.0/v2sim/probtable/ev_types.csv +7 -0
  132. v2sim-1.3.0/v2sim/probtable/soc_dist.csv +101 -0
  133. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/H_spr_weekday.csv +5 -0
  134. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/H_spr_weekend.csv +5 -0
  135. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/O_spr_weekday.csv +5 -0
  136. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/O_spr_weekend.csv +5 -0
  137. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/R_spr_weekday.csv +5 -0
  138. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/R_spr_weekend.csv +5 -0
  139. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/W_spr_weekday.csv +5 -0
  140. v2sim-1.3.0/v2sim/probtable/space_transfer_probability/W_spr_weekend.csv +5 -0
  141. v2sim-1.3.0/v2sim/sim_core.py +744 -0
  142. v2sim-1.3.0/v2sim/statistics/__init__.py +10 -0
  143. v2sim-1.3.0/v2sim/statistics/base.py +81 -0
  144. v2sim-1.3.0/v2sim/statistics/logcs.py +75 -0
  145. v2sim-1.3.0/v2sim/statistics/logev.py +45 -0
  146. v2sim-1.3.0/v2sim/statistics/loggr.py +174 -0
  147. v2sim-1.3.0/v2sim/statistics/manager.py +210 -0
  148. v2sim-1.3.0/v2sim/tools/cmd_advplot.py +24 -0
  149. v2sim-1.3.0/v2sim/tools/cmd_csquery.py +24 -0
  150. v2sim-1.3.0/v2sim/tools/cmd_gen_cs.py +27 -0
  151. v2sim-1.3.0/v2sim/tools/cmd_gen_trip.py +29 -0
  152. v2sim-1.3.0/v2sim/tools/cmd_plot.py +198 -0
  153. v2sim-1.3.0/v2sim/tools/gui_cmp.py +6 -0
  154. v2sim-1.3.0/v2sim/tools/gui_main.py +44 -0
  155. v2sim-1.3.0/v2sim/tools/gui_osm.py +7 -0
  156. v2sim-1.3.0/v2sim/tools/gui_para.py +5 -0
  157. v2sim-1.3.0/v2sim/tools/gui_plgman.py +10 -0
  158. v2sim-1.3.0/v2sim/tools/gui_viewer.py +5 -0
  159. v2sim-1.3.0/v2sim/tools/sim_para.py +278 -0
  160. v2sim-1.3.0/v2sim/tools/sim_single.py +122 -0
  161. v2sim-1.3.0/v2sim/traffic/__init__.py +9 -0
  162. v2sim-1.3.0/v2sim/traffic/cs.py +672 -0
  163. v2sim-1.3.0/v2sim/traffic/cslist.py +336 -0
  164. v2sim-1.3.0/v2sim/traffic/ev.py +460 -0
  165. v2sim-1.3.0/v2sim/traffic/evdict.py +85 -0
  166. v2sim-1.3.0/v2sim/traffic/inst.py +712 -0
  167. v2sim-1.3.0/v2sim/traffic/net.py +390 -0
  168. v2sim-1.3.0/v2sim/traffic/params.py +81 -0
  169. v2sim-1.3.0/v2sim/traffic/seg.py +231 -0
  170. v2sim-1.3.0/v2sim/traffic/trip.py +435 -0
  171. v2sim-1.3.0/v2sim/traffic/utils.py +345 -0
  172. v2sim-1.3.0/v2sim/traffic/win_vis.py +1 -0
  173. v2sim-1.3.0/v2sim/trafficgen/__init__.py +9 -0
  174. v2sim-1.3.0/v2sim/trafficgen/core.py +508 -0
  175. v2sim-1.3.0/v2sim/trafficgen/csquery.py +213 -0
  176. v2sim-1.3.0/v2sim/trafficgen/misc.py +214 -0
  177. v2sim-1.3.0/v2sim/trafficgen/poly.py +67 -0
  178. v2sim-1.3.0/v2sim/trafficgen/tripgen.py +440 -0
v2sim-1.3.0/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ # Compiled source
2
+ __pycache__
3
+ .idea
4
+ .vscode
5
+ .venv
6
+
7
+ # Temporary files
8
+ _sim_temp
9
+ temp
10
+ saved_state
11
+ *.old.*
12
+ buf.csv
13
+
14
+ # Sensitive files
15
+ amap_key.txt
16
+ v2sim/locale/lang.txt
17
+ *.json
18
+ preference.v2simcfg
19
+ recent_projects.txt
20
+
21
+ # Logs
22
+ *.log
23
+ *results*
24
+ profiling
25
+ perf*
26
+
27
+ # Cases
28
+ *.veh.xml*
29
+ *.bat
30
+ *.bak
31
+ deploy
32
+ cases/*
33
+ !cases/std_*
34
+ !cases/pwe_*
35
+
36
+ # Setup files
37
+ build
38
+ dist
39
+ *.egg-info
v2sim-1.3.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, fmy-xfk
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
v2sim-1.3.0/PKG-INFO ADDED
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: v2sim
3
+ Version: 1.3.0
4
+ Summary: V2Sim: An Open-Source Microscopic V2G Simulation Platform in Urban Power and Transportation Network
5
+ Project-URL: Homepage, https://github.com/fmy-xfk/v2sim
6
+ Project-URL: Documentation, https://github.com/fmy-xfk/v2sim/wiki
7
+ Project-URL: Repository, https://github.com/fmy-xfk/v2sim.git
8
+ Project-URL: Issues, https://github.com/fmy-xfk/v2sim/issues
9
+ License-Expression: BSD-3-Clause
10
+ License-File: LICENSE
11
+ Requires-Python: >=3.8
12
+ Requires-Dist: feasytools>=0.1.4
13
+ Requires-Dist: fpowerkit>=0.3.4
14
+ Requires-Dist: libsumo
15
+ Requires-Dist: matplotlib
16
+ Requires-Dist: numba
17
+ Requires-Dist: numpy
18
+ Requires-Dist: pyproj
19
+ Requires-Dist: requests
20
+ Requires-Dist: scikit-learn
21
+ Provides-Extra: v2g
22
+ Requires-Dist: cvxpy; extra == 'v2g'
23
+ Requires-Dist: ecos; extra == 'v2g'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # V2Sim Family
27
+
28
+ > Open-Source V2G Simulation Platform in Urban Power and Transportation Network
29
+
30
+ **Documents:** http://v2sim.heslab.wiki (Backup links: [HTTPS Link](https://hesl-seu.github.io/v2sim-wiki) | [CN Mirror 中文镜像](https://v2sim.myfrank.cn/#/zh_hans/))
31
+
32
+ V2Sim family includes several open-source software for coupled urban power and transportation network. They are different in the transportation simulation part.
33
+
34
+ + **V2Sim**: Use SUMO for **MICROSCOPIC** traffic simulation. It could identify the microscopic motion of a single vehicle, including its lane, speed, accerlation, etc. This version is suitable if your research concerns the implication of delicate motion of EVs on power grid. (Please scroll down to read instructions.)
35
+
36
+ + **V2Sim-UX**: Use uxsim for **MESOCOPIC** traffic simulation. It runs very fast with free-threading Python (3.14+). This version is suitable if your research need fast iterations and focus on the overall implication of the traffic flow. (Link: [V2Sim-UX](https://github.com/hesl-seu/v2sim/tree/uxsim))
37
+
38
+ If you are using V2Sim family, please cite the paper:
39
+ ```
40
+ @ARTICLE{10970754,
41
+ author={Qian, Tao and Fang, Mingyu and Hu, Qinran and Shao, Chengcheng and Zheng, Junyi},
42
+ journal={IEEE Transactions on Smart Grid},
43
+ title={V2Sim: An Open-Source Microscopic V2G Simulation Platform in Urban Power and Transportation Network},
44
+ year={2025},
45
+ volume={16},
46
+ number={4},
47
+ pages={3167-3178},
48
+ keywords={Vehicle-to-grid;Partial discharges;Microscopy;Batteries;Planning;Discharges (electric);Optimization;Vehicle dynamics;Transportation;Roads;EV charging load simulation;microscopic EV behavior;vehicle-to-grid;charging station fault sensing},
49
+ doi={10.1109/TSG.2025.3560976}}
50
+ ```
51
+ Paper link for the microscopic version: https://ieeexplore.ieee.org/document/10970754
52
+
53
+ ## V2Sim: The Microscopic Version
54
+
55
+ V2Sim is a microscopic V2G simulation platform in urban power and transportation network. It is open-source under BSD license.
56
+
57
+ + **Note**: Current code of V2Sim is ahead of the paper described. The exact older code used in the paper is [here](https://github.com/fmy-xfk/v2sim/commit/940ebd5d988f53fde90f4d83d107f136334952f9). The code used in [arXiv](https://arxiv.org/abs/2412.09808) is the initial commit.
58
+
59
+ + **Note 2**: Code of PDN part is not included in the repository, it is stored in another repository: [FPowerKit](https://gitee.com/fmy_xfk/fpowerkit).
60
+
61
+ ## Quick start
62
+ This package has been uploaded to PyPI. It can be installed by:
63
+ ```
64
+ pip install v2sim
65
+ ```
66
+
67
+ Then, input the following command to open the GUI:
68
+ ```
69
+ v2sim-gui
70
+ ```
71
+
72
+ Visit our documents to see the quick start guide!
73
+ Link: https://hesl-seu.github.io/v2sim-wiki/#/v2sim/quick-start (English)
v2sim-1.3.0/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # V2Sim Family
2
+
3
+ > Open-Source V2G Simulation Platform in Urban Power and Transportation Network
4
+
5
+ **Documents:** http://v2sim.heslab.wiki (Backup links: [HTTPS Link](https://hesl-seu.github.io/v2sim-wiki) | [CN Mirror 中文镜像](https://v2sim.myfrank.cn/#/zh_hans/))
6
+
7
+ V2Sim family includes several open-source software for coupled urban power and transportation network. They are different in the transportation simulation part.
8
+
9
+ + **V2Sim**: Use SUMO for **MICROSCOPIC** traffic simulation. It could identify the microscopic motion of a single vehicle, including its lane, speed, accerlation, etc. This version is suitable if your research concerns the implication of delicate motion of EVs on power grid. (Please scroll down to read instructions.)
10
+
11
+ + **V2Sim-UX**: Use uxsim for **MESOCOPIC** traffic simulation. It runs very fast with free-threading Python (3.14+). This version is suitable if your research need fast iterations and focus on the overall implication of the traffic flow. (Link: [V2Sim-UX](https://github.com/hesl-seu/v2sim/tree/uxsim))
12
+
13
+ If you are using V2Sim family, please cite the paper:
14
+ ```
15
+ @ARTICLE{10970754,
16
+ author={Qian, Tao and Fang, Mingyu and Hu, Qinran and Shao, Chengcheng and Zheng, Junyi},
17
+ journal={IEEE Transactions on Smart Grid},
18
+ title={V2Sim: An Open-Source Microscopic V2G Simulation Platform in Urban Power and Transportation Network},
19
+ year={2025},
20
+ volume={16},
21
+ number={4},
22
+ pages={3167-3178},
23
+ keywords={Vehicle-to-grid;Partial discharges;Microscopy;Batteries;Planning;Discharges (electric);Optimization;Vehicle dynamics;Transportation;Roads;EV charging load simulation;microscopic EV behavior;vehicle-to-grid;charging station fault sensing},
24
+ doi={10.1109/TSG.2025.3560976}}
25
+ ```
26
+ Paper link for the microscopic version: https://ieeexplore.ieee.org/document/10970754
27
+
28
+ ## V2Sim: The Microscopic Version
29
+
30
+ V2Sim is a microscopic V2G simulation platform in urban power and transportation network. It is open-source under BSD license.
31
+
32
+ + **Note**: Current code of V2Sim is ahead of the paper described. The exact older code used in the paper is [here](https://github.com/fmy-xfk/v2sim/commit/940ebd5d988f53fde90f4d83d107f136334952f9). The code used in [arXiv](https://arxiv.org/abs/2412.09808) is the initial commit.
33
+
34
+ + **Note 2**: Code of PDN part is not included in the repository, it is stored in another repository: [FPowerKit](https://gitee.com/fmy_xfk/fpowerkit).
35
+
36
+ ## Quick start
37
+ This package has been uploaded to PyPI. It can be installed by:
38
+ ```
39
+ pip install v2sim
40
+ ```
41
+
42
+ Then, input the following command to open the GUI:
43
+ ```
44
+ v2sim-gui
45
+ ```
46
+
47
+ Visit our documents to see the quick start guide!
48
+ Link: https://hesl-seu.github.io/v2sim-wiki/#/v2sim/quick-start (English)
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = [ "hatchling",]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "v2sim"
7
+ version = "1.3.0"
8
+ dependencies = [ "libsumo", "numpy", "matplotlib", "feasytools>=0.1.4", "fpowerkit>=0.3.4", "pyproj", "requests", "scikit-learn", "numba",]
9
+ requires-python = ">= 3.8"
10
+ license = "BSD-3-Clause"
11
+ description = "V2Sim: An Open-Source Microscopic V2G Simulation Platform in Urban Power and Transportation Network"
12
+
13
+ [project.readme]
14
+ file = "README.md"
15
+ content-type = "text/markdown"
16
+
17
+ [project.optional-dependencies]
18
+ v2g = [ "ecos", "cvxpy",]
19
+
20
+ [project.scripts]
21
+ v2sim-gui = "v2sim.tools.gui_main:main"
22
+ v2sim = "v2sim.tools.sim_single:work"
23
+ v2sim-para = "v2sim.tools.sim_para:main"
24
+ v2sim-advplot = "v2sim.tools.cmd_advplot:main"
25
+ v2sim-convert = "v2sim.tools.cmd_convert:main"
26
+ v2sim-csquery = "v2sim.tools.cmd_csquery:main"
27
+ v2sim-gen-cs = "v2sim.tools.cmd_gen_cs:main"
28
+ v2sim-gen-trip = "v2sim.tools.cmd_gen_trip:main"
29
+ v2sim-plot = "v2sim.tools.cmd_plot:main"
30
+ v2sim-osm = "v2sim.tools.gui_osm:entry"
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/fmy-xfk/v2sim"
34
+ Documentation = "https://github.com/fmy-xfk/v2sim/wiki"
35
+ Repository = "https://github.com/fmy-xfk/v2sim.git"
36
+ Issues = "https://github.com/fmy-xfk/v2sim/issues"
37
+
38
+ [tool.hatch.build]
39
+ include = [ "v2sim/*",]
@@ -0,0 +1,21 @@
1
+ from .locale import *
2
+ from .traffic import *
3
+ from .trafficgen import *
4
+ from .plotkit import *
5
+ from .plugins import *
6
+ from .statistics import *
7
+ from .sim_core import (
8
+ load_external_components,
9
+ get_sim_params,
10
+ simulate_multi,
11
+ simulate_single,
12
+ V2SimInstance,
13
+ MsgPack,
14
+ PLUGINS_FILE,
15
+ RESULTS_FOLDER,
16
+ TRIP_EVENT_LOG,
17
+ SIM_INFO_LOG,
18
+ PLUGINS_DIR,
19
+ )
20
+
21
+ __version__ = "1.3.0"
@@ -0,0 +1,152 @@
1
+ from v2sim.gui.com_no_vx import *
2
+ from v2sim.gui.langhelper import *
3
+
4
+ import os
5
+ from PIL import Image, ImageTk
6
+
7
+
8
+ _ = LangLib.Load(__file__)
9
+
10
+
11
+ class CmpBox(Tk):
12
+ def __init__(self):
13
+ super().__init__()
14
+
15
+ self.title(_("TITLE"))
16
+ self.geometry("1024x768")
17
+ self.bind("<Configure>", self.on_resize)
18
+
19
+ self.folder1 = None
20
+ self.folder2 = None
21
+ self.original_image1 = None
22
+ self.original_image2 = None
23
+ self.folder_buf = "./results"
24
+
25
+ self.create_widgets()
26
+
27
+ def create_widgets(self):
28
+ self.menu = Menu(self)
29
+ self.config(menu=self.menu)
30
+ self.filemenu = Menu(self.menu, tearoff=0)
31
+ self.filemenu.add_command(label=_("OPEN_FOLDER1"), command=self.open_folder1)
32
+ self.filemenu.add_command(label=_("OPEN_FOLDER2"), command=self.open_folder2)
33
+ self.filemenu.add_separator()
34
+ self.filemenu.add_command(label=_("EXIT"), command=self.destroy)
35
+ self.menu.add_cascade(label=_("FILE"), menu=self.filemenu)
36
+ add_lang_menu(self.menu)
37
+
38
+ self.sidebar = Frame(self)
39
+ self.sidebar.pack(side=LEFT, fill=Y)
40
+
41
+ self.folder1_button = Button(self.sidebar, text=_("OPEN_FOLDER1"), command=self.open_folder1)
42
+ self.folder1_button.pack(pady=10)
43
+
44
+ self.folder2_button = Button(self.sidebar, text=_("OPEN_FOLDER2"), command=self.open_folder2)
45
+ self.folder2_button.pack(pady=10)
46
+
47
+ self.folder1_label = Label(self.sidebar, text=_("LB_FOLDER1").format(_("TO_BE_SELECTED")))
48
+ self.folder1_label.pack(pady=10)
49
+
50
+ self.folder2_label = Label(self.sidebar, text=_("LB_FOLDER2").format(_("TO_BE_SELECTED")))
51
+ self.folder2_label.pack(pady=10)
52
+
53
+ self.file_listbox = Listbox(self.sidebar)
54
+ self.file_listbox.pack(fill=BOTH, expand=True, pady=10)
55
+ self.file_listbox.bind("<<ListboxSelect>>", self.on_file_select)
56
+
57
+ self.image_frame = Frame(self)
58
+ self.image_frame.pack(side=RIGHT, fill=X, expand=True)
59
+
60
+ self.image1_label = Label(self.image_frame)
61
+ self.image1_label.pack(side=TOP, padx=10, pady=10)
62
+
63
+ self.image2_label = Label(self.image_frame)
64
+ self.image2_label.pack(side=TOP, padx=10, pady=10)
65
+
66
+ def open_folder1(self):
67
+ new_folder = filedialog.askdirectory(initialdir=self.folder_buf, title=_("AD_TITLE1"))
68
+ if new_folder:
69
+ folder_fig = os.path.join(new_folder, "figures")
70
+ if os.path.exists(folder_fig):
71
+ self.folder1 = folder_fig
72
+ self.folder1_label.config(text=_("LB_FOLDER1").format(os.path.basename(new_folder)))
73
+ self.update_file_list()
74
+ self.folder_buf = str(Path(new_folder).parent)
75
+ else:
76
+ MB.showerror(_("ERROR"), _("NO_FIG"))
77
+
78
+ def open_folder2(self):
79
+ new_folder = filedialog.askdirectory(initialdir=self.folder_buf, title=_("AD_TITLE2"))
80
+ if new_folder:
81
+ folder_fig = os.path.join(new_folder, "figures")
82
+ if os.path.exists(folder_fig):
83
+ self.folder2 = folder_fig
84
+ self.folder2_label.config(text=_("LB_FOLDER2").format(os.path.basename(new_folder)))
85
+ self.update_file_list()
86
+ self.folder_buf = str(Path(new_folder).parent)
87
+ else:
88
+ MB.showerror(_("ERROR"), _("NO_FIG"))
89
+
90
+ def update_file_list(self):
91
+ self.file_listbox.delete(0, END)
92
+ if self.folder1 and self.folder2:
93
+ files1 = set(os.listdir(self.folder1))
94
+ files2 = set(os.listdir(self.folder2))
95
+ common_files = files1.union(files2)
96
+ for file in sorted(common_files):
97
+ if file.lower().endswith(('png', 'jpg', 'jpeg', 'gif')): # 只列出图片文件
98
+ self.file_listbox.insert(END, file)
99
+
100
+ def on_file_select(self, event):
101
+ selected_index = self.file_listbox.curselection()
102
+ if selected_index:
103
+ file_name = self.file_listbox.get(selected_index)
104
+ self.display_images(file_name)
105
+
106
+ def resize(self):
107
+ sz = (self.winfo_width() - 200, self.winfo_height() // 2 - 20)
108
+ if self.original_image1 is not None:
109
+ resized_image1 = self.original_image1.copy()
110
+ resized_image1.thumbnail(sz)
111
+ image1 = ImageTk.PhotoImage(resized_image1)
112
+
113
+ self.image1_label.config(image=image1,text="")
114
+ self.image1 = image1
115
+ else:
116
+ self.image1_label.config(image='',text=_("NO_IMAGE"))
117
+ self.image1 = None
118
+
119
+ if self.original_image2 is not None:
120
+ resized_image2 = self.original_image2.copy()
121
+ resized_image2.thumbnail(sz)
122
+ image2 = ImageTk.PhotoImage(resized_image2)
123
+
124
+ self.image2_label.config(image=image2,text="")
125
+ self.image2 = image2
126
+ else:
127
+ self.image2_label.config(image='',text=_("NO_IMAGE"))
128
+ self.image2 = None
129
+
130
+
131
+ def on_resize(self, event):
132
+ self.resize()
133
+
134
+ def display_images(self, file_name:str):
135
+ if self.folder1 is None: return
136
+ img1_path = os.path.join(self.folder1, file_name)
137
+ if self.folder2 is None: return
138
+ img2_path = os.path.join(self.folder2, file_name)
139
+
140
+ try:
141
+ if os.path.exists(img1_path):
142
+ self.original_image1 = Image.open(img1_path)
143
+ else:
144
+ self.original_image1 = None
145
+ if os.path.exists(img2_path):
146
+ self.original_image2 = Image.open(img2_path)
147
+ else:
148
+ self.original_image2 = None
149
+ except Exception as e:
150
+ MB.showerror(_("ERROR"), _("LOAD_FAILED").format(str(e)))
151
+
152
+ self.resize()
@@ -0,0 +1,14 @@
1
+ TITLE=Case comparer
2
+ ERROR=Error
3
+ OPEN_FOLDER1=Open folder 1
4
+ OPEN_FOLDER2=Open folder 2
5
+ TO_BE_SELECTED=(To be selected)
6
+ LB_FOLDER1=Folder 1: {}
7
+ LB_FOLDER2=Folder 2: {}
8
+ AD_TITLE1=Select folder 1
9
+ AD_TITLE2=Select folder 2
10
+ NO_FIG=No 'figures' folder in the selected folder! Please plot the data with gui_viewer.py first!
11
+ LOAD_FAILED=Cannot load image: {}
12
+ NO_IMAGE=(No image)
13
+ EXIT=Exit
14
+ FILE=File
@@ -0,0 +1,14 @@
1
+ TITLE=案例比较器
2
+ ERROR=错误
3
+ OPEN_FOLDER1=打开文件夹1
4
+ OPEN_FOLDER2=打开文件夹2
5
+ TO_BE_SELECTED=未选择
6
+ LB_FOLDER1=文件夹1: {}
7
+ LB_FOLDER2=文件夹2: {}
8
+ AD_TITLE1=选择文件夹1
9
+ AD_TITLE2=选择文件夹2
10
+ NO_FIG=所选文件夹中没有figures文件夹! 请先使用gui_viewer.py画图!
11
+ LOAD_FAILED=无法加载图片: {}
12
+ NO_IMAGE=无图像
13
+ EXIT=退出
14
+ FILE=文件
@@ -0,0 +1,33 @@
1
+ # Load Path
2
+ from pathlib import Path
3
+
4
+ # Load Event Queue
5
+ from .evtq import EventQueue
6
+
7
+ # Load Language Library
8
+ from feasytools import LangLib, LangConfig
9
+ LangConfig.SetAppName("v2sim")
10
+
11
+ # High DPI awareness for Windows
12
+ import platform
13
+ if platform.system() == "Windows":
14
+ import ctypes
15
+ ctypes.windll.shcore.SetProcessDpiAwareness(1)
16
+
17
+ # Load Tk controls
18
+ from tkinter import (
19
+ Toplevel, messagebox as MB, BooleanVar, StringVar, IntVar, Canvas, Event, Tk, Menu, filedialog, Text, Listbox, PhotoImage, Widget,
20
+ NO, YES, NORMAL, DISABLED, END, BOTH, X, Y, LEFT, RIGHT, TOP, BOTTOM, W, E
21
+ )
22
+ from tkinter.ttk import Treeview, Button, LabelFrame, Checkbutton, Combobox, Frame, Label, Entry, Spinbox, Scrollbar, Radiobutton, Notebook, OptionMenu
23
+
24
+ # Load Type Hints
25
+ from typing import Dict, List, Set, Tuple, Any, Union, Optional, Iterable, Callable, Literal
26
+
27
+ # Set exports
28
+ __all__ = [
29
+ "LangLib", "LangConfig", "EventQueue", "Path", "Dict", "List", "Set", "Tuple", "Any", "Union", "Optional", "Iterable", "Callable", "Literal",
30
+ "Toplevel", "MB", "BooleanVar", "StringVar", "IntVar", "Canvas", "Event", "Tk", "Menu", "filedialog", "Text", "Listbox", "PhotoImage", "Widget",
31
+ "NO", "YES", "NORMAL", "DISABLED", "END", "X", "Y", "BOTH", "LEFT", "RIGHT", "TOP", "BOTTOM", "W", "E", "platform",
32
+ "Treeview", "Button", "LabelFrame", "Checkbutton", "Combobox", "Frame", "Label", "Entry", "Spinbox", "Scrollbar", "Radiobutton", "Notebook", "OptionMenu",
33
+ ]
@@ -0,0 +1,5 @@
1
+ from .com_no_vx import *
2
+
3
+ # Load V2Sim common items
4
+ from v2sim import ConfigItem, EditMode, ConfigItemDict, ConfigDict, CONFIG_DIR
5
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
@@ -0,0 +1,100 @@
1
+ import threading
2
+ import time
3
+ import traceback
4
+ from collections import deque
5
+ from queue import Queue
6
+ from typing import Callable, Dict, Tuple
7
+
8
+ class EventQueue:
9
+ def __init__(self, parent, maxsize:int = 0, interval_ms:int = 100, max_proc_ms:int = 90):
10
+ self._Q = Queue(maxsize)
11
+ self._parent = parent
12
+ self._evt:Dict[str, Callable] = {}
13
+ self._interval_ms = interval_ms
14
+ self._max_proc_ns = max_proc_ms * 1e6 # Convert to nanoseconds
15
+ self._delegates:deque[Tuple[Callable, Tuple, Dict]] = deque()
16
+ self.do() # Start processing events immediately
17
+
18
+ def do(self):
19
+ """Process all events in the queue."""
20
+ prod_next = True
21
+ st = time.time_ns()
22
+
23
+ cnt = 0
24
+ while self._delegates:
25
+ func, args, kwargs = self._delegates.popleft()
26
+ try:
27
+ func(*args, **kwargs)
28
+ except Exception as e:
29
+ print(f"Error in delegate function '{func.__name__}': {e}")
30
+
31
+ cnt = 0
32
+ while not self._Q.empty() and (time.time_ns() - st < self._max_proc_ns) and cnt < 100:
33
+ name, args, kwargs = self._Q.get()
34
+ if name == "__quit__":
35
+ self._Q.task_done()
36
+ prod_next = False
37
+ break
38
+ if name in self._evt and self._evt[name] is not None:
39
+ try:
40
+ self._evt[name](*args, **kwargs)
41
+ except Exception as e:
42
+ traceback.print_exc()
43
+ print(f"Error processing event '{name}': {e}")
44
+ else:
45
+ print(f"Event '{name}' is not registered.")
46
+ self._Q.task_done()
47
+ self._parent.update() # Ensure the GUI updates after processing each event
48
+ cnt += 1
49
+ if prod_next:
50
+ intv = self._interval_ms
51
+ if cnt >= 100:
52
+ intv = max(intv // 10, 1)
53
+ self._parent.after(intv, self.do)
54
+
55
+ def register(self, name:str, callback:Callable):
56
+ """Register an event handler for a specific event name."""
57
+ if name in self._evt:
58
+ raise ValueError(f"Event '{name}' is already registered.")
59
+ self._evt[name] = callback
60
+
61
+ def setcallback(self, name:str, callback:Callable):
62
+ """Set or update the callback for an event."""
63
+ if name not in self._evt:
64
+ raise ValueError(f"Event '{name}' is not registered.")
65
+ self._evt[name] = callback
66
+
67
+ def trigger(self, name:str, *args, **kwargs):
68
+ """Trigger an event by its name with optional arguments."""
69
+ if name not in self._evt:
70
+ raise ValueError(f"Event '{name}' is not registered.")
71
+ self._Q.put((name, args, kwargs))
72
+
73
+ def submit(self, name:str, func:Callable, *args, **kwargs):
74
+ """Run a function asychoronously and submit the results to trigger an event."""
75
+ def _run_and_trigger(name, func, *args, **kwargs):
76
+ try:
77
+ result = func(*args, **kwargs)
78
+ if result is None:
79
+ result = ()
80
+ elif not isinstance(result, tuple):
81
+ result = (result,)
82
+ self.trigger(name, *result)
83
+ except Exception as e:
84
+ traceback.print_exc()
85
+ print(f"Error in submitting function '{func.__name__}' for event '{name}': {e}")
86
+ threading.Thread(target=_run_and_trigger, args=(name, func, *args), kwargs=kwargs).start()
87
+
88
+ def asyncrun(self, func:Callable, *args, **kwargs):
89
+ """Run a no-return function asynchronously"""
90
+ def _run(func, *args, **kwargs):
91
+ try:
92
+ func(*args, **kwargs)
93
+ except Exception as e:
94
+ traceback.print_exc()
95
+ print(f"Error in delegating function '{func.__name__}': {e}")
96
+ threading.Thread(target=_run, args=(func, *args), kwargs=kwargs).start()
97
+
98
+ def delegate(self, func:Callable, *args, **kwargs):
99
+ """Run a no-return function on the main thread."""
100
+ self._delegates.append((func, args, kwargs))
@@ -0,0 +1,34 @@
1
+ from v2sim.gui.com_no_vx import *
2
+
3
+ _ = LangLib(["zh_CN", "en_US"])
4
+ _.SetLangLib("zh_CN",
5
+ MB_INFO = "信息",
6
+ MENU_LANG = "语言",
7
+ MENU_LANG_AUTO = "(自动检测)",
8
+ LANG_RESTART = "语言已更改,请重启程序以应用更改。",
9
+ )
10
+
11
+ _.SetLangLib("en_US",
12
+ MB_INFO = "Information",
13
+ MENU_LANG = "Language",
14
+ MENU_LANG_AUTO = "(Auto Detect)",
15
+ LANG_RESTART = "Language has been changed. Please restart the application to apply the changes.",
16
+ )
17
+
18
+ def setLang(lang_code:str):
19
+ title = _["MB_INFO"]
20
+ info = _["LANG_RESTART"]
21
+ def _f():
22
+ nonlocal lang_code, title, info
23
+ LangConfig.SetLangCode(lang_code)
24
+ MB.showinfo(title, info)
25
+ return _f
26
+
27
+ def add_lang_menu(parent: Menu):
28
+ menuLang = Menu(parent, tearoff=False)
29
+ parent.add_cascade(label=_["MENU_LANG"], menu=menuLang)
30
+ menuLang.add_command(label=_["MENU_LANG_AUTO"], command=setLang("<auto>"))
31
+ menuLang.add_command(label="English (United States)", command=setLang("en_US"))
32
+ menuLang.add_command(label="中文 (简体)", command=setLang("zh_CN"))
33
+
34
+ __all__ = ["add_lang_menu"]