Esempio n. 1
0
    def calc_desired_velocity(self, bots, obstacles, targets):
        vel = self.vel
        if self.movement != Movement.Accel:
            vel = Vector(0, 0)
        for inter in bots:
            if (not KNOW_BOT_POSITIONS) and dist(inter.real.pos, self.pos) > self.max_sensing_distance:
                continue
            force = -potential.gradient(potential.morse(r0=2 * BOT_RADIUS, k=2.5, a=4.0),
                                        dist(inter.real.pos, self.pos),
                                        self.pos - inter.real.pos,
                                        self.radius + inter.virtual.radius)
            vel += _FORCE_SENSITIVITY * force

        for target in targets:
            force = -potential.gradient(potential.linear(k=-2.0),
                                        dist(target, self.pos),
                                        target - self.pos,
                                        0)
            vel += _FORCE_SENSITIVITY * force

        for obstacle in obstacles:
            if obstacle.distance(self.pos) <= self.max_sensing_distance:
                force = -potential.gradient(potential.inverse_quadratic(k=1.0),
                                            obstacle.distance(self.pos),
                                            obstacle.repulsion_dir(self.pos),
                                            OBSTACLE_CLEARANCE + self.radius)
                vel += _FORCE_SENSITIVITY * force

        if self.movement == Movement.Dir:
            if length(vel) > 0:
                vel = normalize(vel)
        return vel
Esempio n. 2
0
 def get_distance(self, bot_pos, bot_angle, obstacles):
     ray = self.get_ray(bot_pos, bot_angle)
     p = first_intersection(ray, obstacles)
     if p is None:
         return self.max_distance
     else:
         return min(self.max_distance, dist(ray.orig, p))
Esempio n. 3
0
 def get_distance(self, bot_pos, bot_angle, obstacles):
     ray = self.get_ray(bot_pos, bot_angle)
     p = first_intersection(ray, obstacles)
     if p is None:
         return self.max_distance
     else:
         return min(self.max_distance, dist(ray.orig, p))
Esempio n. 4
0
    def draw(self, screen, field):
        if config.DISPLAYED_POINTS_COUNT > 0:
            k = config.POSITIONS_BUFFER_SIZE / config.DISPLAYED_POINTS_COUNT
            if k == 0:
                k = 1
            for index, (time, point) in enumerate(self.leader_positions):
                if index % k == 0:
                    draw_circle(screen, field, config.TRAJECTORY_POINTS_COLOR, point, 0.03, 1)
            for index, (time, point) in enumerate(self.noisy_leader_positions):
                if index % k == 0:
                    draw_circle(screen, field, config.NOISY_TRAJECTORY_POINTS_COLOR, point, 0.03, 1)

        if config.DISPLAYED_USED_POINTS_COUNT > 0:
            k = len(self.traj_interval) / config.DISPLAYED_USED_POINTS_COUNT
            if k == 0:
                k = 1
            for index, (time, point) in enumerate(self.traj_interval):
                if index % k == 0:
                    draw_circle(screen, field, config.USED_TRAJECTORY_POINTS_COLOR, point, 0.03, 1)

        if config.DRAW_DELAYED_LEADER_POS:
            try:
                orig_leader_dir = Vector(cos(self.orig_leader_theta),
                                         sin(self.orig_leader_theta))
                draw_directed_circle(screen, field, (0, 255, 0),
                                     self.orig_leader_pos, 0.2,
                                     orig_leader_dir, 1)
            except AttributeError:
                pass

        if config.DRAW_SENSOR_RANGE:
            ang = atan2(self.real_dir.y, self.real_dir.x)
            draw_arc(screen, field, config.SENSOR_COLOR, self.pos, self.visibility_radius,
                                    ang - 0.5 * self.visibility_fov,
                                    ang + 0.5 * self.visibility_fov,
                                    1)
            draw_line(screen, field, config.SENSOR_COLOR,
                      self.pos,
                      self.pos + rotate(self.real_dir * self.visibility_radius,
                                        0.5 * self.visibility_fov),
                      1)
            draw_line(screen, field, config.SENSOR_COLOR,
                      self.pos,
                      self.pos + rotate(self.real_dir * self.visibility_radius,
                                        -0.5 * self.visibility_fov),
                      1)

        try:
            if config.DRAW_VISIBILITY and self.leader_is_visible:
                draw_circle(screen, field, config.config.VISIBILITY_COLOR, self.leader.real.pos,
                            0.5 * config.BOT_RADIUS)
        except AttributeError:
            pass

        try:
            if config.DRAW_REFERENCE_POS:
                draw_circle(screen, field, config.TARGET_POINT_COLOR, self.target_point, 0.2)

            if config.DRAW_APPROX_TRAJECTORY and self.trajectory is not None:
                #if len(self.traj_interval) > 1:
                #    p2 = Point(self.traj_interval[0].pos.x,
                #               self.traj_interval[0].pos.y)
                #    for t, p in self.traj_interval:
                #        draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)
                #        p2 = p

                step = (self.t_fn - self.t_st) / config.TRAJECTORY_SEGMENT_COUNT
                for t in (self.t_st + k * step for k in xrange(config.TRAJECTORY_SEGMENT_COUNT)):
                    p = Point(self.trajectory.x(t),
                              self.trajectory.y(t))
                    p2 = Point(self.trajectory.x(t + step),
                               self.trajectory.y(t + step))
                    draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)

                p_st = Point(self.trajectory.x(self.t_st), self.trajectory.y(self.t_st))
                p_fn = Point(self.trajectory.x(self.t_fn), self.trajectory.y(self.t_fn))

                step = 0.5 / config.TRAJECTORY_SEGMENT_COUNT
                p = p_fn
                p2 = p
                t = self.t_fn
                it = 0
                while it < config.TRAJECTORY_SEGMENT_COUNT and min(dist(p, p_fn), dist(p, p_st)) < 1.0:
                    it += 1
                    t += step
                    p2 = p
                    p = Point(self.trajectory.x(t), self.trajectory.y(t))
                    draw_line(screen, field, config.APPROX_TRAJECTORY_COLOR, p, p2)

        except AttributeError as e: # approximation hasn't been calculated yet
            pass
