]> rtime.felk.cvut.cz Git - hubacji1/iamcar2.git/blob - scripts/plot_json_objects_scenario.py
Fix time-out rate caption
[hubacji1/iamcar2.git] / scripts / plot_json_objects_scenario.py
1 """Plot JSON formatted scenario."""
2 from json import loads
3 from math import cos, pi, sin
4 from math import inf
5 from matplotlib import pyplot as plt
6 from sys import argv, exit
7
8 BCAR_MTR = 10.820
9 BCAR_WB = 2.450
10 BCAR_W = 1.625
11 BCAR_L = 3.760
12 BCAR_SD = 0
13 BCAR_DF = 3.105
14 BCAR_DR = 0.655
15
16 MINX = inf
17 MINY = inf
18
19 def get_scenario(fname):
20     """Load scenario from file."""
21     if fname is None:
22         raise ValueError("File name as argument needed")
23     with open(fname, "r") as f:
24         scenario = loads(f.read())
25     return scenario
26
27 def plot_nodes(nodes=[]):
28     """Return ``xcoords``, ``ycoords`` arrays of nodes to plot.
29
30     Keyword arguments:
31     nodes -- The list of nodes to plot.
32     """
33     xcoords = []
34     ycoords = []
35     for n in nodes:
36         xcoords.append(n[0] - MINX)
37         ycoords.append(n[1] - MINY)
38     return (xcoords, ycoords)
39
40 def plot_car(pose):
41     """Return ``xcoords``, ``ycoords`` arrays of car frame to plot.
42
43     Keyword arguments:
44     pose -- The pose of a car.
45     """
46     lfx = pose[0]
47     lfx += (BCAR_W / 2.0) * cos(pose[2] + pi / 2.0)
48     lfx += BCAR_DF * cos(pose[2])
49     lfx += BCAR_SD * cos(pose[2])
50
51     lf3x = pose[0]
52     lf3x += (BCAR_W / 2.0) * cos(pose[2] + pi / 2.0)
53     lf3x += 2/3 * BCAR_DF * cos(pose[2])
54     lf3x += BCAR_SD * cos(pose[2])
55
56     lrx = pose[0]
57     lrx += (BCAR_W / 2.0) * cos(pose[2] + pi / 2.0)
58     lrx += -BCAR_DR * cos(pose[2])
59     lrx += -BCAR_SD * cos(pose[2])
60
61     rrx = pose[0]
62     rrx += (BCAR_W / 2.0) * cos(pose[2] - pi / 2.0)
63     rrx += -BCAR_DR * cos(pose[2])
64     rrx += -BCAR_SD * cos(pose[2])
65
66     rfx = pose[0]
67     rfx += (BCAR_W / 2.0) * cos(pose[2] - pi / 2.0)
68     rfx += BCAR_DF * cos(pose[2])
69     rfx += BCAR_SD * cos(pose[2])
70
71     rf3x = pose[0]
72     rf3x += (BCAR_W / 2.0) * cos(pose[2] - pi / 2.0)
73     rf3x += 2/3 * BCAR_DF * cos(pose[2])
74     rf3x += BCAR_SD * cos(pose[2])
75
76     lfy = pose[1]
77     lfy += (BCAR_W / 2.0) * sin(pose[2] + pi / 2.0)
78     lfy += BCAR_DF * sin(pose[2])
79     lfy += BCAR_SD * sin(pose[2])
80
81     lf3y = pose[1]
82     lf3y += (BCAR_W / 2.0) * sin(pose[2] + pi / 2.0)
83     lf3y += 2/3 * BCAR_DF * sin(pose[2])
84     lf3y += BCAR_SD * sin(pose[2])
85
86     lry = pose[1]
87     lry += (BCAR_W / 2.0) * sin(pose[2] + pi / 2.0)
88     lry += -BCAR_DR * sin(pose[2])
89     lry += -BCAR_SD * sin(pose[2])
90
91     rry = pose[1]
92     rry += (BCAR_W / 2.0) * sin(pose[2] - pi / 2.0)
93     rry += -BCAR_DR * sin(pose[2])
94     rry += -BCAR_SD * sin(pose[2])
95
96     rfy = pose[1]
97     rfy += (BCAR_W / 2.0) * sin(pose[2] - pi / 2.0)
98     rfy += BCAR_DF * sin(pose[2])
99     rfy += BCAR_SD * sin(pose[2])
100
101     rf3y = pose[1]
102     rf3y += (BCAR_W / 2.0) * sin(pose[2] - pi / 2.0)
103     rf3y += 2/3 * BCAR_DF * sin(pose[2])
104     rf3y += BCAR_SD * sin(pose[2])
105
106     cfx = pose[0]
107     cfx += BCAR_DF * cos(pose[2])
108     cfx += BCAR_SD * cos(pose[2])
109
110     cfy = pose[1]
111     cfy += BCAR_DF * sin(pose[2])
112     cfy += BCAR_SD * sin(pose[2])
113
114     xcoords = (lfx, lrx, rrx, rfx, cfx, rf3x, lf3x, cfx, lfx)
115     ycoords = (lfy, lry, rry, rfy, cfy, rf3y, lf3y, cfy, lfy)
116     return ([x - MINX for x in xcoords], [y - MINY for y in ycoords])
117
118 if __name__ == "__main__":
119     sc2 = None
120     if (len(argv) == 2):
121         SCEN_FILE = argv[1]
122     elif (len(argv) == 3):
123         SCEN_FILE = argv[1]
124         SCEN_FILE2 = argv[2]
125         sc2 = get_scenario(SCEN_FILE2)
126     else:
127         SCEN_FILE = "sc.json"
128
129     scenario = get_scenario(SCEN_FILE)
130
131     # Font size to be approximately the same in the paper:
132     #   - sc1-0: 16
133     #   - sc3-2, Intro: 12
134     #   - sc4-0+: 22
135     plt.rcParams["font.family"] = "cmr10"
136     plt.rcParams["font.size"] = 12
137     plt.rcParams['hatch.linewidth'] = 1.0
138     plt.rcParams['lines.linewidth'] = 1.0
139     fig = plt.figure()
140
141     # here subplot starts
142     ax = fig.add_subplot(111)
143     ax.set_aspect("equal")
144     ax.set_title("Real-world parking scenario")
145     ax.set_xlabel("x [m]")
146     ax.set_ylabel("y [m]")
147
148     # For Possible Entry Points (Possible Entry Configurations) use:
149     #ax.set_xlim([35.6, 46.4])
150     #ax.set_ylim([2.9, 2.9 + 6.84])
151
152     # For Last Maneuver use:
153     #ax.set_xlim([38, 44])
154     #ax.set_ylim([3.1, 6.9])
155
156     # For Scenario 3-2 detail use:
157     #ax.set_xlim([0, 15])
158     #ax.set_ylim([35, 50])
159
160     # For Real-world parking scenario in Introduction section use:
161     #ax.set_xlim([32, 47.5])
162     #ax.set_ylim([2.4, 9.9])
163
164     # Set min and max to center the plot.
165     MINX = scenario["init"][0]
166     MINY = scenario["init"][1]
167     if "obst" in scenario and  len(scenario["obst"]) > 0:
168         for o in scenario["obst"]:
169             if not o:
170                 continue
171             for n in o:
172                 if n[0] < MINX:
173                     MINX = n[0]
174                 if n[1] < MINY:
175                     MINY = n[1]
176
177     # Plot all the nodes (if exists), obstacles, and slot.
178     if "nodes_x" in scenario and "nodes_y" in scenario:
179         plt.plot(
180             [x - MINX for x in scenario["nodes_x"]],
181             [y - MINY for y in scenario["nodes_y"]],
182             color="lightgray",
183             marker="o",
184             ms=2,
185             lw=0,
186         )
187     if "obst" in scenario and len(scenario["obst"]) > 0:
188         for o in scenario["obst"]:
189             if not o:
190                 continue
191             plt.plot(*plot_nodes(o), color="blue", linestyle=":")
192     if "slot" in scenario and len(scenario["slot"]) > 0:
193         plt.plot(*plot_nodes(scenario["slot"][0]), color="black")
194         #for s in scenario["slot"]:
195         #    plt.plot(*plot_nodes(s), color="black")
196
197     # Plot `init`, `entry`, and `goal` configurations.
198     if "init" in scenario and len(scenario["init"]) == 3:
199         plt.plot(*plot_car(scenario["init"]), color="red")
200         plt.plot(
201             scenario["init"][0] - MINX,
202             scenario["init"][1] - MINY,
203             color="red",
204             marker="+",
205             ms=12
206         )
207     if "entry" in scenario and len(scenario["entry"]) == 3:
208         plt.plot(*plot_car(scenario["entry"]), color="magenta")
209         plt.plot(
210             scenario["entry"][0] - MINX,
211             scenario["entry"][1] - MINY,
212             color="magenta",
213             marker="+",
214             ms=12
215         )
216     if "goal" in scenario and len(scenario["goal"]) == 3:
217         plt.plot(*plot_car(scenario["goal"]), color="green")
218         plt.plot(
219             scenario["goal"][0] - MINX,
220             scenario["goal"][1] - MINY,
221             color="green",
222             marker="+",
223             ms=12
224         )
225
226     # Plot `path` and `max_path`.
227     if sc2 and "path" in sc2 and  len(sc2["path"]) > 0:
228         plt.plot(*plot_nodes(sc2["path"]), color="orange")
229     if "path" in scenario and  len(scenario["path"]) > 0:
230         plt.plot(*plot_nodes(scenario["path"]), color="green")
231
232     # If there are possible starts specified, you may print and plot them.
233     #if "starts" in scenario and len(scenario["starts"]) > 0:
234     #    print("possible starts:")
235     #    for p in scenario["starts"]:
236     #        plt.plot(*p, color="red", marker="+", ms=12)
237     #        print(" {}".format(p))
238
239     # For the Last Maneuver figure from the paper, use:
240     #   - `init2` -- orange
241     #plt.plot(*plot_car(scenario["init2"]), color="orange")
242     #plt.plot(
243     #    scenario["init2"][0] - MINX,
244     #    scenario["init2"][1] - MINY,
245     #    color="orange",
246     #    #marker="+",
247     #    ms=12
248     #)
249     #   - `goal2` -- orange
250     #plt.plot(*plot_car(scenario["goal2"]), color="orange")
251     #plt.plot(
252     #    scenario["goal2"][0] - MINX,
253     #    scenario["goal2"][1] - MINY,
254     #    color="orange",
255     #    #marker="+",
256     #    ms=12
257     #)
258     #   - `goal2` -- middle (orange)
259     #plt.plot(*plot_car(scenario["goals"][0]), color="orange")
260     #plt.plot(
261     #    scenario["goal2"][0] - MINX,
262     #    scenario["goal2"][1] - MINY,
263     #    color="orange",
264     #    #marker="+",
265     #    ms=12
266     #)
267     #   - `init1` -- green
268     #plt.plot(*plot_car(scenario["init1"]), color="green")
269     #plt.plot(
270     #    scenario["init1"][0] - MINX,
271     #    scenario["init1"][1] - MINY,
272     #    color="green",
273     #    #marker="+",
274     #    ms=12
275     #)
276     #   - `goal1` -- green
277     #plt.plot(*plot_car(scenario["goal1"]), color="green")
278     #plt.plot(
279     #    scenario["goal1"][0] - MINX,
280     #    scenario["goal1"][1] - MINY,
281     #    color="green",
282     #    #marker="+",
283     #    ms=12
284     #)
285
286     # For the Possible Entry Configurations from the paper, use:
287     #if "inits" in scenario:
288     #    for i in scenario["inits"]:
289     #        print(i)
290     #        if len(i) == 3:
291     #            plt.plot(*plot_car(i), color="gray")
292     #            plt.plot(
293     #                i[0] - MINX,
294     #                i[1] - MINY,
295     #                color="gray",
296     #                marker="+",
297     #                ms=12,
298     #            )
299     #    plt.plot(*plot_car(scenario["inits"][0]), color="magenta")
300     #    plt.plot(
301     #        scenario["inits"][0][0] - MINX,
302     #        scenario["inits"][0][1] - MINY,
303     #        color="magenta",
304     #        marker="+",
305     #        ms=12,
306     #    )
307
308     # The `scenario` may also include:
309     #   - `last` -- not sure what this is, see the source code. Maybe overlaps
310     #     with the `goal`.
311     #   - `last1` -- used to demonstrate In-Slot Planner (was Parking Slot
312     #     Planner (PSP.))
313     #   - `last2` -- used to demonstrate In-Slot Planner (was Parking Slot
314     #     Planner (PSP.))
315     #   - `max_orig_path` -- maximum original path. I used this when comparing
316     #     original paths but I had to copy the `max_orig_path` by hand from
317     #     different scenario result.
318     #   - `orig_path` -- the path before the optimization.
319     #   - `max_path` -- the maximum path after optimization. Must be copied by
320     #     hand.
321     #   - `path` -- optimized path of the scenario.
322
323     handles, labels = ax.get_legend_handles_labels()
324
325     # Uncommnent the following line and comment the plt.show() to store to the
326     # file.
327     plt.savefig("out.pdf", bbox_inches="tight")
328     plt.close(fig)