def __init__(self, sflist, c_map, case): ''' Constructor ''' self.sflist = sflist self.noise_model = [case.noise_turn, case.noise_velocity] self.c_map = c_map self.goal_graph = case.goal_graph # Command algo self.cmd_algo = CmdBiased(case, c_map) # self.cmd_algo = CmdRandom(case, c_map) self.deltick = case.deltick # Initialize particle filters for each SensorFly dir self.pfilters = {} for sf in self.sflist: pf = RobotPF(sf, case.num_particles, case.init_p_wt, \ self.noise_model, case.deltick) self.pfilters[sf.name] = pf sf.pf_estimated_xy = np.array(sf.xy, np.float32) # record the actual position without pf correction self.dr_estimated_pos = {} for sf in sflist: self.dr_estimated_pos[sf.name] = [sf.xy, sf.dir] sf.dr_estimated_xy = np.array(sf.xy, np.float32) # Iniitialize a landmark database self.landmark_db = LandmarkDB(case)
class DrunkWalk(object): ''' DrunkWalk deployment algorithm ''' def __init__(self, sflist, c_map, case): ''' Constructor ''' self.sflist = sflist self.noise_model = [case.noise_turn, case.noise_velocity] self.c_map = c_map self.goal_graph = case.goal_graph # Command algo self.cmd_algo = CmdBiased(case, c_map) # self.cmd_algo = CmdRandom(case, c_map) self.deltick = case.deltick # Initialize particle filters for each SensorFly dir self.pfilters = {} for sf in self.sflist: pf = RobotPF(sf, case.num_particles, case.init_p_wt, \ self.noise_model, case.deltick) self.pfilters[sf.name] = pf sf.pf_estimated_xy = np.array(sf.xy, np.float32) # record the actual position without pf correction self.dr_estimated_pos = {} for sf in sflist: self.dr_estimated_pos[sf.name] = [sf.xy, sf.dir] sf.dr_estimated_xy = np.array(sf.xy, np.float32) # Iniitialize a landmark database self.landmark_db = LandmarkDB(case) def command(self): ''' Command as per the planning algorithm ''' for sf in self.sflist: cmd = self.cmd_algo.getCommand(sf) if cmd: sf.setMoveCommand(cmd) def update(self): ''' Update the estimates as per command ''' for sf in self.sflist: # Collision back-off strategy if sf.has_collided: if sf.is_backing_off: sf.backoff_time_cnt = 0 else: sf.backoff_time_cnt = sf.backoff_time_cnt + 2 if sf.backoff_time_cnt < 5 else 5 else: if not sf.is_backing_off: sf.backoff_time_cnt = sf.backoff_time_cnt - 1 if sf.backoff_time_cnt > 1 else 0 # Particle filter update if not sf.has_collided: pf = self.pfilters[sf.name] # Predict pf.predict(sf.command) # Correct pf.correct(self.landmark_db) # Resample pf.resample_fast() # Record estimated location sf.pf_estimated_xy = pf.getEstimate() sf.pf_particles_xy = pf.particles_xy # Dead reckoning update if not sf.has_collided: pos = self.dr_estimated_pos[sf.name] # Get direction from magnetometer if sf.has_turned: # Add noise to turn pos[1] = (pos[1] + sf.command.turn) % 360 # Compute new poses # pos[1] = sf.mag_dir # Update location on all ticks pos[0][0] = pos[0][0] + (sf.command.velocity * self.deltick) * math.cos(math.radians(pos[1])) pos[0][1] = pos[0][1] + (sf.command.velocity * self.deltick) * math.sin(math.radians(pos[1])) self.dr_estimated_pos[sf.name] = pos sf.dr_estimated_xy = np.array(pos[0], np.float32)