Esempio n. 5
0
    def calc_desired_velocity(self, bots, obstacles, targets):
        vel = self.real_vel
        self.collision_delta_time = length(vel) / BOT_ACCEL_CAP
        if self.movement != Movement.Accel:
            vel = Vector(0, 0)
        for inter in bots:
            if (not KNOW_BOT_POSITIONS) and dist(inter.real.pos, self.pos) > self.max_sensing_distance:
                continue
            force = -potential.gradient(potential.morse(r0=2 * BOT_RADIUS, k=2.5, a=4.0),
                                        dist(inter.real.pos, self.pos),
                                        self.pos - inter.real.pos,
                                        self.radius + inter.virtual.radius)
            vel += _FORCE_SENSITIVITY * force

        for target in targets:
            force = -potential.gradient(potential.linear(k=-10.0),
                                        dist(target, self.pos),
                                        target - self.pos,
                                        0)
            vel += _FORCE_SENSITIVITY * force


        if ROTATE_SENSORS:
            ang = self.get_heading_angle()
        else:
            ang = 0.0
        self.distances = []
        for s in self.sensors:
            d = s.get_distance(self.pos, ang, obstacles)
            self.distances.append(d)
            if d < self.max_sensing_distance:
                force = -potential.gradient(potential.inverse_quadratic(k=1.5),
                                            d,
                                            -s.get_ray(self.pos, ang).dir,
                                            OBSTACLE_CLEARANCE)
                vel += _FORCE_SENSITIVITY * force * self.obstacle_force_coeff

        if self.movement == Movement.Dir:
            if length(vel) > 0:
                vel = normalize(vel)

        # TODO: get max_vel from corresponding Model
        if length(vel) > BOT_VEL_CAP:
            vel = normalize(vel) * BOT_VEL_CAP

        self.virtual_vel_before_check = vel
        if COLLISION_CHECK:
            # check for possible collisions:
            # stop moving forward if an obstacle is nearby
            collision = False
            abs_vel = length(vel)
            if ROTATE_SENSORS:
                ang = self.get_heading_angle()
            else:
                ang = 0.0
            for cur_d, s in zip(self.distances, self.sensors):
                if cur_d == s.max_distance:
                    continue
                r = s.get_ray(self.pos, ang)
                c = cos(signed_angle(vel, r.dir))
                new_d = cur_d - c * abs_vel * self.collision_delta_time
                if new_d < CRITICAL_DIST and new_d < cur_d:
                    collision = True
                    break
            if not collision:
                # separate check for possible collision with another bot
                for inter in bots:
                    # don't count collsions with self
                    if inter.virtual is self:
                        continue
                    new_d = dist(inter.real.pos + self.collision_delta_time * inter.real.vel,
                                 self.pos + self.collision_delta_time * vel)
                    new_d -= (self.radius + inter.real.radius)
                    cur_d = dist(inter.real.pos, self.pos)
                    cur_d -= (self.radius + inter.real.radius)
                    if d <= CRITICAL_DIST and new_d < cur_d:
                        collision = True
                        break
            if collision:
                vel = normalize(vel) * CRITICAL_VEL
                self.collision = True
            else:
                self.collision = False

        return vel
