Skip to content
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

Model reference architecture & Cohesion between Rust and Python #12

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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
@@ -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);
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
@@ -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
}
@@ -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 {
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
@@ -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
}
@@ -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()? ) ) )
}
}

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