Esempio n. 1
0
class MyFrontEnd(FrontEnd):
    def __init__(self,omap_path,sparki):
        self.omap = ObstacleMap(omap_path,noise_range=0)
        self.rangefinder = Rangefinder(cone_width=deg2rad(15.),obstacle_width=1.)
    
        FrontEnd.__init__(self,self.omap.width,self.omap.height)

        self.sparki = sparki
        self.robot = Robot()

        # center robot
        self.robot.x = self.omap.width*0.5
        self.robot.y = self.omap.height*0.5

        # create particle filter
        alpha=[0.5,0.5,0.5,0.5,0.5,0.5]
        self.particle_filter = ParticleFilter(num_particles=100,alpha=alpha,robot=self.robot,omap=self.omap)
        
        self.sonar_step = deg2rad(1.)

    def keydown(self,key):
        # update velocities based on key pressed
        if key == pygame.K_UP: # set positive linear velocity
            self.robot.lin_vel = 20.0
        elif key == pygame.K_DOWN: # set negative linear velocity
            self.robot.lin_vel = -20.0
        elif key == pygame.K_LEFT: # set positive angular velocity
            self.robot.ang_vel = 100.*math.pi/180.
        elif key == pygame.K_RIGHT: # set negative angular velocity
            self.robot.ang_vel = -100.*math.pi/180.
        elif key == pygame.K_k: # set positive servo angle
            self.robot.sonar_angle = 45.*math.pi/180.
        elif key == pygame.K_l: # set negative servo angle
            self.robot.sonar_angle = -45.*math.pi/180.
    
    def keyup(self,key):
        # update velocities based on key released
        if key == pygame.K_UP or key == pygame.K_DOWN: # set zero linear velocity
            self.robot.lin_vel = 0
        elif key == pygame.K_LEFT or key == pygame.K_RIGHT: # set zero angular velocity
            self.robot.ang_vel = 0
        elif key == pygame.K_k or key == pygame.K_l: # set zero servo angle
            self.robot.sonar_angle = 0
        
    def draw(self,surface):
        # draw obstacle map
        self.omap.draw(surface)

        # draw robot
        self.robot.draw(surface)
        
        # draw particles
        self.particle_filter.draw(surface)
    
    def update(self,time_delta):
        # Get map/sonar transformation matrices
        T_map_sonar = self.robot.get_robot_sonar_transform()*self.robot.get_map_robot_transform()
        T_sonar_map = self.robot.get_robot_map_transform()*self.robot.get_sonar_robot_transform()

        if self.sparki.port == '':
            # calculate sonar distance from map
            self.robot.sonar_distance = self.omap.get_first_hit(T_sonar_map)
        else:
            # get current rangefinder reading
            self.robot.sonar_distance = self.sparki.dist
        
        # update particles
        self.particle_filter.generate(time_delta)
        self.particle_filter.update()
        self.particle_filter.sample()
        
        # calculate servo setting
        servo = int(self.robot.sonar_angle*180./math.pi)

        # calculate motor settings
        left_speed, left_dir, right_speed, right_dir = self.robot.compute_motors()

        # send command
        self.sparki.send_command(left_speed,left_dir,right_speed,right_dir,servo)
        
        # update robot position
        self.robot.update(time_delta)
