Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions docs/dev/stdlib-worksheets/08-08-movement-actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# §8.8.2–§8.8.4 — movement actions

Source: ASAM OpenSCENARIO DSL 2.2.0, `domain-model` §8.8.2–§8.8.4
(Tables 88–146). Landed in slice 43f. Target chunk: `kDomainMovementActions` in
`frontends/dsl/src/stdlib.cpp`.

Twenty-nine actions in three families, four enums, and the two intermediate
bases the chapter's "Parents" rows name but §8.8.1 does not declare. Every
action is printed as a "Basic information" table (parents, controlled states,
action ending) plus, where it takes arguments, a parameter table. Controlled
states and action ending are runtime semantics with no place in a declaration;
only the parents and the parameters translate.

## The intermediate bases

§8.8.1 declares `osc_action` with exactly two children, `action_for_environment`
and `action_for_movable_object` (both landed in 43d). §8.8.3's and §8.8.4's
"Parents" rows then name `action_for_vehicle` and `action_for_person`, which no
table declares. §8.8.1's prose supplies them: "Actions for actors that are
children of `movable_object`, like `vehicle` or `person`, inherit from
`action_for_movable_object`."

```
action vehicle.action_for_vehicle inherits movable_object.action_for_movable_object
action person.action_for_person inherits movable_object.action_for_movable_object
```

⚠ These two are the only declarations in the chapter not backed by a table of
their own. They are named as parents thirteen and one times respectively, so
leaving them out would make those thirteen actions unparentable.

## §8.8.2 actions for movable object (parent `action_for_movable_object`)

| § | Action | Fields | ⚠ |
| --- | --- | --- | --- |
| .3 | `move` | — | generic; §8.8.3's `drive` and §8.8.4's `walk` are its per-actor counterparts |
| .4 | `assign_position` | `position: position_3d`, `route_point: route_point`, `odr_point: odr_point` | "Use only one of the three"; all three are `Mandatory: no` |
| .5 | `assign_orientation` | `orientation: orientation_3d` | |
| .6 | `assign_speed` | `speed: speed` | |
| .7 | `assign_acceleration` | `acceleration: acceleration` | |
| .8 | `replay_path` | `absolute: path`, `relative: relative_path`, `reference: physical_object`, `transform: relative_transform`, `start_offset: length`, `end_offset: length` | `absolute` and `relative` are both `Mandatory: yes` yet mutually exclusive |
| .9 | `replay_trajectory` | same six, with `trajectory`/`relative_trajectory` | |
| .10 | `remain_stationary` | — | |
| .11 | `change_position` | `target_position: position`, `target_st: route_point`, `target_odr: odr_point`, `target_xyz: position_3d`, `interpolation: path_interpolation`, `on_road_network: bool` | `target_xyz` is marked deprecated in favour of `target_position`; carried, see note 3 |
| .12 | `change_speed` | `target: speed`, `rate_profile: dynamic_profile`, `rate_peak: acceleration` | |
| .13 | `keep_speed` | — | |
| .14 | `change_acceleration` | `target: acceleration`, `rate_profile: dynamic_profile`, `rate_peak: jerk` | |
| .15 | `keep_acceleration` | — | |
| .16 | `follow_path` | as `replay_path` | the target-behaviour counterpart of `replay_path` |
| .17 | `follow_trajectory` | as `replay_trajectory` | |
| .18 | enum `dynamic_profile` | `none, constant, smooth, asap` | `none` also in `hitch_type`, `directionality`, `stop_line_marking` |

## §8.8.3 actions for vehicle (parent `action_for_vehicle`)

| § | Action | Fields |
| --- | --- | --- |
| .1 | `drive` | — |
| .2 | `follow_lane` | `offset: length`, `rate_profile: dynamic_profile`, `rate_peak: speed`, `target: lane` |
| .3 | `change_lane` | `num_of_lanes: uint`, `side: lane_change_side`, `reference: physical_object`, `offset: length`, `rate_profile: dynamic_profile`, `rate_peak: speed`, `target: lane` |
| .4 | `change_time_gap` | `target: time`, `direction: gap_direction`, `reference: physical_object` |
| .5 | `keep_time_gap` | `reference: physical_object`, `direction: road_distance_direction` |
| .6 | `change_space_gap` | `target: length`, `direction: gap_direction`, `reference: physical_object` |
| .7 | `keep_space_gap` | `reference: physical_object`, `direction: road_distance_direction` |
| .8 | `change_time_headway` | `target: time`, `direction: headway_direction`, `reference: physical_object` |
| .9 | `keep_time_headway` | `reference: physical_object` |
| .10 | `change_space_headway` | `target: length`, `direction: headway_direction`, `reference: physical_object` |
| .11 | `keep_space_headway` | `reference: physical_object` |
| .12 | `connect_trailer` | `trailer: trailer` |
| .13 | `disconnect_trailer` | — |
| .14 | enum `lane_change_side` | `left, right, inside, outside, same` |
| .15 | enum `gap_direction` | `ahead, behind, left, right, inside, outside` |
| .16 | enum `headway_direction` | `ahead, behind` |

