Example #1
0
def scenarios():
    mission = Mission(start=Start((71.65, 63.78), Heading(math.pi * 0.91)),
                      goal=EndlessGoal())
    scenario = Scenario(
        scenario_root="scenarios/loop",
        route="basic.rou.xml",
        missions={"Agent-007": mission},
    )
    return cycle([scenario])
Example #2
0
 def _agent_spec_callback(self, ros_agent_spec: AgentSpec):
     assert (len(ros_agent_spec.tasks) == 1
             ), "more than 1 task per agent is not yet supported"
     task = ros_agent_spec.tasks[0]
     task_params = json.loads(task.params_json) if task.params_json else {}
     task_version = task.task_ver or "latest"
     agent_locator = f"{self._zoo_module}:{task.task_ref}-{task_version}"
     agent_spec = None
     try:
         agent_spec = registry.make(agent_locator, **task_params)
     except ImportError as ie:
         rospy.logerr(
             f"Unable to locate agent with locator={agent_locator}:  {ie}")
     if not agent_spec:
         rospy.logwarn(
             f"got unknown task_ref '{task.task_ref}' in AgentSpec message with params='{task.param_json}'.  ignoring."
         )
         return
     if (ros_agent_spec.end_pose.position.x != 0.0
             or ros_agent_spec.end_pose.position.y != 0.0):
         goal = PositionalGoal(
             (
                 ros_agent_spec.end_pose.position.x,
                 ros_agent_spec.end_pose.position.y,
             ),
             ros_agent_spec.veh_length,
         )
     else:
         goal = EndlessGoal()
     mission = Mission(
         start=Start.from_pose(
             ROSDriver._pose_from_ros(ros_agent_spec.start_pose)),
         goal=goal,
         # TODO:  how to prevent them from spawning on top of another existing vehicle? (see how it's done in SUMO traffic)
         entry_tactic=default_entry_tactic(ros_agent_spec.start_speed),
         vehicle_spec=VehicleSpec(
             veh_id=f"veh_for_agent_{ros_agent_spec.agent_id}",
             veh_config_type=ROSDriver._decode_vehicle_type(
                 ros_agent_spec.veh_type),
             dimensions=Dimensions(
                 ros_agent_spec.veh_length,
                 ros_agent_spec.veh_width,
                 ros_agent_spec.veh_height,
             ),
         ),
     )
     with self._reset_lock:
         if (ros_agent_spec.agent_id in self._agents
                 or ros_agent_spec.agent_id in self._agents_to_add):
             rospy.logwarn(
                 f"trying to add new agent with existing agent_id '{ros_agent_spec.agent_id}'.  ignoring."
             )
             return
         self._agents_to_add[ros_agent_spec.agent_id] = (agent_spec,
                                                         mission)
Example #3
0
def scenario():
    mission = Mission(
        start=Start(np.array([71.65, 63.78]), Heading(math.pi * 0.91)),
        goal=EndlessGoal(),
    )
    scenario = Scenario(
        scenario_root="scenarios/loop",
        route="basic.rou.xml",
        missions={AGENT_ID: mission},
    )
    return scenario
Example #4
0
 def get_vehicle_start_at_time(self, vehicle_id: str,
                               start_time: float) -> Tuple[Start, float]:
     """Returns a Start object that can be used to create a Mission for
     a vehicle from a traffic history dataset starting at its location
     at start_time.  Also returns its speed at that time."""
     pphs = self._traffic_history.vehicle_pose_at_time(
         vehicle_id, start_time)
     assert pphs
     pos_x, pos_y, heading, speed = pphs
     # missions start from front bumper, but pos is center of vehicle
     veh_dims = self._traffic_history.vehicle_dims(vehicle_id)
     hhx, hhy = radians_to_vec(heading) * (0.5 * veh_dims.length)
     return (
         Start(
             (pos_x + hhx, pos_y + hhy),
             Heading(heading),
         ),
         speed,
     )
