-
Notifications
You must be signed in to change notification settings - Fork 149
OpenScenarioXML Export #421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Eric-Vin
wants to merge
21
commits into
main
Choose a base branch
from
OpenScenarioXML
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
1cd2aa6
Work on OpenScenarioXML Export.
Eric-Vin 8c056c2
Initial OpenScenarioXML export implementation.
Eric-Vin 048d3f0
Tidying up
Eric-Vin 6ff049a
Fixed coordinate system
Eric-Vin 0b45e3d
Updated dependencies and fixed wheelbase offset
Eric-Vin 8ecd602
Added pedestrians to OpenScenarioXML export
Eric-Vin 8685fac
Merge branch 'main' into OpenScenarioXML
Eric-Vin 5e2b7e3
XOSC export improvements, fixes, and test.
Eric-Vin 743cf43
Fixed metadrive import?
Eric-Vin 992be25
Tweaked Metadrive real_time default.
Eric-Vin 15c729a
Added documentation
Eric-Vin ab311ca
Minor fixes.
Eric-Vin 54a2a5e
Fixed blank line
Eric-Vin 25fe1a1
Another blank line?
Eric-Vin 518c308
Fix scenariogeneration link
Eric-Vin 96b3ee1
Fixed link
Eric-Vin 70d6b32
PR revisions
Eric-Vin c8df0b1
Fix heading -> yaw
Eric-Vin 050a706
PR fixes and mode2D fix for modular scenarios.
Eric-Vin 1b8851f
Minor changes.
Eric-Vin 05159d2
Attempted moving cache purge.
Eric-Vin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,12 +8,15 @@ | |
| import hashlib | ||
| import io | ||
| import math | ||
| import os | ||
| import pickle | ||
| import struct | ||
| import types | ||
| import warnings | ||
|
|
||
| from scenic.core.distributions import Samplable, needsSampling | ||
| from scenic.core.utils import DefaultIdentityDict | ||
| from scenic.core.vectors import Vector | ||
|
|
||
|
|
||
| def deterministicHash(mapping, *, digest_size=8): | ||
|
|
@@ -392,3 +395,224 @@ def readStr(stream): | |
|
|
||
|
|
||
| Serializer.addCodec(str, writeStr, readStr) | ||
|
|
||
|
|
||
| def toOpenScenario( | ||
| simulationResult, | ||
| scenario, | ||
| scene, | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| mapPath=None, | ||
| scenarioName="ScenicScenario", | ||
| ): | ||
| """Export a `SimulationResult` as a `scenariogeneration.xosc.scenario <https://pyoscx.github.io/scenariogeneration/xosc/scenario.html>`_ object. | ||
|
|
||
| Args: | ||
| simulationResult: The `SimulationResult` to be exported to XOSC | ||
| scenario: The scenario from which simulationResult was sampled. | ||
| scene: The scene from which simulationResult was sampled. | ||
| mapPath: The path to the XODR map used to run the simulation. If | ||
| one is not provided the `map` param of the scenario is used. | ||
| scenarioName: The name of the scenario in the generated XOSC file. | ||
| """ | ||
| try: | ||
| import scenariogeneration | ||
| from scenariogeneration import ScenarioGenerator, xosc | ||
| except ModuleNotFoundError as e: | ||
| raise ModuleNotFoundError( | ||
| "The `scenariogeneration` package is required to use Scenic's XOSC export functionality." | ||
| ) from e | ||
|
|
||
| # Create catalog | ||
| xosc_catalog = xosc.Catalog() | ||
|
|
||
| # Create parameters | ||
| xosc_paramdec = xosc.ParameterDeclarations() | ||
|
|
||
| # Extract map | ||
| if mapPath is None: | ||
| if "map" not in scenario.params: | ||
| raise ValueError( | ||
| "No `mapPath` provided and scenario does not have a `map` parameter defined." | ||
| ) | ||
| mapPath = ( | ||
| mapPath if mapPath is not None else os.path.abspath(scenario.params["map"]) | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| ) | ||
| xosc_road = xosc.RoadNetwork(roadfile=mapPath) | ||
|
|
||
| # Create entitities | ||
| entities = xosc.Entities() | ||
| xosc_objects = {} | ||
| for obj_i, obj in enumerate(scene.objects): | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| if hasattr(obj, "isVehicle") and obj.isVehicle: | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| obj_name = obj.name if hasattr(obj, "name") else f"Vehicle{obj_i}" | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| veh_bb = xosc.BoundingBox( | ||
| obj.width, | ||
| obj.length, | ||
| obj.height, | ||
| 0, | ||
| 0, | ||
| 0, | ||
| ) | ||
| veh_fa = xosc.Axle( | ||
| obj.maxSteeringAngle, | ||
| obj.wheelDiameter, | ||
| obj.trackWidth, | ||
| obj.wheelbase, | ||
| obj.groundClearance, | ||
| ) | ||
| veh_ra = xosc.Axle( | ||
| obj.maxSteeringAngle, | ||
| obj.wheelDiameter, | ||
| obj.trackWidth, | ||
| 0, | ||
| obj.groundClearance, | ||
| ) | ||
| xosc_obj = xosc.Vehicle( | ||
| name=obj_name, | ||
| vehicle_type=xosc.VehicleCategory.car, | ||
| boundingbox=veh_bb, | ||
| frontaxle=veh_fa, | ||
| rearaxle=veh_ra, | ||
| max_speed=obj.maxSpeed, | ||
| max_acceleration=obj.maxAcceleration, | ||
| max_deceleration=obj.maxDeceleration, | ||
| mass=None, | ||
| model3d=None, | ||
| max_acceleration_rate=None, | ||
| max_deceleration_rate=None, | ||
| role=None, | ||
| ) | ||
| elif hasattr(obj, "isPedestrian") and obj.isPedestrian: | ||
| obj_name = obj.name if hasattr(obj, "name") else f"Pedestrian{obj_i}" | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| ped_bb = xosc.BoundingBox( | ||
| obj.width, | ||
| obj.length, | ||
| obj.height, | ||
| 0, | ||
| 0, | ||
| 0, | ||
| ) | ||
| xosc_obj = xosc.Pedestrian( | ||
| name=obj_name, | ||
| mass=obj.mass, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Surprisingly, yes:
And this appears supported by the spec. No idea why though. |
||
| boundingbox=ped_bb, | ||
| category=xosc.PedestrianCategory.pedestrian, | ||
| model=None, | ||
| role=None, | ||
| ) | ||
| else: | ||
| warnings.warn( | ||
| f"Object {obj} of unsupported type is being ignored during XOSC export." | ||
| ) | ||
| continue | ||
|
|
||
| xosc_objects[obj] = xosc_obj | ||
| entities.add_scenario_object(obj_name, xosc_obj) | ||
|
|
||
| # Helper function | ||
| def pos_to_WorldPosition(obj, pos, yaw): | ||
| # XOSC Reference point is back axle, so we must translate Scenic's | ||
| # convention to this. | ||
| state_position = ( | ||
| pos.offsetRotated(yaw, Vector(0, -0.5 * obj.wheelbase, 0)) | ||
| if obj.isVehicle | ||
| else pos | ||
| ) | ||
| state_orientation = yaw + math.radians(90) | ||
| return xosc.WorldPosition( | ||
| x=state_position.x, | ||
| y=state_position.y, | ||
| z=state_position.z, | ||
| h=state_orientation, | ||
| ) | ||
|
|
||
| # Initial states | ||
| init = xosc.Init() | ||
|
|
||
| for obj, xosc_obj in xosc_objects.items(): | ||
| obj_init_action = xosc.TeleportAction( | ||
| pos_to_WorldPosition(obj, obj.position, obj.yaw) | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| ) | ||
| init.add_init_action(xosc_obj.name, obj_init_action) | ||
|
|
||
| # Dynamics | ||
| xosc_act = xosc.Act( | ||
| "MainAct", | ||
| xosc.ValueTrigger( | ||
| "StartSimulation", | ||
| 0, | ||
| xosc.ConditionEdge.none, | ||
| xosc.SimulationTimeCondition(0, xosc.Rule.greaterThan), | ||
| ), | ||
| ) | ||
|
|
||
| for obj_i, (obj, xosc_obj) in enumerate(xosc_objects.items()): | ||
| action_times = [] | ||
| action_positions = [] | ||
| for t, states in enumerate(simulationResult.trajectory): | ||
| action_positions.append( | ||
| pos_to_WorldPosition( | ||
| obj, states.positions[obj_i], states.orientations[obj_i].yaw | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
| ) | ||
| ) | ||
| action_times.append(simulationResult.timestep * t) | ||
|
Eric-Vin marked this conversation as resolved.
Outdated
|
||
|
|
||
| polyline = xosc.Polyline(time=action_times, positions=action_positions) | ||
| trajectory = xosc.Trajectory(name=f"Trajectory_{xosc_obj.name}", closed=False) | ||
| trajectory.add_shape(polyline) | ||
|
|
||
| traj_action = xosc.FollowTrajectoryAction( | ||
| trajectory=trajectory, | ||
| following_mode=xosc.FollowingMode.position, | ||
| reference_domain=xosc.ReferenceContext.absolute, | ||
| scale=1, | ||
| offset=0, | ||
| ) | ||
|
|
||
| event = xosc.Event(f"Event_{xosc_obj.name}", xosc.Priority.override) | ||
| event.add_trigger( | ||
| xosc.ValueTrigger( | ||
| f"TimeTrigger_{xosc_obj.name}", | ||
| 0, | ||
| xosc.ConditionEdge.none, | ||
| xosc.SimulationTimeCondition(0, xosc.Rule.greaterThan), | ||
| ) | ||
| ) | ||
| event.add_action(f"Action_{xosc_obj.name}", action=traj_action) | ||
|
|
||
| maneuver = xosc.Maneuver("Maneuver_{xosc_obj.name}") | ||
| maneuver.add_event(event) | ||
|
|
||
| manuever_group = xosc.ManeuverGroup(f"ManeuverGroup_{xosc_obj.name}") | ||
| manuever_group.add_maneuver(maneuver) | ||
| manuever_group.add_actor(xosc_obj.name) | ||
|
|
||
| xosc_act.add_maneuver_group(manuever_group) | ||
|
|
||
| # Create storyboard | ||
| xosc_sb = xosc.StoryBoard( | ||
| init, | ||
| xosc.ValueTrigger( | ||
| "StopSimulation", | ||
| 0, | ||
| xosc.ConditionEdge.rising, | ||
| xosc.SimulationTimeCondition( | ||
| simulationResult.currentRealTime, xosc.Rule.greaterThan | ||
| ), | ||
| "stop", | ||
| ), | ||
| ) | ||
| xosc_sb.add_act(xosc_act) | ||
|
|
||
| # Create scenario | ||
| xosc_scenario = xosc.Scenario( | ||
| scenarioName, | ||
| "Scenic", | ||
| xosc_paramdec, | ||
| entities=entities, | ||
| storyboard=xosc_sb, | ||
| roadnetwork=xosc_road, | ||
| catalog=xosc_catalog, | ||
| ) | ||
|
|
||
| return xosc_scenario | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.