Note the asymmetry the standard chose deliberately: the `change_*` actions take
a `gap_direction` (six values, longitudinal *and* lateral), while the `keep_*`
actions take a `road_distance_direction` (§8.7.22, just `longitudinal` and
`lateral`). Carried as printed.

## §8.8.4 actions for person (parent `action_for_person`)

| § | Action | Fields |
| --- | --- | --- |
| .1 | `walk` | — |

§8.8.4's prose says a `person` **or an `animal`** walks, but the parent it names
is `action_for_person` and no `action_for_animal` exists. Declared on `person`
as printed; `animal` reaches `move` through `action_for_movable_object`.

## ⚠ Notes carried into the library

1. **Mutually exclusive parameters are still just fields.** `assign_position`
says "use only one of the three"; `replay_path` marks both `absolute` and
`relative` mandatory although only one can be given. The language has no
choice-group construct, and §7.3.11 lets a scenario leave a field
unconstrained, so all of them are plain fields. This is the same rule that
made every table row a field in 43b.
2. **`left`, `right`, `inside` and `outside` now live in four enums**
(`side_left_right`, `lane_change_side`, `gap_direction`, and
`junction_direction` for `left`/`right`). §7.3.3's `lane_change_side!left`
becomes unavoidable in ordinary scenario text. Worth a pinning test, since
§8.9's modifiers add more of the same.
3. **`change_position.target_xyz` is marked deprecated** in favour of
`target_position`, in the same table that declares it. It is declared: the
language has no deprecation marker, and dropping a field the standard prints
would reject a conforming scenario. A diagnostic for it belongs to a
deprecation pass, not to the library.
4. **`change_lane.reference` documents `Default=it.actor`.** A default that
names the invoking actor is not a constant expression, so no default is
declared — the field is left unconstrained, which is what §7.3.11 already
means.
5. **Three names appear as both an action here and a modifier in §8.9**
(`change_speed`, `keep_speed`, `change_lane`). They do not collide: an
action's name is a qualified behavior name (§7.2.2.2.5), so this chapter
declares `movable_object.change_speed` while §8.9 declares a plain
`change_speed`. The 43g slice must keep that distinction.
19 changes: 19 additions & 0 deletions docs/dev/stdlib-worksheets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,25 @@ translated.
| --- | --- | --- |
| [`08-12-02-map.md`](08-12-02-map.md) | §8.12.2 actor `map` | 43e |
| [`08-15-traffic-lights.md`](08-15-traffic-lights.md) | §8.15 traffic lights | 43h |
| [`08-08-movement-actions.md`](08-08-movement-actions.md) | §8.8.2–§8.8.4 movement actions | 43f |

## Reading a chapter without reading all of it

Most §8 chapters spend the majority of their lines on worked examples, which are
illustrative rather than normative and are not what a translation needs. §8.8 is
2190 lines; its normative tables are 725 of them. Dropping the `Examples`
subsections first makes the difference between "too big for one sitting" and
"one sitting":

```sh
sed 's/\\//g' domain-model.md | awk 'NR>=2930 && NR<=5120' \
| awk '/^##### .* Examples/{skip=1} /^#### /{skip=0} !skip'
```

The examples are still worth a look afterwards — §8.15.10's showed which actor
the traffic-light actions hang off, and §8.12.2's showed that `create_route` is
called with fewer arguments than it declares — but they are a second pass, not
the first one.

