|  | 
| 9 | 9 | import numpy as np | 
| 10 | 10 | import math | 
| 11 | 11 | import copy | 
|  | 12 | +import itertools | 
| 12 | 13 | import matplotlib.pyplot as plt | 
| 13 | 14 | 
 | 
| 14 | 15 | 
 | 
| 15 |  | -# EKF state covariance | 
| 16 |  | -Cx = np.diag([0.5, 0.5, math.radians(30.0)])**2 | 
| 17 |  | - | 
| 18 | 16 | #  Simulation parameter | 
| 19 | 17 | Qsim = np.diag([0.2, math.radians(1.0)])**2 | 
| 20 | 18 | Rsim = np.diag([1.0, math.radians(10.0)])**2 | 
|  | 
| 31 | 29 | show_animation = True | 
| 32 | 30 | 
 | 
| 33 | 31 | 
 | 
|  | 32 | +class Edge(): | 
|  | 33 | + | 
|  | 34 | +    def __init__(self): | 
|  | 35 | +        self.e = np.zeros((3, 1)) | 
|  | 36 | + | 
|  | 37 | + | 
|  | 38 | +def calc_edges(xlist, zlist): | 
|  | 39 | + | 
|  | 40 | +    edges = [] | 
|  | 41 | +    zids = list(itertools.combinations(range(len(zlist)), 2)) | 
|  | 42 | +    #  print(zids) | 
|  | 43 | + | 
|  | 44 | +    for (t, td) in zids: | 
|  | 45 | +        xt = xlist[0, t] | 
|  | 46 | +        yt = xlist[1, t] | 
|  | 47 | +        yawt = xlist[2, t] | 
|  | 48 | +        xtd = xlist[0, td] | 
|  | 49 | +        ytd = xlist[1, td] | 
|  | 50 | +        yawtd = xlist[2, td] | 
|  | 51 | + | 
|  | 52 | +        dt = zlist[t][0, 0] | 
|  | 53 | +        anglet = zlist[t][1, 0] | 
|  | 54 | +        phit = zlist[t][2, 0] | 
|  | 55 | + | 
|  | 56 | +        dtd = zlist[td][0, 0] | 
|  | 57 | +        angletd = zlist[td][0, 0] | 
|  | 58 | +        phitd = zlist[td][2, 0] | 
|  | 59 | + | 
|  | 60 | +        edge = Edge() | 
|  | 61 | + | 
|  | 62 | +        t1 = dt * math.cos(yawt + anglet) | 
|  | 63 | +        t2 = dtd * math.cos(yawtd + angletd) | 
|  | 64 | +        t3 = dt * math.sin(yawt + anglet) | 
|  | 65 | +        t4 = dtd * math.sin(yawtd + angletd) | 
|  | 66 | + | 
|  | 67 | +        edge.e[0, 0] = xtd - xt - t1 + t2 | 
|  | 68 | +        edge.e[1, 0] = ytd - yt - t3 + t4 | 
|  | 69 | +        edge.e[2, 0] = yawtd - yawt - phit + phitd | 
|  | 70 | + | 
|  | 71 | +        edges.append(edge) | 
|  | 72 | + | 
|  | 73 | +    return edges | 
|  | 74 | + | 
|  | 75 | + | 
| 34 | 76 | def graph_based_slam(xEst, PEst, u, z, hxDR, hz): | 
| 35 | 77 | 
 | 
| 36 | 78 |     x_opt = copy.deepcopy(hxDR) | 
| 37 | 79 | 
 | 
| 38 | 80 |     for itr in range(20): | 
| 39 |  | -        #  pos_edges = [] | 
| 40 |  | - | 
| 41 |  | -        #  # このfor文では、HalfEdgeからグラフの辺を作っていきます。 | 
| 42 |  | -        #  for i in range(len(actual_landmarks.positions)):                           # ランドマークごとにHalfEdgeからEdgeを作る | 
| 43 |  | -        #  es = list(filter(lambda e: e.landmark_id == i, obs_edges))      # 同じランドマークIDを持つHalfEdgeの抽出 | 
| 44 |  | -        #  ps = list(itertools.combinations(es,2))                                       # esの要素のペアを全通り作る | 
| 45 |  | -        #  for p in ps: | 
| 46 |  | -            #  pos_edges.append(Edge(p[0],p[1]))                                    # エッジを登録 | 
|  | 81 | +        edges = calc_edges(x_opt, hz) | 
|  | 82 | +        print("nedges:", len(edges)) | 
| 47 | 83 | 
 | 
| 48 | 84 |         n = len(hz) * 3 | 
| 49 | 85 |         H = np.zeros((n, n)) | 
| @@ -87,18 +123,19 @@ def observation(xTrue, xd, u, RFID): | 
| 87 | 123 |     xTrue = motion_model(xTrue, u) | 
| 88 | 124 | 
 | 
| 89 | 125 |     # add noise to gps x-y | 
| 90 |  | -    z = np.matrix(np.zeros((0, 3))) | 
|  | 126 | +    z = np.matrix(np.zeros((0, 4))) | 
| 91 | 127 | 
 | 
| 92 | 128 |     for i in range(len(RFID[:, 0])): | 
| 93 | 129 | 
 | 
| 94 | 130 |         dx = RFID[i, 0] - xTrue[0, 0] | 
| 95 | 131 |         dy = RFID[i, 1] - xTrue[1, 0] | 
| 96 | 132 |         d = math.sqrt(dx**2 + dy**2) | 
| 97 |  | -        angle = pi_2_pi(math.atan2(dy, dx)) | 
|  | 133 | +        angle = pi_2_pi(math.atan2(dy, dx)) - xTrue[2, 0] | 
|  | 134 | +        phi = angle - xTrue[2, 0] | 
| 98 | 135 |         if d <= MAX_RANGE: | 
| 99 | 136 |             dn = d + np.random.randn() * Qsim[0, 0]  # add noise | 
| 100 | 137 |             anglen = angle + np.random.randn() * Qsim[1, 1]  # add noise | 
| 101 |  | -            zi = np.matrix([dn, anglen, i]) | 
|  | 138 | +            zi = np.matrix([dn, anglen, phi, i]) | 
| 102 | 139 |             z = np.vstack((z, zi)) | 
| 103 | 140 | 
 | 
| 104 | 141 |     # add noise to input | 
| @@ -141,11 +178,11 @@ def main(): | 
| 141 | 178 | 
 | 
| 142 | 179 |     time = 0.0 | 
| 143 | 180 | 
 | 
| 144 |  | -    # RFID positions [x, y] | 
| 145 |  | -    RFID = np.array([[10.0, -2.0], | 
| 146 |  | -                     [15.0, 10.0], | 
| 147 |  | -                     [3.0, 15.0], | 
| 148 |  | -                     [-5.0, 20.0]]) | 
|  | 181 | +    # RFID positions [x, y, yaw] | 
|  | 182 | +    RFID = np.array([[10.0, -2.0, 0.0], | 
|  | 183 | +                     [15.0, 10.0, 0.0], | 
|  | 184 | +                     [3.0, 15.0, 0.0], | 
|  | 185 | +                     [-5.0, 20.0, 0.0]]) | 
| 149 | 186 | 
 | 
| 150 | 187 |     # State Vector [x y yaw v]' | 
| 151 | 188 |     xEst = np.matrix(np.zeros((STATE_SIZE, 1))) | 
|  | 
0 commit comments