def find_optimal_candidates(candidates, velocity_obstacles): optimal_satisfied = -1 optimal_candidates = [] for d, candidate in candidates: valid = True i = 0 for vo in velocity_obstacles: if i != candidate.vo1 and i != candidate.vo2 and \ det(vo.left, candidate.position - vo.apex) < 0 < \ det(vo.right, candidate.position - vo.apex): valid = False if i > optimal_satisfied: optimal_satisfied = i optimal_candidates = [(d, candidate)] elif i == optimal_satisfied: optimal_candidates.append((d, candidate)) i += 1 break i += 1 if valid: if i > optimal_satisfied: optimal_satisfied = i optimal_candidates = [(d, candidate)] elif i == optimal_satisfied: optimal_candidates.append((d, candidate)) return optimal_candidates
def compute_hrvos(self, position, velocity, neighbours): velocity_obstacles = [] neighbours.sort( key=lambda o: np.linalg.norm(o.get_position() - position)) # Velocity obstacles from neighbours are added in order of increasing # distance so that more distant ones will be discarded first when we # cannot satisfy them all for neighbour in neighbours: neighbour_position = neighbour.get_position() neighbour_velocity = neighbour.get_velocity() offset = neighbour_position - position distance = np.linalg.norm(offset) if distance > self.neighbour_range: continue if distance > 2 * self.radius: # Robots have not collided angle = np.arctan2(offset[1], offset[0]) opening_angle = np.arcsin(2 * self.radius / distance) left = np.array([ np.cos(angle + opening_angle), np.sin(angle + opening_angle) ]) right = np.array([ np.cos(angle - opening_angle), np.sin(angle - opening_angle) ]) d = 2 * np.sin(opening_angle) * np.cos(opening_angle) if det(offset, velocity - neighbour_velocity) > 0: # vA on left of centre line s = 0.5 * det(velocity - neighbour_velocity, left) / d apex = np.array(neighbour_velocity + s * right - ( self.noise * abs(offset) / ( 2 * self.radius)) * offset / distance) else: # va on right of centre line s = 0.5 * det(velocity - neighbour_velocity, right) / d apex = np.array(neighbour_velocity + s * left - ( self.noise * abs(offset) / ( 2 * self.radius)) * offset / distance) else: # Robots have collided apex = np.array(0.5 * (neighbour_velocity + velocity) - ( self.noise + 0.5 * (2 * self.radius - abs( offset) / self.dt)) * offset / distance) right = normal(position, neighbour_position) left = -right velocity_obstacles.append(VelocityObstacle(apex, left, right)) return velocity_obstacles
def compute_max_candidates(self, velocity_obstacles, preferred_velocity): candidates = [] for j, vo in enumerate(velocity_obstacles): discriminant = self.max_speed ** 2 - det(vo.apex, vo.right) ** 2 if discriminant > 0: t1 = -(np.dot(vo.apex, vo.right)) + np.sqrt(discriminant) t2 = -(np.dot(vo.apex, vo.right)) - np.sqrt(discriminant) if t1 >= 0: pos = vo.apex + t1 * vo.right candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, -1, j))) if t2 >= 0: pos = vo.apex + t2 * vo.right candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, -1, j))) discriminant = self.max_speed ** 2 - det(vo.apex, vo.left) ** 2 if discriminant > 0: t1 = -(np.dot(vo.apex, vo.left)) + np.sqrt(discriminant) t2 = -(np.dot(vo.apex, vo.left)) - np.sqrt(discriminant) if t1 >= 0: pos = vo.apex + t1 * vo.left candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, -1, j))) if t2 >= 0: pos = vo.apex + t2 * vo.left candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, -1, j))) return candidates
def compute_projection_candidates(self, velocity_obstacles, preferred_velocity): candidates = [] for i, vo in enumerate(velocity_obstacles): dot_prod = np.dot(preferred_velocity - vo.apex, vo.left) if dot_prod > 0 > det(vo.left, preferred_velocity - vo.apex): pos = vo.apex + dot_prod * vo.left if np.linalg.norm(pos) < self.max_speed: candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, i, i))) return candidates
def compute_intersect_candidates(self, velocity_obstacles, preferred_velocity): candidates = [] for i in range(len(velocity_obstacles)): for j in range(i + 1, len(velocity_obstacles)): vo1 = velocity_obstacles[i] vo2 = velocity_obstacles[j] d = det(vo1.right, vo2.right) if d != 0: s = det(vo2.apex - vo1.apex, vo2.right) / d t = det(vo2.apex - vo1.apex, vo1.right) / d if s >= 0 and t >= 0: pos = vo1.apex + s * vo1.right if np.linalg.norm(pos) < self.max_speed: candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, i, j))) d = det(vo1.left, vo2.right) if d != 0: s = det(vo2.apex - vo1.apex, vo2.right) / d t = det(vo2.apex - vo1.apex, vo1.left) / d if s >= 0 and t >= 0: pos = vo1.apex + s * vo1.left if np.linalg.norm(pos) < self.max_speed: candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, i, j))) d = det(vo1.right, vo2.left) if d != 0: s = det(vo2.apex - vo1.apex, vo2.left) / d t = det(vo2.apex - vo1.apex, vo1.right) / d if s >= 0 and t >= 0: pos = vo1.apex + s * vo1.right if np.linalg.norm(pos) < self.max_speed: candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, i, j))) d = det(vo1.left, vo2.left) if d != 0: s = det(vo2.apex - vo1.apex, vo2.left) / d t = det(vo2.apex - vo1.apex, vo1.left) / d if s >= 0 and t >= 0: pos = vo1.apex + s * vo1.left if np.linalg.norm(pos) < self.max_speed: candidates.append(( np.linalg.norm(preferred_velocity - pos), Candidate(pos, i, j))) return candidates