Chapters translated before the worksheet discipline existed (§8.7, §8.10, §8.11,
§8.12.3–§8.12.41, §8.13, §8.14) have no worksheet; their findings are recorded in
Expand Down
3 changes: 2 additions & 1 deletion docs/roadmap/coverage/osc-dsl-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ included, so a conforming implementation and Scena agree.
| `std` — the `map` actor | §8.12.2 | In | p7-s5 | **Landed** (`dsl_stdlib_test.cpp`): the top-level road-network actor with its six fields, its 18 conversion and creation methods, and its 12 search-space modifiers. *Applying* an actor-associated modifier is issue #100 — the parser keeps the actor prefix in the declared name, so the application site cannot find it; the declarations are well-formed and are pinned. Worksheet: `docs/dev/stdlib-worksheets/08-12-02-map.md` |
| `std` — action hierarchy and the environment | §8.8.1, §8.10, §8.11 | In | p7-s5 | **Landed** (`dsl_stdlib_test.cpp`): `osc_action` with `action_for_environment` and `action_for_movable_object`; the `environment` actor with `local_to_unix_time`; the `weather`/`air`/`precipitation`/`wind`/`fog`/`clouds`/`celestial_light_source` structs; the seven §8.11 environment actions. Their *execution* stays Post (see the actor table) — the DSL environment actions are checked, not run, in v0.0.1 |
| `std` — traffic lights | §8.15 | In | p7-s5 | **Landed** (`dsl_stdlib_test.cpp`): `traffic_light_bulb`, `traffic_light` and `traffic_light_group` with their state methods, `traffic_light_stop_line` (a `route_element`), `traffic_light_phase`/`traffic_light_cycle`, the `traffic_light_controller` actor and its seven §8.15.9 actions, and 5 enums. Their *execution* stays Post (see the actor table). Worksheet: `docs/dev/stdlib-worksheets/08-15-traffic-lights.md` |
| `std` — movement actions and modifiers | §8.3, §8.5, §8.8.2–§8.9 | In | p7-s5 | Lands with the remaining slices of #43 |
| `std` — movement actions | §8.8.2–§8.8.4 | In | p7-s5 | **Landed** (`dsl_stdlib_test.cpp`): 15 actions for `movable_object`, 13 for `vehicle` and `walk` for `person`, plus `dynamic_profile`, `lane_change_side`, `gap_direction` and `headway_direction`. `action_for_vehicle` and `action_for_person` are declared here — §8.8.3/§8.8.4 name them as parents but only §8.8.1's prose defines them. Their *execution* stays Post except where the roadmap's action table says otherwise. Worksheet: `docs/dev/stdlib-worksheets/08-08-movement-actions.md` |
| `std` — movement modifiers | §8.3, §8.5, §8.9 | In | p7-s5 | Lands with the remaining slice of #43 |

Coverage of the individual §8 declarations: all physical types and units
(§8.14.1), compound structs (§8.14.2), string methods (§8.13), all actors
Expand Down
186 changes: 185 additions & 1 deletion frontends/dsl/src/stdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,189 @@ modifier map.set_traffic_lights_control_file:
file: string
)OSC";

// §8.8.2–§8.8.4 the movement actions: fifteen for `movable_object`, thirteen
// for `vehicle` and one for `person`, plus the four enums they use and the two
// intermediate bases §8.8.1 names only in prose. Each action's table gives it a
// parent, its controlled states and how it ends; only the parent and the
// parameters translate, the other two being runtime semantics.
// Translation worksheet: docs/dev/stdlib-worksheets/08-08-movement-actions.md
constexpr std::string_view kDomainMovementActions = R"OSC(
# --- §8.8.2/§8.8.3/§8.8.4 the intermediate action bases ----------------------
# §8.8.1 declares `osc_action` with exactly two children. §8.8.3's and §8.8.4's
# "Parents" rows then name `action_for_vehicle` and `action_for_person`, which
# no table declares; §8.8.1's prose supplies them — "Actions for actors that
# are children of `movable_object`, like `vehicle` or `person`, inherit from
# `action_for_movable_object`".
action vehicle.action_for_vehicle inherits movable_object.action_for_movable_object

action person.action_for_person inherits movable_object.action_for_movable_object

# --- §8.8.2.18 enum dynamic_profile ------------------------------------------
enum dynamic_profile: [none, constant, smooth, asap]

# --- §8.8.2 actions for movable object ---------------------------------------
# The tables give each action a parent, its controlled states and how it ends.
# Only the parent and the parameters translate: the other two are runtime
# semantics with no place in a declaration.
action movable_object.move inherits movable_object.action_for_movable_object

# §8.8.2.4: "Use only one of the three possible arguments" — the language has no
# choice group, and §7.3.11 already lets a scenario leave a field unconstrained.
action movable_object.assign_position inherits movable_object.action_for_movable_object:
position: position_3d
route_point: route_point
odr_point: odr_point

action movable_object.assign_orientation inherits movable_object.action_for_movable_object:
orientation: orientation_3d

action movable_object.assign_speed inherits movable_object.action_for_movable_object:
speed: speed

action movable_object.assign_acceleration inherits movable_object.action_for_movable_object:
acceleration: acceleration

action movable_object.replay_path inherits movable_object.action_for_movable_object:
absolute: path
relative: relative_path
reference: physical_object
transform: relative_transform
start_offset: length
end_offset: length

action movable_object.replay_trajectory inherits movable_object.action_for_movable_object:
absolute: trajectory
relative: relative_trajectory
reference: physical_object
transform: relative_transform
start_offset: length
end_offset: length

action movable_object.remain_stationary inherits movable_object.action_for_movable_object