Example #5
0
    def _prepare_sensors_for_agent_control(self, sim, vehicle_id, agent_id,
                                           agent_interface, bubble):
        plan = Plan(sim.road_map, None, find_route=False)
        vehicle = sim.vehicle_index.start_agent_observation(
            sim,
            vehicle_id,
            agent_id,
            agent_interface,
            plan,
            boid=bubble.is_boid,
        )

        # Setup mission (also used for observations)
        # XXX: this is not quite right.  route may not be what the agent wants to take.
        route = sim.traffic_sim.vehicle_route(vehicle_id=vehicle.id)
        if len(route) > 0:
            goal = PositionalGoal.from_road(route[-1], sim.scenario.road_map)
        else:
            goal = EndlessGoal()
        mission = Mission(start=Start(vehicle.position[:2], vehicle.heading),
                          goal=goal)
        plan.create_route(mission)
Example #6
0
    def _extract_mission(mission, road_map):
        """Takes a sstudio.types.(Mission, EndlessMission, etc.) and converts it to
        the corresponding SMARTS mission types.
        """
        def resolve_offset(offset, lane_length):
            # epsilon to ensure we are within this edge and not the subsequent one
            epsilon = 1e-6
            lane_length -= epsilon
            if offset == "base":
                return epsilon
            elif offset == "max":
                return lane_length
            elif offset == "random":
                return random.uniform(epsilon, lane_length)
            else:
                return float(offset)

        def to_position_and_heading(road_id, lane_index, offset, road_map):
            road = road_map.road_by_id(road_id)
            lane = road.lane_at_index(lane_index)
            offset = resolve_offset(offset, lane.length)
            position = lane.from_lane_coord(RefLinePoint(s=offset))
            lane_vector = lane.vector_at_offset(offset)
            heading = vec_to_radians(lane_vector[:2])
            return position, Heading(heading)

        def to_scenario_via(vias: Tuple[SSVia, ...],
                            road_map: RoadMap) -> Tuple[Via, ...]:
            s_vias = []
            for via in vias:
                road = road_map.road_by_id(via.road_id)
                lane = road.lane_at_index(via.lane_index)
                lane_width = lane.width_at_offset(via.lane_offset)
                hit_distance = (via.hit_distance
                                if via.hit_distance > 0 else lane_width / 2)
                via_position = lane.from_lane_coord(
                    RefLinePoint(via.lane_offset))

                s_vias.append(
                    Via(
                        lane_id=lane.lane_id,
                        lane_index=via.lane_index,
                        road_id=via.road_id,
                        position=tuple(via_position[:2]),
                        hit_distance=hit_distance,
                        required_speed=via.required_speed,
                    ))

            return tuple(s_vias)

        # For now we discard the route and just take the start and end to form our
        # missions.
        if isinstance(mission, sstudio_types.Mission):
            position, heading = to_position_and_heading(
                *mission.route.begin,
                road_map,
            )
            start = Start(position, heading)

            position, _ = to_position_and_heading(
                *mission.route.end,
                road_map,
            )
            goal = PositionalGoal(position, radius=2)

            return Mission(
                start=start,
                route_vias=mission.route.via,
                goal=goal,
                start_time=mission.start_time,
                entry_tactic=mission.entry_tactic,
                via=to_scenario_via(mission.via, road_map),
            )
        elif isinstance(mission, sstudio_types.EndlessMission):
            position, heading = to_position_and_heading(
                *mission.begin,
                road_map,
            )
            start = Start(position, heading)

            return Mission(
                start=start,
                goal=EndlessGoal(),
                start_time=mission.start_time,
                entry_tactic=mission.entry_tactic,
                via=to_scenario_via(mission.via, road_map),
            )
        elif isinstance(mission, sstudio_types.LapMission):
            start_road_id, start_lane, start_road_offset = mission.route.begin
            end_road_id, end_lane, end_road_offset = mission.route.end

            travel_road = road_map.road_by_id(start_road_id)
            if start_road_id == end_road_id:
                travel_road = travel_road.outgoing_roads[0]

            end_road = road_map.road_by_id(end_road_id)
            via_roads = [road_map.road_by_id(r) for r in mission.route.via]

            route = road_map.generate_routes(travel_road, end_road, via_roads,
                                             1)[0]

            start_position, start_heading = to_position_and_heading(
                *mission.route.begin,
                road_map,
            )
            end_position, _ = to_position_and_heading(
                *mission.route.end,
                road_map,
            )

            return LapMission(
                start=Start(start_position, start_heading),
                goal=PositionalGoal(end_position, radius=2),
                route_vias=mission.route.via,
                num_laps=mission.num_laps,
                route_length=route.road_length,
                start_time=mission.start_time,
                entry_tactic=mission.entry_tactic,
                via_points=to_scenario_via(mission.via, road_map),
            )

        raise RuntimeError(
            f"sstudio mission={mission} is an invalid type={type(mission)}")
