Skip to content

Model reference architecture & Cohesion between Rust and Python #12

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
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/output
Cargo.lock
sim-env
sim-env
target
27 changes: 20 additions & 7 deletions sim/scenarios/basic/runconfig.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
# Import simulation infrastructure components
from simfrastructure import RunConfig
from simfrastructure import RunConfig, sim_args

# Import input models
from input import eom, force_effector
from models.force_effector import ForceEffector
from models.eom import EOM
from simfrastructure.python.runconfig import *

# Create models here
force = ForceEffector( 0, 10, 20, ModelBase( 100, 200 ) )
eom = EOM(
x=0,
y=0,
z=0,
force_effectors=ReferenceList( force ),
base=ModelBase( 100, 200 )
)

# Create the actual configuration
config = RunConfig(
model_list=[
eom.model,
force_effector.model,
],
description="A basic system to simulate!"
# Description
"A basic system to simulate!",

# Define models:
ModelGroup( eom, force )
)
8 changes: 4 additions & 4 deletions sim/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ use sim::models::register_models;
fn main() {
let args: Vec<_> = env::args().collect();
println!( "Starting simulation..." );
for arg in args.iter() {
println!( "Argument: {}", arg );
}
// for arg in args.iter() {
// println!( "Argument: {}", arg );
// }

// First, build registry of available model types
let mut model_registry: ModelCreatorMap = HashMap::new();
register_models( &mut model_registry );

// Now generate the runtime with the given list of models
let runtime = Runtime::from_config( &args[ 1 ], &model_registry );
let runtime = Runtime::from_config( &args[ 1 ], &model_registry, &args );

for model in runtime.model_list.iter() {
println!("Model {:?}", model);
Expand Down
10 changes: 0 additions & 10 deletions sim/src/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +0,0 @@
# Load all files in the current directory into this namespace
# from pathlib import Path

# model_directory = Path( __file__ ).parent
# model_files = model_directory.glob("**/*.py")

# # Remove unwanted files
# model_files = [file for file in model_files]

# print(list(model_files))
11 changes: 8 additions & 3 deletions sim/src/models/eom/eom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
an EOM object in the simulation configuration."""

from dataclasses import dataclass
from simfrastructure.python.runconfig import RunModel
from simfrastructure.python.runconfig import Model, ModelBase, ReferenceList

@dataclass
class EOM( RunModel ):
class EOM( Model ):
"""Generates an input class for the EOM model"""

x: int
y: int
z: int
z: int

force_effectors: ReferenceList

base: ModelBase
90 changes: 46 additions & 44 deletions sim/src/models/eom/eom.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,61 @@
use std::any::Any;
use std::borrow::BorrowMut;
use std::cell::{RefCell};
use std::collections::HashMap;
use std::ops::Deref;
use std::rc::Rc;
use pyo3::{FromPyObject, PyAny, PyErr};

use crate::simfrastructure::models::{ModelDetails, SimModelTrait, ModelFromInput};
use crate::simfrastructure::{PyAny, PyErr};
use crate::models::force_effector::ForceEffector;
use crate::simfrastructure::{models::*};
use crate::simfrastructure::{ModelPtr};
use crate::simfrastructure::models::SimModelTrait;

pub fn new( input: &PyAny ) -> Result<ModelPtr, PyErr> {
Ok(
Rc::new(
EOM {
// EOM-specific properties
x: input.getattr( "x" )?.extract()?,
y: input.getattr( "y" )?.extract()?,
z: input.getattr( "z" )?.extract()?,

force_effectors: vec![],

// General Model Properties
model_details: ModelDetails {
name: input.getattr( "name" )?.extract()?,
order: input.getattr( "order" )?.extract()?,
}
}
)
)
}
use crate::simfrastructure::*;

#[derive(std::fmt::Debug)]
#[derive(FromPyObject)]
pub struct EOM {
pub x: i128,
pub y: i128,
pub z: i128,

pub force_effectors: Vec<ModelPtr>,
pub force_effectors: ReferenceList<ForceEffector>,

pub model_details: ModelDetails,
pub base: ModelBase,
}

impl ModelFromInput for EOM {
fn new( input: &PyAny ) -> Result<ModelPtr, PyErr> {
Ok(
Rc::new(
EOM {
// EOM-specific properties
x: input.getattr( "x" )?.extract()?,
y: input.getattr( "y" )?.extract()?,
z: input.getattr( "z" )?.extract()?,

force_effectors: vec![],

// General Model Properties
model_details: ModelDetails {
name: input.getattr( "name" )?.extract()?,
order: input.getattr( "order" )?.extract()?,
}
}
)
)
Ok( Rc::<RefCell<EOM>>::new( RefCell::new( input.extract()? ) ) )
}
}

impl SimModelTrait for EOM {

fn resolve_references( &mut self, global_model_list: &std::collections::HashMap<ModelID, ModelPtr> ) {
// self.force_effectors.populate_refs( global_model_list as &HashMap<ModelID, Rc<RefCell<ForceEffector>>> ).expect(
// "Failed to connect references!"
// );

// let jj = self.force_effectors.reference_list[0].upgrade().borrow_mut();

}

fn initialize( &mut self ) -> bool {
println!( "EOM Model is referencing:" );
for reference in &self.base.local_refs.reference_list {
let upgraded = reference.upgrade().unwrap();
let mut contents = upgraded.deref().borrow_mut();
if let Some( force_model ) = contents.as_any().downcast_mut::<ForceEffector>() {
println!( " - Force ID: {}", force_model.get_details().id );
force_model.get_details().id = 5;
println!( " - Force ID (new): {}", force_model.get_details().id );
}
}
true
}

fn update( &mut self ) -> bool {
true
}
Expand All @@ -68,11 +64,17 @@ impl SimModelTrait for EOM {
true
}

fn get_model( &mut self ) -> &ModelDetails {
&self.model_details
fn get_details( &mut self ) -> &mut ModelBase {
&mut self.base
}

fn as_any(&mut self) -> &mut dyn Any {
self
}
}

impl Model for EOM {}


#[cfg(test)]
mod tests {
Expand Down
2 changes: 1 addition & 1 deletion sim/src/models/eom/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod eom;
pub use eom::{new, EOM};
pub use eom::{EOM};
8 changes: 5 additions & 3 deletions sim/src/models/force_effector/ForceEffector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
a ForceEffector object in the simulation configuration."""

from dataclasses import dataclass
from simfrastructure.python.runconfig import RunModel
from simfrastructure import Model, ModelBase

@dataclass
class ForceEffector( RunModel ):
class ForceEffector( Model ):
"""Generates an input class for the ForceEffector model"""

fx: int
fy: int
fz: int
fz: int

base: ModelBase
94 changes: 59 additions & 35 deletions sim/src/models/force_effector/force_effector.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
use std::any::Any;
use std::cell::RefCell;
use std::rc::Rc;
use pyo3::{FromPyObject, PyAny, PyErr};

use crate::simfrastructure::models::{ModelDetails, SimModelTrait, ModelFromInput};
use crate::simfrastructure::{PyAny, PyErr};
use crate::simfrastructure::models::{ModelBase, SimModelTrait, ModelFromInput};
use crate::simfrastructure::{ModelPtr};

#[derive(std::fmt::Debug)]
#[derive(FromPyObject)]
pub struct ForceEffector {
pub fx: i128,
pub fy: i128,
pub fz: i128,

pub model_details: ModelDetails,
pub base: ModelBase,
}

pub fn new( input: &PyAny ) -> Result<ModelPtr, PyErr> {
Ok(
Rc::new(
ForceEffector {
// EOM-specific properties
fx: input.getattr( "fx" )?.extract()?,
fy: input.getattr( "fy" )?.extract()?,
fz: input.getattr( "fz" )?.extract()?,
// Ok(
// Rc::new(
// ForceEffector {
// // EOM-specific properties
// fx: input.getattr( "fx" )?.extract()?,
// fy: input.getattr( "fy" )?.extract()?,
// fz: input.getattr( "fz" )?.extract()?,

// General Model Properties
model_details: ModelDetails {
name: input.getattr( "name" )?.extract()?,
order: input.getattr( "order" )?.extract()?,
}
}
)
)
// // General Model Properties
// model_details: ModelDetails {
// // name: input.getattr( "name" )?.extract()?,
// order: input.getattr( "order" )?.extract()?,
// }
// }
// )
// )
// let model: ForceEffector = input.extract()?;
// let modelPtr = Rc::new( model );

// let model: ForceEffector = ;

// Ok( Rc::<ForceEffector>::new( input.extract()? ) )
Ok( Rc::<RefCell<ForceEffector>>::new( RefCell::new( input.extract()? ) ) )

// let model: Rc<ForceEffector> = Rc::from(
// input.extract()?
// );
// Ok( modelPtr )
}

impl SimModelTrait for ForceEffector {
fn initialize( &mut self ) -> bool {
true
}

fn update( &mut self ) -> bool {
true
}
Expand All @@ -41,29 +60,34 @@ impl SimModelTrait for ForceEffector {
true
}

fn get_model( &mut self ) -> &ModelDetails {
&self.model_details
fn get_details( &mut self ) -> &mut ModelBase {
&mut self.base
}

fn as_any(&mut self) -> &mut dyn Any {
self
}
}

impl ModelFromInput for ForceEffector {
fn new( input: &PyAny ) -> Result<ModelPtr, PyErr> {
Ok(
Rc::new(
ForceEffector {
// EOM-specific properties
fx: input.getattr( "fx" )?.extract()?,
fy: input.getattr( "fy" )?.extract()?,
fz: input.getattr( "fz" )?.extract()?,
// Ok(
// Rc::new(
// ForceEffector {
// // EOM-specific properties
// fx: input.getattr( "fx" )?.extract()?,
// fy: input.getattr( "fy" )?.extract()?,
// fz: input.getattr( "fz" )?.extract()?,

// General Model Properties
model_details: ModelDetails {
name: input.getattr( "name" )?.extract()?,
order: input.getattr( "order" )?.extract()?,
}
}
)
)
// // General Model Properties
// model_details: ModelDetails {
// // name: input.getattr( "name" )?.extract()?,
// order: input.getattr( "order" )?.extract()?,
// }
// }
// )
// )
Ok( Rc::<RefCell<ForceEffector>>::new( RefCell::new( input.extract()? ) ) )
}
}

Expand Down
2 changes: 1 addition & 1 deletion sim/src/models/force_effector/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub mod force_effector;
pub use force_effector::{new, ForceEffector};
pub use force_effector::ForceEffector;
2 changes: 1 addition & 1 deletion sim/src/simfrastructure/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .python.runconfig import RunConfig
from .python.runconfig import RunConfig, Model, ModelBase, sim_args
from .python.utilities import unit_conversion
Loading