Skip to content

Commit 74b8432

Browse files
committed
start implement lectangle fitting
1 parent d2ab014 commit 74b8432

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
"""
2+
3+
Object shape recognition with rectangle fitting
4+
5+
author: Atsushi Sakai (@Atsushi_twi)
6+
7+
"""
8+
9+
import matplotlib.pyplot as plt
10+
import math
11+
import random
12+
import numpy as np
13+
14+
show_animation = True
15+
16+
17+
class VehicleSimulator():
18+
19+
def __init__(self, ix, iy, iyaw, iv, max_v, w, L):
20+
self.x = ix
21+
self.y = iy
22+
self.yaw = iyaw
23+
self.v = iv
24+
self.max_v = max_v
25+
self.W = w
26+
self.L = L
27+
self._calc_vehicle_contour()
28+
29+
def update(self, dt, a, omega):
30+
self.x += self.v * math.cos(self.yaw) * dt
31+
self.y += self.v * math.sin(self.yaw) * dt
32+
self.yaw += omega * dt
33+
self.v += a * dt
34+
if self.v >= self.max_v:
35+
self.v = self.max_v
36+
37+
def plot(self):
38+
plt.plot(self.x, self.y, ".r")
39+
40+
# convert global coordinate
41+
gx, gy = self.calc_global_contour()
42+
plt.plot(gx, gy, "-xr")
43+
44+
def calc_global_contour(self):
45+
gx = [(ix * math.cos(self.yaw) + iy * math.sin(self.yaw)) +
46+
self.x for (ix, iy) in zip(self.vc_x, self.vc_y)]
47+
gy = [(ix * math.sin(self.yaw) - iy * math.cos(self.yaw)) +
48+
self.y for (ix, iy) in zip(self.vc_x, self.vc_y)]
49+
50+
return gx, gy
51+
52+
def _calc_vehicle_contour(self):
53+
54+
self.vc_x = []
55+
self.vc_y = []
56+
57+
self.vc_x.append(self.L / 2.0)
58+
self.vc_y.append(self.W / 2.0)
59+
60+
self.vc_x.append(self.L / 2.0)
61+
self.vc_y.append(-self.W / 2.0)
62+
63+
self.vc_x.append(-self.L / 2.0)
64+
self.vc_y.append(-self.W / 2.0)
65+
66+
self.vc_x.append(-self.L / 2.0)
67+
self.vc_y.append(self.W / 2.0)
68+
69+
self.vc_x.append(self.L / 2.0)
70+
self.vc_y.append(self.W / 2.0)
71+
72+
self.vc_x, self.vc_y = self._interporate(self.vc_x, self.vc_y)
73+
74+
def _interporate(self, x, y):
75+
rx, ry = [], []
76+
dtheta = 0.05
77+
for i in range(len(x) - 1):
78+
rx.extend([(1.0 - θ) * x[i] + θ * x[i + 1]
79+
for θ in np.arange(0.0, 1.0, dtheta)])
80+
ry.extend([(1.0 - θ) * y[i] + θ * y[i + 1]
81+
for θ in np.arange(0.0, 1.0, dtheta)])
82+
83+
rx.extend([(1.0 - θ) * x[len(x) - 1] + θ * x[1]
84+
for θ in np.arange(0.0, 1.0, dtheta)])
85+
ry.extend([(1.0 - θ) * y[len(y) - 1] + θ * y[1]
86+
for θ in np.arange(0.0, 1.0, dtheta)])
87+
88+
return rx, ry
89+
90+
91+
def get_observation_points(vlist, angle_reso):
92+
x, y, angle, r = [], [], [], []
93+
94+
# store all points
95+
for v in vlist:
96+
97+
gx, gy = v.calc_global_contour()
98+
99+
for vx, vy in zip(gx, gy):
100+
vangle = math.atan2(vy, vx)
101+
vr = math.hypot(vx, vy) # * random.uniform(0.95, 1.05)
102+
103+
x.append(vx)
104+
y.append(vy)
105+
angle.append(vangle)
106+
r.append(vr)
107+
108+
# ray casting filter
109+
rx, ry = ray_casting_filter(x, y, angle, r, angle_reso)
110+
111+
return rx, ry
112+
113+
114+
def ray_casting_filter(xl, yl, thetal, rangel, angle_reso):
115+
rx, ry = [], []
116+
rangedb = [float("inf") for _ in range(
117+
int(math.floor((math.pi * 2.0) / angle_reso)) + 1)]
118+
119+
for i in range(len(thetal)):
120+
angleid = int(round(thetal[i] / angle_reso))
121+
122+
if rangedb[angleid] > rangel[i]:
123+
rangedb[angleid] = rangel[i]
124+
125+
for i in range(len(rangedb)):
126+
t = i * angle_reso
127+
if rangedb[i] != float("inf"):
128+
rx.append(rangedb[i] * math.cos(t))
129+
ry.append(rangedb[i] * math.sin(t))
130+
131+
return rx, ry
132+
133+
134+
def main():
135+
136+
# simulation parameters
137+
simtime = 30.0 # simulation time
138+
dt = 0.2 # time tick
139+
140+
angle_reso = np.deg2rad(3.0) # sensor angle resolution
141+
142+
v1 = VehicleSimulator(-10.0, 0.0, np.deg2rad(90.0),
143+
0.0, 50.0 / 3.6, 3.0, 5.0)
144+
v2 = VehicleSimulator(20.0, 10.0, np.deg2rad(180.0),
145+
0.0, 50.0 / 3.6, 4.0, 10.0)
146+
147+
time = 0.0
148+
while time <= simtime:
149+
time += dt
150+
151+
v1.update(dt, 0.1, 0.0)
152+
v2.update(dt, 0.1, -0.05)
153+
154+
ox, oy = get_observation_points([v1, v2], angle_reso)
155+
156+
if show_animation: # pragma: no cover
157+
plt.cla()
158+
plt.axis("equal")
159+
plt.plot(0.0, 0.0, "*r")
160+
v1.plot()
161+
v2.plot()
162+
163+
plt.plot(ox, oy, "ob")
164+
# plt.plot(x, y, "xr")
165+
# plot_circle(ex, ey, er, "-r")
166+
plt.pause(0.1)
167+
168+
print("Done")
169+
170+
171+
if __name__ == '__main__':
172+
main()

0 commit comments

Comments
 (0)