Example #7
0
    def step(self, sim):
        """Run hijacking and update agent and actor states."""
        captures_by_agent_id = defaultdict(list)

        # Do an optimization to only check if there are pending agents.
        if not sim.agent_manager.pending_agent_ids:
            return

        social_vehicle_ids = [
            v_id for v_id in sim.vehicle_index.social_vehicle_ids()
            if not sim.vehicle_index.vehicle_is_shadowed(v_id)
        ]
        vehicles = {
            v_id: sim.vehicle_index.vehicle_by_id(v_id)
            for v_id in social_vehicle_ids
        }

        def largest_vehicle_plane_dimension(vehicle):
            return max(*vehicle.chassis.dimensions.as_lwh[:2])

        vehicle_comp = [(v.position[:2], largest_vehicle_plane_dimension(v), v)
                        for v in vehicles.values()]

        for agent_id in sim.agent_manager.pending_agent_ids:
            trap = self._traps[agent_id]

            if trap is None:
                continue

            trap.step_trigger(sim.last_dt)

            if not trap.ready:
                continue

            # Order vehicle ids by distance.
            sorted_vehicle_ids = sorted(
                list(social_vehicle_ids),
                key=lambda v: squared_dist(vehicles[v].position[:2], trap.
                                           mission.start.position[:2]),
            )
            for v_id in sorted_vehicle_ids:
                # Skip the capturing process if history traffic is used
                if sim.scenario.traffic_history is not None:
                    break

                if not trap.includes(v_id):
                    continue

                vehicle = vehicles[v_id]
                point = vehicle.pose.point.as_shapely

                if not point.within(trap.geometry):
                    continue

                captures_by_agent_id[agent_id].append((
                    v_id,
                    trap,
                    replace(
                        trap.mission,
                        start=Start(vehicle.position[:2],
                                    vehicle.pose.heading),
                    ),
                ))
                # TODO: Resolve overlap using a tree instead of just removing.
                social_vehicle_ids.remove(v_id)
                break

        # Use fed in trapped vehicles.
        agents_given_vehicle = set()
        used_traps = []
        for agent_id in sim._agent_manager.pending_agent_ids:
            if agent_id not in self._traps:
                continue

            trap = self._traps[agent_id]

            captures = captures_by_agent_id[agent_id]

            if not trap.ready:
                continue

            vehicle = None
            if len(captures) > 0:
                vehicle_id, trap, mission = rand.choice(captures)
                vehicle = sim.switch_control_to_agent(vehicle_id,
                                                      agent_id,
                                                      mission,
                                                      recreate=True,
                                                      is_hijacked=False)
            elif trap.patience_expired:
                # Make sure there is not a vehicle in the same location
                mission = trap.mission
                nv_dims = Vehicle.agent_vehicle_dims(mission)
                new_veh_maxd = max(nv_dims.as_lwh[:2])
                overlapping = False
                for pos, largest_dimension, _ in vehicle_comp:
                    if (squared_dist(pos, mission.start.position[:2]) <=
                        (0.5 * (largest_dimension + new_veh_maxd))**2):
                        overlapping = True
                        break
                if overlapping:
                    continue

                vehicle = TrapManager._make_vehicle(sim, agent_id, mission,
                                                    trap.default_entry_speed)
            else:
                continue
            if vehicle == None:
                continue
            sim.create_vehicle_in_providers(vehicle, agent_id)
            agents_given_vehicle.add(agent_id)
            used_traps.append((agent_id, trap))

        if len(agents_given_vehicle) > 0:
            self.remove_traps(used_traps)
            sim.agent_manager.remove_pending_agent_ids(agents_given_vehicle)