]> rtime.felk.cvut.cz Git - hubacji1/iamcar2.git/blob - scripts/plot_json_objects_scenario.py
Change plot font family to cmr10
[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     if (len(argv) == 2):
120         SCEN_FILE = argv[1]
121     else:
122         SCEN_FILE = "sc.json"
123
124     scenario = get_scenario(SCEN_FILE)
125
126     # Font size to be approximately the same in the paper:
127     #   - sc1-0: 16
128     #   - sc3-2, Intro: 12
129     #   - sc4-0+: 22
130     plt.rcParams["font.family"] = "cmr10"
131     plt.rcParams["font.size"] = 12
132     plt.rcParams['hatch.linewidth'] = 1.0
133     plt.rcParams['lines.linewidth'] = 1.0
134     fig = plt.figure()
135
136     # here subplot starts
137     ax = fig.add_subplot(111)
138     ax.set_aspect("equal")
139     ax.set_title("Real-world parking scenario")
140     ax.set_xlabel("x [m]")
141     ax.set_ylabel("y [m]")
142
143     # For Possible Entry Points (Possible Entry Configurations) use:
144     #ax.set_xlim([35.6, 46.4])
145     #ax.set_ylim([2.9, 2.9 + 6.84])
146
147     # For Last Maneuver use:
148     #ax.set_xlim([38, 44])
149     #ax.set_ylim([3.1, 6.9])
150
151     # For Scenario 3-2 detail use:
152     #ax.set_xlim([0, 15])
153     #ax.set_ylim([35, 50])
154
155     # For Real-world parking scenario in Introduction section use:
156     #ax.set_xlim([32, 47.5])
157     #ax.set_ylim([2.4, 9.9])
158
159     # Set min and max to center the plot.
160     MINX = scenario["init"][0]
161     MINY = scenario["init"][1]
162     if "obst" in scenario and  len(scenario["obst"]) > 0:
163         for o in scenario["obst"]:
164             for n in o:
165                 if n[0] < MINX:
166                     MINX = n[0]
167                 if n[1] < MINY:
168                     MINY = n[1]
169
170     # Plot all the nodes (if exists), obstacles, and slot.
171     if "nodes_x" in scenario and "nodes_y" in scenario:
172         plt.plot(
173             scenario["nodes_x"] - MINX,
174             scenario["nodes_y"] - MINY,
175             color="lightgray",
176             marker="o",
177             ms=2,
178             lw=0,
179         )
180     if "obst" in scenario and len(scenario["obst"]) > 0:
181         for o in scenario["obst"]:
182             plt.plot(*plot_nodes(o), color="blue", linestyle=":")
183     if "slot" in scenario and len(scenario["slot"]) > 0:
184         plt.plot(*plot_nodes(scenario["slot"][0]), color="black")
185         #for s in scenario["slot"]:
186         #    plt.plot(*plot_nodes(s), color="black")
187
188     # Plot `init`, `entry`, and `goal` configurations.
189     if "init" in scenario and len(scenario["init"]) == 3:
190         plt.plot(*plot_car(scenario["init"]), color="red")
191         plt.plot(
192             scenario["init"][0] - MINX,
193             scenario["init"][1] - MINY,
194             color="red",
195             marker="+",
196             ms=12
197         )
198     if "entry" in scenario and len(scenario["entry"]) == 3:
199         plt.plot(*plot_car(scenario["entry"]), color="magenta")
200         plt.plot(
201             scenario["entry"][0] - MINX,
202             scenario["entry"][1] - MINY,
203             color="magenta",
204             marker="+",
205             ms=12
206         )
207     if "goal" in scenario and len(scenario["goal"]) == 3:
208         plt.plot(*plot_car(scenario["goal"]), color="green")
209         plt.plot(
210             scenario["goal"][0] - MINX,
211             scenario["goal"][1] - MINY,
212             color="green",
213             marker="+",
214             ms=12
215         )
216
217     # Plot `path` and `max_path`.
218     if "max_path" in scenario and  len(scenario["path"]) > 0:
219         plt.plot(*plot_nodes(scenario["max_path"]), color="orange")
220     if "path" in scenario and  len(scenario["path"]) > 0:
221         plt.plot(*plot_nodes(scenario["path"]), color="orange")
222
223     # If there are possible starts specified, you may print and plot them.
224     #if "starts" in scenario and len(scenario["starts"]) > 0:
225     #    print("possible starts:")
226     #    for p in scenario["starts"]:
227     #        plt.plot(*p, color="red", marker="+", ms=12)
228     #        print(" {}".format(p))
229
230     # For the Last Maneuver figure from the paper, use:
231     #   - `init2` -- orange
232     #plt.plot(*plot_car(scenario["init2"]), color="orange")
233     #plt.plot(
234     #    scenario["init2"][0] - MINX,
235     #    scenario["init2"][1] - MINY,
236     #    color="orange",
237     #    #marker="+",
238     #    ms=12
239     #)
240     #   - `goal2` -- orange
241     #plt.plot(*plot_car(scenario["goal2"]), color="orange")
242     #plt.plot(
243     #    scenario["goal2"][0] - MINX,
244     #    scenario["goal2"][1] - MINY,
245     #    color="orange",
246     #    #marker="+",
247     #    ms=12
248     #)
249     #   - `goal2` -- middle (orange)
250     #plt.plot(*plot_car(scenario["goals"][0]), 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     #   - `init1` -- green
259     #plt.plot(*plot_car(scenario["init1"]), color="green")
260     #plt.plot(
261     #    scenario["init1"][0] - MINX,
262     #    scenario["init1"][1] - MINY,
263     #    color="green",
264     #    #marker="+",
265     #    ms=12
266     #)
267     #   - `goal1` -- green
268     #plt.plot(*plot_car(scenario["goal1"]), color="green")
269     #plt.plot(
270     #    scenario["goal1"][0] - MINX,
271     #    scenario["goal1"][1] - MINY,
272     #    color="green",
273     #    #marker="+",
274     #    ms=12
275     #)
276
277     # For the Possible Entry Configurations from the paper, use:
278     #if "inits" in scenario:
279     #    for i in scenario["inits"]:
280     #        print(i)
281     #        if len(i) == 3:
282     #            plt.plot(*plot_car(i), color="gray")
283     #            plt.plot(
284     #                i[0] - MINX,
285     #                i[1] - MINY,
286     #                color="gray",
287     #                marker="+",
288     #                ms=12,
289     #            )
290     #    plt.plot(*plot_car(scenario["inits"][0]), color="magenta")
291     #    plt.plot(
292     #        scenario["inits"][0][0] - MINX,
293     #        scenario["inits"][0][1] - MINY,
294     #        color="magenta",
295     #        marker="+",
296     #        ms=12,
297     #    )
298
299     # The `scenario` may also include:
300     #   - `last` -- not sure what this is, see the source code. Maybe overlaps
301     #     with the `goal`.
302     #   - `last1` -- used to demonstrate In-Slot Planner (was Parking Slot
303     #     Planner (PSP.))
304     #   - `last2` -- used to demonstrate In-Slot Planner (was Parking Slot
305     #     Planner (PSP.))
306     #   - `max_orig_path` -- maximum original path. I used this when comparing
307     #     original paths but I had to copy the `max_orig_path` by hand from
308     #     different scenario result.
309     #   - `orig_path` -- the path before the optimization.
310     #   - `max_path` -- the maximum path after optimization. Must be copied by
311     #     hand.
312     #   - `path` -- optimized path of the scenario.
313
314     handles, labels = ax.get_legend_handles_labels()
315
316     # Uncommnent the following line and comment the plt.show() to store to the
317     # file.
318     plt.savefig("out.eps", bbox_inches="tight")
319     #plt.show()
320     plt.close(fig)