-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #113 from NREL/rjr/headings-module
a prototype of creating AccessModels
- Loading branch information
Showing
47 changed files
with
705 additions
and
326 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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 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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use super::access_model_error::AccessModelError; | ||
use crate::model::{ | ||
property::{edge::Edge, vertex::Vertex}, | ||
state::{state_feature::StateFeature, state_model::StateModel}, | ||
traversal::state::state_variable::StateVar, | ||
}; | ||
|
||
pub trait AccessModel: Send + Sync { | ||
/// lists the state variables expected by this access model that are not | ||
/// defined on the base configuration. for example, if this access model | ||
/// has state variables that differ based on the query, they can be injected | ||
/// into the state model by listing them here. | ||
fn state_features(&self) -> Vec<(String, StateFeature)>; | ||
|
||
/// Updates the traversal state by accessing some destination edge | ||
/// when coming from some previous edge. | ||
/// | ||
/// The traversal argument represents a set of vertices and | ||
/// edges connected in the network: | ||
/// `(v1) -[prev]-> (v2) -[next]-> (v3)` | ||
/// Where `next` is the edge we want to access. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `traversal` - the vertex/edge traversal | ||
/// * `state` - state of the search at the beginning of the dst edge | ||
/// * `state_variable_indices` - the names and indices of state variables | ||
/// | ||
/// # Returns | ||
/// | ||
/// Either an optional access result or an error. if there are no | ||
/// state updates due to access, None is returned. | ||
fn access_edge( | ||
&self, | ||
traversal: (&Vertex, &Edge, &Vertex, &Edge, &Vertex), | ||
state: &mut Vec<StateVar>, | ||
state_model: &StateModel, | ||
) -> Result<(), AccessModelError>; | ||
} |
23 changes: 23 additions & 0 deletions
23
rust/routee-compass-core/src/model/access/access_model_builder.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use super::{access_model_error::AccessModelError, access_model_service::AccessModelService}; | ||
use std::sync::Arc; | ||
|
||
/// A [`AccessModelBuilder`] takes a JSON object describing the configuration of a | ||
/// traversal model and builds a [`AccessModelService`]. | ||
/// | ||
/// A [`AccessModelBuilder`] instance should be an empty struct that implements | ||
/// this trait. | ||
pub trait AccessModelBuilder { | ||
/// Builds a [`AccessModelService`] from configuration. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `parameters` - the contents of the "traversal" TOML config section | ||
/// | ||
/// # Returns | ||
/// | ||
/// A [`AccessModelService`] designed to persist the duration of the CompassApp. | ||
fn build( | ||
&self, | ||
parameters: &serde_json::Value, | ||
) -> Result<Arc<dyn AccessModelService>, AccessModelError>; | ||
} |
13 changes: 13 additions & 0 deletions
13
rust/routee-compass-core/src/model/access/access_model_error.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use crate::model::state::state_error::StateError; | ||
|
||
#[derive(thiserror::Error, Debug)] | ||
pub enum AccessModelError { | ||
#[error("error while executing access model {name}: {error}")] | ||
RuntimeError { name: String, error: String }, | ||
#[error(transparent)] | ||
StateError(#[from] StateError), | ||
#[error(transparent)] | ||
SerdeJsonError(#[from] serde_json::Error), | ||
#[error("{0}")] | ||
BuildError(String), | ||
} |
21 changes: 21 additions & 0 deletions
21
rust/routee-compass-core/src/model/access/access_model_service.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,21 @@ | ||
use super::{access_model::AccessModel, access_model_error::AccessModelError}; | ||
use std::sync::Arc; | ||
|
||
pub trait AccessModelService: Send + Sync { | ||
/// Builds a [AccessModel] for the incoming query, used as parameters for this | ||
/// build operation. | ||
/// | ||
/// The query is passed as parameters to this operation so that any query-time | ||
/// coefficients may be applied to the [AccessModel]. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `query` - the incoming query which may contain parameters for building the [AccessModel] | ||
/// | ||
/// # Returns | ||
/// | ||
/// The [AccessModel] instance for this query, or an error | ||
/// | ||
/// [AccessModel]: compass_core::model::access::access_model::AccessModel | ||
fn build(&self, query: &serde_json::Value) -> Result<Arc<dyn AccessModel>, AccessModelError>; | ||
} |
File renamed without changes.
51 changes: 51 additions & 0 deletions
51
rust/routee-compass-core/src/model/access/default/combined_model.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use crate::model::{ | ||
access::{ | ||
access_model::AccessModel, access_model_error::AccessModelError, | ||
access_model_service::AccessModelService, | ||
}, | ||
property::{edge::Edge, vertex::Vertex}, | ||
state::{state_feature::StateFeature, state_model::StateModel}, | ||
traversal::state::state_variable::StateVar, | ||
}; | ||
use itertools::Itertools; | ||
use std::sync::Arc; | ||
|
||
pub struct CombinedAccessModelService { | ||
pub services: Vec<Arc<dyn AccessModelService>>, | ||
} | ||
|
||
pub struct CombinedAccessModel { | ||
pub models: Vec<Arc<dyn AccessModel>>, | ||
} | ||
|
||
impl AccessModelService for CombinedAccessModelService { | ||
fn build(&self, query: &serde_json::Value) -> Result<Arc<dyn AccessModel>, AccessModelError> { | ||
let models = self | ||
.services | ||
.iter() | ||
.map(|m| m.build(query)) | ||
.collect::<Result<_, _>>()?; | ||
Ok(Arc::new(CombinedAccessModel { models })) | ||
} | ||
} | ||
|
||
impl AccessModel for CombinedAccessModel { | ||
fn state_features(&self) -> Vec<(String, StateFeature)> { | ||
self.models | ||
.iter() | ||
.flat_map(|m| m.state_features()) | ||
.collect_vec() | ||
} | ||
|
||
fn access_edge( | ||
&self, | ||
traversal: (&Vertex, &Edge, &Vertex, &Edge, &Vertex), | ||
state: &mut Vec<StateVar>, | ||
state_model: &StateModel, | ||
) -> Result<(), AccessModelError> { | ||
for model in self.models.iter() { | ||
model.access_edge(traversal, state, state_model)?; | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub mod combined_model; | ||
pub mod no_access_model; | ||
pub mod turn_delays; |
56 changes: 56 additions & 0 deletions
56
rust/routee-compass-core/src/model/access/default/no_access_model.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use std::sync::Arc; | ||
|
||
use crate::model::access::{ | ||
access_model::AccessModel, access_model_builder::AccessModelBuilder, | ||
access_model_service::AccessModelService, | ||
}; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct NoAccessModel {} | ||
|
||
impl AccessModel for NoAccessModel { | ||
fn state_features(&self) -> Vec<(String, crate::model::state::state_feature::StateFeature)> { | ||
vec![] | ||
} | ||
|
||
fn access_edge( | ||
&self, | ||
_traversal: ( | ||
&crate::model::property::vertex::Vertex, | ||
&crate::model::property::edge::Edge, | ||
&crate::model::property::vertex::Vertex, | ||
&crate::model::property::edge::Edge, | ||
&crate::model::property::vertex::Vertex, | ||
), | ||
_state: &mut Vec<crate::model::traversal::state::state_variable::StateVar>, | ||
_state_model: &crate::model::state::state_model::StateModel, | ||
) -> Result<(), crate::model::access::access_model_error::AccessModelError> { | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl AccessModelService for NoAccessModel { | ||
fn build( | ||
&self, | ||
_query: &serde_json::Value, | ||
) -> Result< | ||
std::sync::Arc<dyn AccessModel>, | ||
crate::model::access::access_model_error::AccessModelError, | ||
> { | ||
let model: Arc<dyn AccessModel> = Arc::new(self.clone()); | ||
Ok(model) | ||
} | ||
} | ||
|
||
impl AccessModelBuilder for NoAccessModel { | ||
fn build( | ||
&self, | ||
_parameters: &serde_json::Value, | ||
) -> Result< | ||
Arc<dyn AccessModelService>, | ||
crate::model::access::access_model_error::AccessModelError, | ||
> { | ||
let service: Arc<dyn AccessModelService> = Arc::new(self.clone()); | ||
Ok(service) | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
rust/routee-compass-core/src/model/access/default/turn_delays/edge_heading.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use serde::Deserialize; | ||
|
||
/// simplifies the representation of directionality for a linestring | ||
/// to just the headings of the start and end points, using cardinal angles [0, 360). | ||
/// if the start and end have the same heading, the edge heading is None. | ||
#[derive(Copy, Clone, Deserialize)] | ||
pub struct EdgeHeading { | ||
arrival_heading: i16, | ||
departure_heading: Option<i16>, | ||
} | ||
|
||
impl EdgeHeading { | ||
/// creates an EdgeHeading from a start and end heading | ||
pub fn new(arrival_heading: i16, departure_heading: i16) -> Self { | ||
Self { | ||
arrival_heading, | ||
departure_heading: Some(departure_heading), | ||
} | ||
} | ||
|
||
/// retrieve the start | ||
pub fn start_heading(&self) -> i16 { | ||
self.arrival_heading | ||
} | ||
|
||
/// If the end heading is not specified, it is assumed to be the same as the start heading | ||
pub fn end_heading(&self) -> i16 { | ||
match self.departure_heading { | ||
Some(end_heading) => end_heading, | ||
None => self.arrival_heading, | ||
} | ||
} | ||
/// Compute the angle between this edge and some destination edge. | ||
pub fn bearing_to_destination(&self, destination: &EdgeHeading) -> i16 { | ||
let angle = destination.start_heading() - self.end_heading(); | ||
if angle > 180 { | ||
angle - 360 | ||
} else if angle < -180 { | ||
angle + 360 | ||
} else { | ||
angle | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_simple() { | ||
let edge_heading = EdgeHeading::new(45, 90); | ||
let next_edge_heading = EdgeHeading::new(90, 135); | ||
assert_eq!(edge_heading.bearing_to_destination(&next_edge_heading), 0); | ||
} | ||
|
||
#[test] | ||
fn test_wrap_360() { | ||
let edge_heading = EdgeHeading::new(10, 10); | ||
let next_edge_heading = EdgeHeading::new(350, 350); | ||
assert_eq!(edge_heading.bearing_to_destination(&next_edge_heading), -20); | ||
|
||
let edge_heading = EdgeHeading::new(350, 350); | ||
let next_edge_heading = EdgeHeading::new(10, 10); | ||
assert_eq!(edge_heading.bearing_to_destination(&next_edge_heading), 20); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
rust/routee-compass-core/src/model/access/default/turn_delays/mod.rs
This file contains 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 |
---|---|---|
@@ -0,0 +1,6 @@ | ||
pub mod edge_heading; | ||
pub mod turn; | ||
pub mod turn_delay_access_model; | ||
pub mod turn_delay_access_model_engine; | ||
pub mod turn_delay_access_model_service; | ||
pub mod turn_delay_model; |
Oops, something went wrong.