# `target_xyz` is marked deprecated in the same table that declares it, in
# favour of `target_position`. It is declared anyway: the language has no
# deprecation marker, and dropping a field the standard prints would reject a
# conforming scenario.
action movable_object.change_position inherits movable_object.action_for_movable_object:
target_position: position
target_st: route_point
target_odr: odr_point
target_xyz: position_3d
interpolation: path_interpolation
on_road_network: bool

action movable_object.change_speed inherits movable_object.action_for_movable_object:
target: speed
rate_profile: dynamic_profile
rate_peak: acceleration

action movable_object.keep_speed inherits movable_object.action_for_movable_object

action movable_object.change_acceleration inherits movable_object.action_for_movable_object:
target: acceleration
rate_profile: dynamic_profile
rate_peak: jerk

action movable_object.keep_acceleration inherits movable_object.action_for_movable_object

# §8.8.2.16/§8.8.2.17 are the target-behaviour counterparts of replay_path and
# replay_trajectory (§8.8.2.1 vs §8.8.2.2): same parameters, different promise
# about the actor's dynamic limits.
action movable_object.follow_path inherits movable_object.action_for_movable_object:
absolute: path
relative: relative_path
reference: physical_object
transform: relative_transform
start_offset: length
end_offset: length

action movable_object.follow_trajectory inherits movable_object.action_for_movable_object:
absolute: trajectory
relative: relative_trajectory
reference: physical_object
transform: relative_transform
start_offset: length
end_offset: length

# --- §8.8.3.14 enum lane_change_side -----------------------------------------
enum lane_change_side: [left, right, inside, outside, same]

# --- §8.8.3.15 enum gap_direction --------------------------------------------
enum gap_direction: [ahead, behind, left, right, inside, outside]

# --- §8.8.3.16 enum headway_direction ----------------------------------------
enum headway_direction: [ahead, behind]

# --- §8.8.3 actions for vehicle ----------------------------------------------
action vehicle.drive inherits vehicle.action_for_vehicle

action vehicle.follow_lane inherits vehicle.action_for_vehicle:
offset: length
rate_profile: dynamic_profile
rate_peak: speed
target: lane

# `reference` documents `Default=it.actor`; a default naming the invoking actor
# is not a constant expression, so the field is simply left unconstrained.
action vehicle.change_lane inherits vehicle.action_for_vehicle:
num_of_lanes: uint
side: lane_change_side
reference: physical_object
offset: length
rate_profile: dynamic_profile
rate_peak: speed
target: lane

# The change_/keep_ pairs below are deliberately asymmetric: a `change_*` takes
# a `gap_direction` (six values, longitudinal and lateral), a `keep_*` takes a
# `road_distance_direction` (§8.7.22, just longitudinal and lateral).
action vehicle.change_time_gap inherits vehicle.action_for_vehicle:
target: time
direction: gap_direction
reference: physical_object

action vehicle.keep_time_gap inherits vehicle.action_for_vehicle:
reference: physical_object
direction: road_distance_direction

action vehicle.change_space_gap inherits vehicle.action_for_vehicle:
target: length
direction: gap_direction
reference: physical_object

action vehicle.keep_space_gap inherits vehicle.action_for_vehicle:
reference: physical_object
direction: road_distance_direction

action vehicle.change_time_headway inherits vehicle.action_for_vehicle:
target: time
direction: headway_direction
reference: physical_object

action vehicle.keep_time_headway inherits vehicle.action_for_vehicle:
reference: physical_object

action vehicle.change_space_headway inherits vehicle.action_for_vehicle:
target: length
direction: headway_direction
reference: physical_object

action vehicle.keep_space_headway inherits vehicle.action_for_vehicle:
reference: physical_object

action vehicle.connect_trailer inherits vehicle.action_for_vehicle:
trailer: trailer

action vehicle.disconnect_trailer inherits vehicle.action_for_vehicle

# --- §8.8.4 actions for person -----------------------------------------------
# §8.8.4's prose says a person OR an animal walks, but the parent it names is
# `action_for_person` and no `action_for_animal` exists. Declared on `person` as
# printed; an animal reaches `move` through `action_for_movable_object`.
action person.walk inherits person.action_for_person
)OSC";

const std::string& types_module() {
static const std::string source = std::string(kTypesScalars) + std::string(kTypesCompound);
return source;
Expand All @@ -973,7 +1156,8 @@ const std::string& types_module() {
const std::string& domain_module() {
static const std::string source = std::string(kDomainEntities) + std::string(kDomainRoads) +
std::string(kDomainEnvironment) +
std::string(kDomainTrafficLights) + std::string(kDomainMap);
std::string(kDomainTrafficLights) + std::string(kDomainMap) +
std::string(kDomainMovementActions);
return source;
}

Expand Down
Loading
Loading