Esempio n. 2
0
class MyFrontEnd(FrontEnd):
    def __init__(self, omap_path, sparki):
        self.omap = ObstacleMap(omap_path, noise_range=1)
        self.rangefinder = Rangefinder(cone_width=deg2rad(15.),
                                       obstacle_width=1.)

        FrontEnd.__init__(self, self.omap.width, self.omap.height)

        self.sparki = sparki
        self.robot = Robot()

        # center robot
        self.robot.x = self.omap.width * 0.5
        self.robot.y = self.omap.height * 0.5

        # create particle filter
        alpha = [0.5, 0.5, 0.5, 0.5]
        self.particle_filter = ParticleFilter(num_particles=50,
                                              alpha=alpha,
                                              robot=self.robot,
                                              omap=self.omap)

        # set message callback
        self.sparki.message_callback = self.message_received

        # last timestamp received
        self.last_timestamp = 0

    def keydown(self, key):
        # update velocities based on key pressed
        if key == pygame.K_UP:  # set positive linear velocity
            self.robot.requested_lin_vel = 2.0
        elif key == pygame.K_DOWN:  # set negative linear velocity
            self.robot.requested_lin_vel = -2.0
        elif key == pygame.K_LEFT:  # set positive angular velocity
            self.robot.requested_ang_vel = 10. * math.pi / 180.
        elif key == pygame.K_RIGHT:  # set negative angular velocity
            self.robot.requested_ang_vel = -10. * math.pi / 180.
        elif key == pygame.K_k:  # set positive servo angle
            self.robot.requested_sonar_angle = 45. * math.pi / 180.
        elif key == pygame.K_l:  # set negative servo angle
            self.robot.requested_sonar_angle = -45. * math.pi / 180.

    def keyup(self, key):
        # update velocities based on key released
        if key == pygame.K_UP or key == pygame.K_DOWN:  # set zero linear velocity
            self.robot.requested_lin_vel = 0
        elif key == pygame.K_LEFT or key == pygame.K_RIGHT:  # set zero angular velocity
            self.robot.requested_ang_vel = 0
        elif key == pygame.K_k or key == pygame.K_l:  # set zero servo angle
            self.robot.requested_sonar_angle = 0

    def draw(self, surface):
        # draw obstacle map
        self.omap.draw(surface)

        # draw robot
        self.robot.draw(surface)

        # draw particles
        self.particle_filter.draw(surface)

    def update(self):
        """ Sends command to robot, if not in simulator mode. """
        if self.sparki.port is not '':
            # calculate servo setting
            servo = int(self.robot.requested_sonar_angle * 180. / math.pi)

            # calculate motor settings
            left_speed, left_dir, right_speed, right_dir = self.robot.compute_motors(
            )

            # send command
            self.sparki.send_command(left_speed, left_dir, right_speed,
                                     right_dir, servo)

    def message_received(self, message):
        """ Callback for when a message is received from the robot or the simulator.
            Arguments:
                message: dictionary with status values
        """
        # check if there is no previous timestamp
        if self.last_timestamp == 0:
            self.last_timestamp = message['timestamp']
            return

        # calculate time_delta based on the current and previous timestamps
        time_delta = (message['timestamp'] - self.last_timestamp) / 1000.
        self.last_timestamp = message['timestamp']
        # print(time_delta)

        # update linear and angular velocities
        if 'left_motor_speed' in message.keys():
            # calculate linear and angular velocities from reported motor settings
            left_speed = message['left_motor_speed']
            left_dir = message['left_motor_dir']
            right_speed = message['right_motor_speed']
            right_dir = message['right_motor_dir']

            # print(left_speed,left_dir,right_speed,right_dir)
            self.robot.compute_velocities(left_speed, left_dir, right_speed,
                                          right_dir)
        else:
            # copy requested velocities to actual velocities
            self.robot.lin_vel = self.robot.requested_lin_vel
            self.robot.ang_vel = self.robot.requested_ang_vel

        # update robot position using forward kinematics
        self.robot.update(time_delta)

        # update sonar ping distance
        if 'rangefinder' in message.keys():
            # convert to cm
            self.robot.sonar_distance = message['rangefinder']
        else:
            # simulate rangefinder reading
            T_sonar_map = self.robot.get_robot_map_transform(
            ) * self.robot.get_sonar_robot_transform()
            self.robot.sonar_distance = self.omap.get_first_hit(T_sonar_map)

        # update particles
        self.particle_filter.generate(time_delta)
        self.particle_filter.update()
        self.particle_filter.sample()