Esempio n. 6
0
 def testDist(self):
     self.assertAlmostEqual(dist(Point(0.0, 0.0), Point(0.0, 0.0)),
                            0.0, geom_places)
     self.assertAlmostEqual(dist(Point(1.0, 2.0), Point(0.0, 3.0)),
                            2**0.5, geom_places)
Esempio n. 7
0
    def calc_desired_velocity(self, bots, obstacles, targets):
        vel = self.real_vel
        self.collision_delta_time = length(vel) / BOT_ACCEL_CAP
        if self.movement != Movement.Accel:
            vel = Vector(0, 0)
        for inter in bots:
            if (not KNOW_BOT_POSITIONS) and dist(
                    inter.real.pos, self.pos) > self.max_sensing_distance:
                continue
            force = -potential.gradient(
                potential.morse(r0=2 * BOT_RADIUS, k=2.5, a=4.0),
                dist(inter.real.pos, self.pos), self.pos - inter.real.pos,
                self.radius + inter.virtual.radius)
            vel += _FORCE_SENSITIVITY * force

        for target in targets:
            force = -potential.gradient(potential.linear(
                k=-10.0), dist(target, self.pos), target - self.pos, 0)
            vel += _FORCE_SENSITIVITY * force

        if ROTATE_SENSORS:
            ang = self.get_heading_angle()
        else:
            ang = 0.0
        self.distances = []
        for s in self.sensors:
            d = s.get_distance(self.pos, ang, obstacles)
            self.distances.append(d)
            if d < self.max_sensing_distance:
                force = -potential.gradient(potential.inverse_quadratic(k=1.5),
                                            d, -s.get_ray(self.pos, ang).dir,
                                            OBSTACLE_CLEARANCE)
                vel += _FORCE_SENSITIVITY * force * self.obstacle_force_coeff

        if self.movement == Movement.Dir:
            if length(vel) > 0:
                vel = normalize(vel)

        # TODO: get max_vel from corresponding Model
        if length(vel) > BOT_VEL_CAP:
            vel = normalize(vel) * BOT_VEL_CAP

        self.virtual_vel_before_check = vel
        if COLLISION_CHECK:
            # check for possible collisions:
            # stop moving forward if an obstacle is nearby
            collision = False
            abs_vel = length(vel)
            if ROTATE_SENSORS:
                ang = self.get_heading_angle()
            else:
                ang = 0.0
            for cur_d, s in zip(self.distances, self.sensors):
                if cur_d == s.max_distance:
                    continue
                r = s.get_ray(self.pos, ang)
                c = cos(signed_angle(vel, r.dir))
                new_d = cur_d - c * abs_vel * self.collision_delta_time
                if new_d < CRITICAL_DIST and new_d < cur_d:
                    collision = True
                    break
            if not collision:
                # separate check for possible collision with another bot
                for inter in bots:
                    # don't count collsions with self
                    if inter.virtual is self:
                        continue
                    new_d = dist(
                        inter.real.pos +
                        self.collision_delta_time * inter.real.vel,
                        self.pos + self.collision_delta_time * vel)
                    new_d -= (self.radius + inter.real.radius)
                    cur_d = dist(inter.real.pos, self.pos)
                    cur_d -= (self.radius + inter.real.radius)
                    if d <= CRITICAL_DIST and new_d < cur_d:
                        collision = True
                        break
            if collision:
                vel = normalize(vel) * CRITICAL_VEL
                self.collision = True
            else:
                self.collision = False

        return vel
Esempio n. 8
0
 def testDist(self):
     self.assertAlmostEqual(dist(Point(0.0, 0.0), Point(0.0, 0.0)), 0.0,
                            geom_places)
     self.assertAlmostEqual(dist(Point(1.0, 2.0), Point(0.0, 3.0)), 2**0.5,
                            geom_places)