class StateRBPF: def __init__(self): # ----- Set parameters here! ----- # self.M = 200 # total number of particles パーティクルの数 self.f = 924.1770935 # focus length of camera [px] カメラの焦点距離 [px] #self.f = 1575.54144 # focus length of camera [px] カメラの焦点距離 [px] # Particle Filter self.noise_x_sys = 0.001 # system noise of position (SD) 位置のシステムノイズ(標準偏差) self.noise_x_sys_coefficient = 0.05 # system noise of position (coefficient) 位置のシステムノイズ(係数) self.noise_a_sys = 0.1 # system noise of acceleration (SD) 加速度のシステムノイズ(標準偏差) self.noise_g_sys = 0.01 # system noise of orientation (SD) 角度のシステムノイズ(標準偏差) self.noise_a_obs = 0.001 # observation noise of acceleration (SD) 加速度の観測ノイズ(標準偏差) self.noise_g_obs = 0.0001 # observation noise of orientation (SD) 角度の観測ノイズ(標準偏差) self.noise_camera = 5.0 # observation noise of camera (SD) カメラの観測ノイズ(標準偏差) self.noise_coplanarity = 0.1 # observation noise of coplanarity (SD) 共面条件の観測ノイズ(標準偏差) self.init() def init(self): self.isFirstTimeIMU = True self.isFirstTimeCamera = True self.lock = False self.t = 0.0 self.t1 = 0.0 self.t_camera = 0.0 self.t1_camera = 0.0 self.accel1 = np.array([0.0, 0.0, 0.0]) self.accel2 = np.array([0.0, 0.0, 0.0]) self.accel3 = np.array([0.0, 0.0, 0.0]) self.gyro = np.array([0.0, 0.0, 0.0]) self.P1 = np.identity(3) self.initParticleFilter() def initParticleFilter(self): self.pf = ParticleFilter().getParticleFilterClass("RBPF") self.pf.setFocus(self.f) self.pf.setParameter(self.noise_x_sys, self.noise_a_sys, self.noise_g_sys, self.noise_camera, self.noise_coplanarity, self.noise_x_sys_coefficient ) #パーティクルフィルタのパラメータ(ノイズ) parameters (noise) self.X = [] # パーティクルセット set of particles self.loglikelihood = 0.0 self.count = 1 self.step = 1 def initParticle(self, accel, ori): X = [] for i in xrange(self.M): particle = Particle() particle.initWithIMU(accel, ori) X.append(particle) return X def setObservationModel(self, observation_): self.pf.setObservationModel(observation_) """ This method is called from "sensor.py" when new IMU sensor data are arrived. time : time (sec) accel : acceleration in global coordinates ori : orientaion """ def setSensorData(self, time_, accel, ori, gyro_): # If process is locked by Image Particle Filter, do nothing if (self.lock): print("locked") return # Get current time self.t1 = self.t self.t = time_ self.dt = self.t - self.t1 self.gyro = gyro_ if (self.isFirstTimeIMU): # init particle self.X = self.initParticle(accel, ori) else: # exec particle filter self.X = self.pf.pf_step_IMU(self.X, self.dt, accel, ori, self.M, self.isFirstTimeCamera) if (self.isFirstTimeIMU): self.isFirstTimeIMU = False # Count self.count += 1 """ This method is called from Image class when new camera image data are arrived. time_ : time (sec) keypointPairs : list of KeyPointPair class objects """ def setImageData(self, time_, keypoints): # If IMU data has not been arrived yet, do nothing if (self.isFirstTimeIMU): return ######################## #print("=================") #print("step "+str(self.step)+" count "+str(self.count)) ########################### if (keypoints == "nomatch"): print("nomatch ***********************") self.reduce_particle_variance(self.X) self.count += 1 self.step += 1 return # Lock IMU process self.lock = True #start_time = time.clock() # Get current time self.t1 = self.t self.t = time_ self.dt = self.t - self.t1 self.t1_camera = self.t_camera self.t_camera = time_ dt_camera = self.t_camera - self.t1_camera # covariance matrix of position P = self.createPositionCovarianceMatrixFromParticle(self.X) #P *= 0.01 if (self.step > 0 and self.step < 10): #self.saveXYZasCSV(self.X,"1") pass if (self.isFirstTimeCamera): # exec particle filter self.X = self.pf.pf_step_camera_firsttime(self.X, self.dt, keypoints, self.step, P, self.M) else: # exec particle filter self.X = self.pf.pf_step_camera(self.X, self.dt, keypoints, self.step, P, self.M, self.X1, self.P1, dt_camera, self.gyro) if (self.step > 0 and self.step < 10): #self.saveXYZasCSV(self.X,"2") pass # Get prev position and orientation prevXx, prevXo = self.getPositionAndOrientation() self.X1 = Particle() self.X1.initWithPositionAndOrientation(prevXx, prevXo) self.P1 = P # Count self.count += 1 # Step (camera only observation step) self.step += 1 #end_time = time.clock() #print "%f" %(end_time-start_time) # Unlock IMU process self.lock = False if (self.isFirstTimeCamera): self.isFirstTimeCamera = False def reduce_particle_variance(self, X): """ This method is called when No-resampling = True. Reduce particle variance to avoid divergence of particles. """ x = [] # Calc average of position for X_ in X: x.append(X_.x) average = np.mean(x, axis=0) # Reduce variance of position for X_ in X: difference = X_.x - average X_.x = average + difference * 0.1 return X """ print Landmark (X,Y,Z) """ def printLandmark(self, X): print("-----") landmarks = self.getLandmarkXYZ(X) for key, value in landmarks.iteritems(): print(str(key) + " "), print(value) """ return Landmark (X,Y,Z) """ def getLandmarkXYZ(self, X): allLandmarks = {} # calc sum of landmark XYZ for x in X: for landmarkId, landmark in x.landmarks.iteritems(): xyz = landmark.getXYZ() if (allLandmarks.has_key(landmarkId) == False): allLandmarks[landmarkId] = xyz else: allLandmarks[landmarkId] += xyz # calc average of landamrk XYZ for key, value in allLandmarks.iteritems(): value /= float(self.M) return allLandmarks """ print (X,Y,Z) of particles """ def printXYZ(self, X): print("-----") for x in X: x.printXYZ() """ save (X,Y,Z) of particles as CSV file """ def saveXYZasCSV(self, X, appendix): x = [] for X_ in X: x.append(X_.x) date = datetime.datetime.now() #datestr = date.strftime("%Y%m%d_%H%M%S_") + "%04d" % (date.microsecond // 1000) #np.savetxt('./data/plot3d/'+datestr+'_xyz_'+appendix+'.csv', x, delimiter=',') datestr = date.strftime("%Y%m%d_%H%M%S_") np.savetxt('./data/output/particle_' + datestr + str(self.count) + '_' + appendix + '.csv', x, delimiter=',') """ create covariance matrix of position from particle set """ def createPositionCovarianceMatrixFromParticle(self, X): x = [] for X_ in X: if (len(x) == 0): x = X_.x else: x = np.vstack((x, X_.x)) P = np.cov(x.T) return P """ return estimated state vector of position and orientation """ def getPositionAndOrientation(self): x = [] o = [] for X_ in self.X: x.append(X_.x) o.append(X_.o) return np.mean(x, axis=0), np.mean(o, axis=0) """ This method is called from "Main.py" return estimated state vector """ def getState(self): x = [] v = [] a = [] o = [] for X_ in self.X: x.append(X_.x) v.append(X_.v) a.append(X_.a) o.append(X_.o) #print(np.var(x, axis=0)) return np.mean(x, axis=0), np.mean(v, axis=0), np.mean( a, axis=0), np.mean(o, axis=0)
class StateRBPF: def __init__(self): # ----- Set parameters here! ----- # self.M = 200 # total number of particles パーティクルの数 self.f = 924.1770935 # focus length of camera [px] カメラの焦点距離 [px] #self.f = 1575.54144 # focus length of camera [px] カメラの焦点距離 [px] # Particle Filter self.noise_x_sys = 0.001 # system noise of position (SD) 位置のシステムノイズ(標準偏差) self.noise_x_sys_coefficient = 0.05 # system noise of position (coefficient) 位置のシステムノイズ(係数) self.noise_a_sys = 0.1 # system noise of acceleration (SD) 加速度のシステムノイズ(標準偏差) self.noise_g_sys = 0.01 # system noise of orientation (SD) 角度のシステムノイズ(標準偏差) self.noise_a_obs = 0.001 # observation noise of acceleration (SD) 加速度の観測ノイズ(標準偏差) self.noise_g_obs = 0.0001 # observation noise of orientation (SD) 角度の観測ノイズ(標準偏差) self.noise_camera = 5.0 # observation noise of camera (SD) カメラの観測ノイズ(標準偏差) self.noise_coplanarity = 0.1 # observation noise of coplanarity (SD) 共面条件の観測ノイズ(標準偏差) self.init() def init(self): self.isFirstTimeIMU = True self.isFirstTimeCamera = True self.lock = False self.t = 0.0 self.t1 = 0.0 self.t_camera = 0.0 self.t1_camera = 0.0 self.accel1 = np.array([0.0, 0.0, 0.0]) self.accel2 = np.array([0.0, 0.0, 0.0]) self.accel3 = np.array([0.0, 0.0, 0.0]) self.gyro = np.array([0.0, 0.0, 0.0]) self.P1 = np.identity(3) self.initParticleFilter() def initParticleFilter(self): self.pf = ParticleFilter().getParticleFilterClass("RBPF") self.pf.setFocus(self.f) self.pf.setParameter(self.noise_x_sys, self.noise_a_sys, self.noise_g_sys, self.noise_camera, self.noise_coplanarity, self.noise_x_sys_coefficient) #パーティクルフィルタのパラメータ(ノイズ) parameters (noise) self.X = [] # パーティクルセット set of particles self.loglikelihood = 0.0 self.count = 1 self.step = 1 def initParticle(self, accel, ori): X = [] for i in xrange(self.M): particle = Particle() particle.initWithIMU(accel, ori) X.append(particle) return X def setObservationModel(self, observation_): self.pf.setObservationModel(observation_) """ This method is called from "sensor.py" when new IMU sensor data are arrived. time : time (sec) accel : acceleration in global coordinates ori : orientaion """ def setSensorData(self, time_, accel, ori, gyro_): # If process is locked by Image Particle Filter, do nothing if(self.lock): print("locked") return # Get current time self.t1 = self.t self.t = time_ self.dt = self.t - self.t1 self.gyro = gyro_ if(self.isFirstTimeIMU): # init particle self.X = self.initParticle(accel, ori) else: # exec particle filter self.X = self.pf.pf_step_IMU(self.X, self.dt, accel, ori, self.M, self.isFirstTimeCamera) if(self.isFirstTimeIMU): self.isFirstTimeIMU = False # Count self.count+=1 """ This method is called from Image class when new camera image data are arrived. time_ : time (sec) keypointPairs : list of KeyPointPair class objects """ def setImageData(self, time_, keypoints): # If IMU data has not been arrived yet, do nothing if(self.isFirstTimeIMU): return ######################## #print("=================") #print("step "+str(self.step)+" count "+str(self.count)) ########################### if(keypoints == "nomatch"): print("nomatch ***********************") self.reduce_particle_variance(self.X) self.count += 1 self.step += 1 return # Lock IMU process self.lock = True #start_time = time.clock() # Get current time self.t1 = self.t self.t = time_ self.dt = self.t - self.t1 self.t1_camera = self.t_camera self.t_camera = time_ dt_camera = self.t_camera - self.t1_camera # covariance matrix of position P = self.createPositionCovarianceMatrixFromParticle(self.X) #P *= 0.01 if(self.step > 0 and self.step < 10): #self.saveXYZasCSV(self.X,"1") pass if(self.isFirstTimeCamera): # exec particle filter self.X = self.pf.pf_step_camera_firsttime(self.X, self.dt, keypoints, self.step, P, self.M) else: # exec particle filter self.X = self.pf.pf_step_camera(self.X, self.dt, keypoints, self.step, P, self.M, self.X1, self.P1, dt_camera, self.gyro) if(self.step > 0 and self.step < 10): #self.saveXYZasCSV(self.X,"2") pass # Get prev position and orientation prevXx, prevXo = self.getPositionAndOrientation() self.X1 = Particle() self.X1.initWithPositionAndOrientation(prevXx, prevXo) self.P1 = P # Count self.count += 1 # Step (camera only observation step) self.step += 1 #end_time = time.clock() #print "%f" %(end_time-start_time) # Unlock IMU process self.lock = False if(self.isFirstTimeCamera): self.isFirstTimeCamera = False def reduce_particle_variance(self, X): """ This method is called when No-resampling = True. Reduce particle variance to avoid divergence of particles. """ x = [] # Calc average of position for X_ in X: x.append(X_.x) average = np.mean(x, axis=0) # Reduce variance of position for X_ in X: difference = X_.x - average X_.x = average + difference * 0.1 return X """ print Landmark (X,Y,Z) """ def printLandmark(self,X): print("-----") landmarks = self.getLandmarkXYZ(X) for key, value in landmarks.iteritems(): print(str(key)+" "), print(value) """ return Landmark (X,Y,Z) """ def getLandmarkXYZ(self,X): allLandmarks = {} # calc sum of landmark XYZ for x in X: for landmarkId, landmark in x.landmarks.iteritems(): xyz = landmark.getXYZ() if(allLandmarks.has_key(landmarkId) == False): allLandmarks[landmarkId] = xyz else: allLandmarks[landmarkId] += xyz # calc average of landamrk XYZ for key, value in allLandmarks.iteritems(): value /= float(self.M) return allLandmarks """ print (X,Y,Z) of particles """ def printXYZ(self,X): print("-----") for x in X: x.printXYZ() """ save (X,Y,Z) of particles as CSV file """ def saveXYZasCSV(self,X,appendix): x = [] for X_ in X: x.append(X_.x) date = datetime.datetime.now() #datestr = date.strftime("%Y%m%d_%H%M%S_") + "%04d" % (date.microsecond // 1000) #np.savetxt('./data/plot3d/'+datestr+'_xyz_'+appendix+'.csv', x, delimiter=',') datestr = date.strftime("%Y%m%d_%H%M%S_") np.savetxt('./data/output/particle_'+datestr+str(self.count)+'_'+appendix+'.csv', x, delimiter=',') """ create covariance matrix of position from particle set """ def createPositionCovarianceMatrixFromParticle(self, X): x = [] for X_ in X: if(len(x)==0): x = X_.x else: x = np.vstack((x,X_.x)) P = np.cov(x.T) return P """ return estimated state vector of position and orientation """ def getPositionAndOrientation(self): x = [] o = [] for X_ in self.X: x.append(X_.x) o.append(X_.o) return np.mean(x, axis=0),np.mean(o, axis=0) """ This method is called from "Main.py" return estimated state vector """ def getState(self): x = [] v = [] a = [] o = [] for X_ in self.X: x.append(X_.x) v.append(X_.v) a.append(X_.a) o.append(X_.o) #print(np.var(x, axis=0)) return np.mean(x, axis=0),np.mean(v, axis=0),np.mean(a, axis=0),np.mean(o, axis=0)