diff --git a/.github/workflows/cargo-deny.yml b/.github/workflows/cargo-deny.yml index fed9c81..42d6d1e 100644 --- a/.github/workflows/cargo-deny.yml +++ b/.github/workflows/cargo-deny.yml @@ -1,7 +1,7 @@ -name: Cargo Dependencies +name: Safe Stage - Check Dependencies on: pull_request: - branches: [$default-branch] + branches: [ main ] paths: - "**/Cargo.lock" - "**/Cargo.toml" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 529f428..54e9995 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Build and Release Service Application +name: Build and Release on: push: tags: @@ -23,10 +23,10 @@ jobs: - name: Build Safe Stage run: | cargo run -p bindings - cargo build --release -F ffi + cargo build --release --features ffi working-directory: ./safe-stage - - name: Publish Service Application + - name: Build Service App run: | dotnet publish working-directory: ./service-app diff --git a/.github/workflows/safe-stage-miri.yml b/.github/workflows/safe-stage-miri.yml index d2f53d9..fd85fd3 100644 --- a/.github/workflows/safe-stage-miri.yml +++ b/.github/workflows/safe-stage-miri.yml @@ -1,13 +1,13 @@ -name: Check Safe Stage Safety +name: Safe Stage - Check Safety on: push: - branches: [$default-branch] + branches: [ main ] paths: - - "safe-stage/src/*" + - "safe-stage/src/**" pull_request: - branches: [$default-branch] + branches: [ main ] paths: - - "safe-stage/src/*" + - "safe-stage/src/**" env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/safe-stage.yml b/.github/workflows/safe-stage.yml index 2cb84ab..97d0cac 100644 --- a/.github/workflows/safe-stage.yml +++ b/.github/workflows/safe-stage.yml @@ -1,48 +1,20 @@ -name: Check Safe Stage +name: Safe Stage - Checks on: push: - branches: [$default-branch] + branches: [ main ] paths: - - "safe-stage/*" + - "safe-stage/**" pull_request: - branches: [$default-branch] + branches: [ main ] paths: - - "safe-stage/*" + - "safe-stage/**" env: CARGO_TERM_COLOR: always + MSRV: 1.86.0 jobs: - safe-stage-build: - runs-on: ubuntu-latest - strategy: - matrix: - FEATURES: ["--all", "-F ffi"] - steps: - - uses: actions/checkout@v4 - - uses: actions/cache@v4 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ./safe-stage/target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Check Formatting - run: cargo fmt --all --check - working-directory: ./safe-stage - - - name: Build with Features "${{ matrix.FEATURES }}" - run: cargo build --locked ${{ matrix.FEATURES }} - working-directory: ./safe-stage - - - name: Run clippy with Features "${{ matrix.FEATURES }}" - run: cargo clippy --locked ${{ matrix.FEATURES }} -- -D warnings - working-directory: ./safe-stage - - safe-stage-test: + safe-stage: runs-on: ubuntu-latest permissions: checks: write @@ -51,8 +23,6 @@ jobs: PROFILE_FEATURES: [ "ci-default;--all", - "ci-features-serde;--all -F serde", - "ci-features-linear;-p collisions --no-default-features -F rayon-bvh-linear", "ci-features-ffi;-F ffi", ] steps: @@ -67,9 +37,6 @@ jobs: ./safe-stage/target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Add nextest - uses: taiki-e/install-action@nextest - - name: Extract Profile and Features id: extraction run: | @@ -85,6 +52,27 @@ jobs: echo "profile=$PROFILE" >> "$GITHUB_OUTPUT" echo "features=$FEATURES" >> "$GITHUB_OUTPUT" + - name: Install Rust with MSRV + uses: taiki-e/github-actions/install-rust@main + with: + toolchain: ${{ env.MSRV }} + component: rustfmt,clippy + + - name: Check Formatting + run: cargo fmt --all --check + working-directory: ./safe-stage + + - name: Build with Features "${{ steps.extraction.outputs.features }}" + run: cargo build --locked ${{ steps.extraction.outputs.features }} + working-directory: ./safe-stage + + - name: Run clippy with Features "${{ steps.extraction.outputs.features }}" + run: cargo clippy --locked ${{ steps.extraction.outputs.features }} -- -D warnings + working-directory: ./safe-stage + + - name: Add nextest + uses: taiki-e/install-action@nextest + - name: Run Documentation Tests with Profile "${{ steps.extraction.outputs.profile }}" run: cargo test --locked --doc ${{ steps.extraction.outputs.features }} working-directory: ./safe-stage diff --git a/.github/workflows/service-app.yml b/.github/workflows/service-app.yml index 3e6a9b0..337c4d4 100644 --- a/.github/workflows/service-app.yml +++ b/.github/workflows/service-app.yml @@ -1,9 +1,9 @@ -name: Build Service Application +name: Service App - Build on: push: - branches: [$default-branch] + branches: [ main ] pull_request: - branches: [$default-branch] + branches: [ main ] env: CARGO_TERM_COLOR: always @@ -36,10 +36,10 @@ jobs: - name: Build Safe Stage run: | cargo run -p bindings - cargo build -F ffi + cargo build --release --features ffi working-directory: ./safe-stage - - name: Build Service Application + - name: Build Service App run: | dotnet build working-directory: ./service-app diff --git a/README.md b/README.md index a9c4009..57fd28d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Only Windows and .NET runtime are needed to run a compiled binary of the service ### Building -- installed Rust with version 1.83 or newer +- installed Rust with version 1.86 or newer - As of 18/12/2024, the *Nightly* version of the Rust toolchain results in a slightly better performance and is therefore recommended - installed .NET SDK 8 or newer - installed `cargo-expand` or selected nightly chain (run `cargo install cargo-expand` to install) - required for generating bindings @@ -38,7 +38,7 @@ Only Windows and .NET runtime are needed to run a compiled binary of the service ### MSRV (Minimum Supported Rust Version) -- `1.83.0` - due to stabilization of floats in `const` context +- `1.86.0` - floats in `const` context, trait upcasting coercion ## Building diff --git a/safe-stage/.nextest.toml b/safe-stage/.nextest.toml index c27c26e..1861a10 100644 --- a/safe-stage/.nextest.toml +++ b/safe-stage/.nextest.toml @@ -7,26 +7,6 @@ path = "junit-report.xml" store-success-output = true store-failure-output = true -[profile.ci-features-serde] -fail-fast = false - -[profile.ci-features-serde.junit] -report-name = "nextest-features-serde" -path = "junit-report.xml" -store-success-output = true -store-failure-output = true - -[profile.ci-features-linear] -fail-fast = false - -[profile.ci-features-linear.junit] -report-name = "nextest-features-linear" -path = "junit-report.xml" -store-success-output = true -store-failure-output = true - -[profile.ci-features-ffi] -fail-fast = false [profile.ci-features-ffi.junit] report-name = "nextest-features-ffi" diff --git a/safe-stage/collisions/src/complex.rs b/safe-stage/collisions/src/complex.rs index 34d2005..36561cf 100644 --- a/safe-stage/collisions/src/complex.rs +++ b/safe-stage/collisions/src/complex.rs @@ -2,14 +2,10 @@ //! Composite data structures for accelerating collision detection. //! //! Differences: -//! - [BvhTree] - boxes for bounding volumes, slower transformations, tighter bounds, -//! any `Collider` composites, during rotation, AABBs are converted to OBBs -//! - [BvhRecursive] - generic bounding volume hierarchy, -//! recommended to use with [AlignedBoxCollider] -//! - [BvhSphereLinear] - bounding sphere hierarchy, implemented with Vec as node storage, -//! very fast transformations slower collision detection -//! - [BvhSphereRecursive] - bounding sphere hierarchy, variant of [BvhRecursive] but optimized -//! for [SphereCollider] as the bounding shape +//! - [BvhTree] - boxes for bounding volumes, slower transformations, tighter bounds, any `Collider` composites, during rotation, AABBs are converted to OBBs +//! - [BvhRecursive] - generic bounding volume hierarchy, recommended to use with [AlignedBoxCollider] +//! - [BvhSphereLinear] - bounding sphere hierarchy, implemented with Vec as node storage, very fast transformations slower collision detection +//! - [BvhSphereRecursive] - bounding sphere hierarchy, variant of [BvhRecursive] but optimized for [SphereCollider] as the bounding shape use crate::collides_group_impl; use crate::complex::bvh_recursive::BvhRecursive; diff --git a/safe-stage/models/src/assembly/thesis/chamber.rs b/safe-stage/models/src/assembly/thesis/chamber.rs index c2466d4..25f9b8b 100644 --- a/safe-stage/models/src/assembly/thesis/chamber.rs +++ b/safe-stage/models/src/assembly/thesis/chamber.rs @@ -1,7 +1,7 @@ +use crate::immovable::Immovable; use crate::loader::load_stl_from_bytes; use crate::parts::chamber::Chamber; use collisions::common::Translation; -use collisions::complex::group::ColliderGroup; use collisions::{collider_group, PrimaryCollider}; use maths::Vector3; @@ -21,7 +21,7 @@ pub struct ThesisChamber { } impl Chamber for ThesisChamber { - fn full(&self) -> ColliderGroup { + fn full(&self) -> Immovable { collider_group!( self.pole_piece.clone(), self.walls.clone(), @@ -29,11 +29,11 @@ impl Chamber for ThesisChamber { ) } - fn less_obstructive(&self) -> ColliderGroup { + fn less_obstructive(&self) -> Immovable { collider_group!(self.pole_piece.clone(), self.walls.clone()) } - fn non_obstructive(&self) -> ColliderGroup { + fn non_obstructive(&self) -> Immovable { collider_group!(self.pole_piece.clone()) } } diff --git a/safe-stage/models/src/assembly/thesis/equipment.rs b/safe-stage/models/src/assembly/thesis/equipment.rs index e95f5ca..d314a45 100644 --- a/safe-stage/models/src/assembly/thesis/equipment.rs +++ b/safe-stage/models/src/assembly/thesis/equipment.rs @@ -1,6 +1,6 @@ +use crate::immovable::Immovable; use crate::loader::load_stl_from_bytes; use crate::parts::equipment::Equipment; -use collisions::complex::group::ColliderGroup; use collisions::{collider_group, PrimaryCollider}; const DETECTOR_ALPHA: &[u8] = include_bytes!("./models/Detector Alpha.stl"); @@ -17,7 +17,7 @@ impl Default for ThesisDetectorAlpha { } impl Equipment for ThesisDetectorAlpha { - fn collider(&self) -> ColliderGroup { + fn collider(&self) -> Immovable { collider_group!(self.0.clone()) } } @@ -33,7 +33,7 @@ impl Default for ThesisDetectorBeta { } impl Equipment for ThesisDetectorBeta { - fn collider(&self) -> ColliderGroup { + fn collider(&self) -> Immovable { collider_group!(self.0.clone()) } } diff --git a/safe-stage/models/src/assembly/thesis/holders.rs b/safe-stage/models/src/assembly/thesis/holders.rs index 57c6d06..bb29d43 100644 --- a/safe-stage/models/src/assembly/thesis/holders.rs +++ b/safe-stage/models/src/assembly/thesis/holders.rs @@ -1,7 +1,7 @@ +use crate::immovable::Immovable; use crate::loader::load_stl_from_bytes; use crate::parts::holder::Holder; use collisions::common::{Rotation, Translation}; -use collisions::complex::group::ColliderGroup; use collisions::{collider_group, PrimaryCollider}; use maths::{Quaternion, Vector3}; use std::sync::LazyLock; @@ -38,7 +38,7 @@ macro_rules! thesis_holder_impl { Box::new(self.clone()) } - fn collider(&self) -> ColliderGroup { + fn collider(&self) -> Immovable { if let Some(sample) = &self.sample { collider_group!(self.body.clone(), sample.clone()) } else { diff --git a/safe-stage/models/src/assembly/thesis/retract.rs b/safe-stage/models/src/assembly/thesis/retract.rs index 0d702a6..768ce02 100644 --- a/safe-stage/models/src/assembly/thesis/retract.rs +++ b/safe-stage/models/src/assembly/thesis/retract.rs @@ -1,9 +1,9 @@ +use crate::immovable::Immovable; use crate::loader::load_stl_from_bytes; use crate::movable::Movable; use crate::parts::retract::Retract; use crate::position::linear::LinearState; use collisions::common::Translation; -use collisions::complex::group::ColliderGroup; use collisions::{collider_group, PrimaryCollider}; use maths::Vector3; use std::sync::Arc; @@ -22,7 +22,7 @@ pub struct ThesisRetract { } impl Retract for ThesisRetract { - fn as_arc(&self) -> Arc + Send + Sync> { + fn as_movable(&self) -> Arc> { Arc::new(self.clone()) } } @@ -44,7 +44,7 @@ impl Default for ThesisRetract { } impl Movable for ThesisRetract { - fn move_to(&self, position: &LinearState) -> ColliderGroup { + fn move_to(&self, position: &LinearState) -> Immovable { match position { LinearState::None => collider_group!(self.entry.clone(), self.retracted.clone()), LinearState::Full => collider_group!(self.entry.clone(), self.inserted.clone()), diff --git a/safe-stage/models/src/assembly/thesis/stage.rs b/safe-stage/models/src/assembly/thesis/stage.rs index 962e5ca..c97e257 100644 --- a/safe-stage/models/src/assembly/thesis/stage.rs +++ b/safe-stage/models/src/assembly/thesis/stage.rs @@ -1,3 +1,4 @@ +use crate::immovable::Immovable; use crate::loader::load_stl_from_bytes; use crate::movable::Movable; use crate::parts::holder::Holder; @@ -36,7 +37,7 @@ impl Clone for ThesisStage { } impl Stage for ThesisStage { - fn as_arc(&self) -> Arc + Send + Sync> { + fn as_movable(&self) -> Arc> { Arc::new(self.clone()) } fn swap_holder(&mut self, holder: Option>) { @@ -67,7 +68,7 @@ impl Default for ThesisStage { } impl Movable for ThesisStage { - fn move_to(&self, coords: &SixAxis) -> ColliderGroup { + fn move_to(&self, coords: &SixAxis) -> Immovable { let offset = coords.pos + STAGE_POSITION; let tilt = Quaternion::from_euler(&Vector3::new(0.0, coords.rot.y(), 0.0)); let rotation = Quaternion::from_euler(&Vector3::new(0.0, 0.0, coords.rot.z())); diff --git a/safe-stage/models/src/immovable.rs b/safe-stage/models/src/immovable.rs new file mode 100644 index 0000000..91b5e6e --- /dev/null +++ b/safe-stage/models/src/immovable.rs @@ -0,0 +1,4 @@ +use collisions::complex::group::ColliderGroup; +use collisions::PrimaryCollider; + +pub type Immovable = ColliderGroup; diff --git a/safe-stage/models/src/lib.rs b/safe-stage/models/src/lib.rs index ff9aa65..d9a0fba 100644 --- a/safe-stage/models/src/lib.rs +++ b/safe-stage/models/src/lib.rs @@ -2,6 +2,7 @@ //! Focused on modeling the parts of an electron microscope. pub mod assembly; +pub mod immovable; pub mod loader; pub mod movable; pub mod parts; diff --git a/safe-stage/models/src/movable.rs b/safe-stage/models/src/movable.rs index 264323b..44d7452 100644 --- a/safe-stage/models/src/movable.rs +++ b/safe-stage/models/src/movable.rs @@ -1,8 +1,7 @@ -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use crate::immovable::Immovable; /// Entity can be moved to position `P` where it is represented as `C`. -pub trait Movable

{ +pub trait Movable

: Send + Sync { /// Get the representation of the entity at the given position. - fn move_to(&self, position: &P) -> ColliderGroup; + fn move_to(&self, position: &P) -> Immovable; } diff --git a/safe-stage/models/src/parts/chamber.rs b/safe-stage/models/src/parts/chamber.rs index 899df21..e12848a 100644 --- a/safe-stage/models/src/parts/chamber.rs +++ b/safe-stage/models/src/parts/chamber.rs @@ -1,12 +1,11 @@ -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use crate::immovable::Immovable; /// # Chamber pub trait Chamber: Send + Sync { /// Get the full representation of the chamber. - fn full(&self) -> ColliderGroup; + fn full(&self) -> Immovable; /// Get the representation of the chamber with less obstructive parts. - fn less_obstructive(&self) -> ColliderGroup; + fn less_obstructive(&self) -> Immovable; /// Get the representation of the chamber only with non-obstructive parts. - fn non_obstructive(&self) -> ColliderGroup; + fn non_obstructive(&self) -> Immovable; } diff --git a/safe-stage/models/src/parts/equipment.rs b/safe-stage/models/src/parts/equipment.rs index c05a4e9..ecd9d67 100644 --- a/safe-stage/models/src/parts/equipment.rs +++ b/safe-stage/models/src/parts/equipment.rs @@ -1,8 +1,7 @@ -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use crate::immovable::Immovable; /// # Equipment pub trait Equipment: Send + Sync { /// Get the full representation of the equipment. - fn collider(&self) -> ColliderGroup; + fn collider(&self) -> Immovable; } diff --git a/safe-stage/models/src/parts/holder.rs b/safe-stage/models/src/parts/holder.rs index 4e34000..4562599 100644 --- a/safe-stage/models/src/parts/holder.rs +++ b/safe-stage/models/src/parts/holder.rs @@ -1,4 +1,4 @@ -use collisions::complex::group::ColliderGroup; +use crate::immovable::Immovable; use collisions::PrimaryCollider; /// # Stage Holder @@ -6,7 +6,7 @@ pub trait Holder: Send + Sync { /// Clone the holder into box. fn cloned(&self) -> Box; /// Get the full representation of the holder. - fn collider(&self) -> ColliderGroup; + fn collider(&self) -> Immovable; /// Swap the attached sample with the given one. fn swap_sample(&mut self, sample: Option); } diff --git a/safe-stage/models/src/parts/retract.rs b/safe-stage/models/src/parts/retract.rs index 9e87941..da15244 100644 --- a/safe-stage/models/src/parts/retract.rs +++ b/safe-stage/models/src/parts/retract.rs @@ -3,7 +3,7 @@ use crate::position::linear::LinearState; use std::sync::Arc; /// # Retractable Device -pub trait Retract: Movable + Send + Sync { +pub trait Retract: Movable { /// Get the Retractable Device as [Arc] reference. - fn as_arc(&self) -> Arc + Send + Sync>; + fn as_movable(&self) -> Arc>; } diff --git a/safe-stage/models/src/parts/stage.rs b/safe-stage/models/src/parts/stage.rs index 7dfb245..1e30b56 100644 --- a/safe-stage/models/src/parts/stage.rs +++ b/safe-stage/models/src/parts/stage.rs @@ -4,9 +4,9 @@ use crate::position::sixaxis::SixAxis; use std::sync::Arc; /// # Stage -pub trait Stage: Movable + Send + Sync { +pub trait Stage: Movable { /// Get the Stage as [Arc] reference. - fn as_arc(&self) -> Arc + Send + Sync>; + fn as_movable(&self) -> Arc>; /// Swap the attached holder with the given one. fn swap_holder(&mut self, holder: Option>); /// Get the active holder. diff --git a/safe-stage/paths/benches/space_sampling.rs b/safe-stage/paths/benches/space_sampling.rs index b052a41..a33201f 100644 --- a/safe-stage/paths/benches/space_sampling.rs +++ b/safe-stage/paths/benches/space_sampling.rs @@ -12,8 +12,8 @@ fn sample_space(stage: &ThesisStage, chamber: &ThesisChamber) -> Grid3DSpace { sample_grid_space_3d_par( &min.pos, &max.pos, - &chamber.full(), stage, + &chamber.full(), &step, &Vector3::ZERO, ) diff --git a/safe-stage/paths/src/common/sight.rs b/safe-stage/paths/src/common/sight.rs index 9ef6314..9a33b8e 100644 --- a/safe-stage/paths/src/common/sight.rs +++ b/safe-stage/paths/src/common/sight.rs @@ -1,25 +1,23 @@ use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::NaNExtension; +use models::immovable::Immovable; use models::{movable::Movable, position::sixaxis::SixAxis}; use rayon::prelude::*; /// Check if there is a line of sight between two coordinates /// by using linear interpolation with fixed step. +/// +/// Use `line_of_sight_step_par` instead. +/// #[deprecated] -pub fn line_of_sight( +pub fn line_of_sight( from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, move_step: f64, rotate_step: f64, -) -> bool -where - M: Movable, - I: Collides>, -{ +) -> bool { let diff_pos = (to.pos - from.pos).abs(); let diff_rot = from.shortest_rotation(to); @@ -39,44 +37,16 @@ where true } -/// Checks if there is a line of sight between two coordinates by moving in a given step. -/// -/// Parallel version available with [line_of_sight_par]. -pub fn line_of_sight_step( - from: &SixAxis, - to: &SixAxis, - movable: &M, - immovable: &I, - step: &SixAxis, -) -> bool -where - M: Movable, - I: Collides>, -{ - let max_steps = from.stepping(to, step); - (0..=max_steps).all(|i| { - let t = (i as f64 / max_steps as f64).map_nan(0.0); - let state = from.lerp_t(to, t); - !immovable.collides_with(&movable.move_to(&state)) - }) -} - /// Checks if there is a line of sight between two coordinates by moving in a given step. /// /// **Runs in parallel using Rayon.** -/// -/// Single-threaded version available with [line_of_sight_step]. -pub fn line_of_sight_step_par( +pub fn line_of_sight_step_par( from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, step: &SixAxis, -) -> bool -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +) -> bool { let max_steps = from.stepping(to, step); (0..=max_steps).into_par_iter().all(|i| { let t = (i as f64 / max_steps as f64).map_nan(0.0); diff --git a/safe-stage/paths/src/common/timing.rs b/safe-stage/paths/src/common/timing.rs index 31647d9..72424a3 100644 --- a/safe-stage/paths/src/common/timing.rs +++ b/safe-stage/paths/src/common/timing.rs @@ -1,3 +1,4 @@ +#[macro_export] macro_rules! timed { ($block:block) => {{ let start = std::time::Instant::now(); @@ -6,4 +7,4 @@ macro_rules! timed { }}; } -pub(crate) use timed; +pub use timed; diff --git a/safe-stage/paths/src/deferred/pathing/a_star.rs b/safe-stage/paths/src/deferred/pathing/a_star.rs index e376deb..8f49a67 100644 --- a/safe-stage/paths/src/deferred/pathing/a_star.rs +++ b/safe-stage/paths/src/deferred/pathing/a_star.rs @@ -4,8 +4,7 @@ use crate::neighbors::NeighborStrategy; use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use std::collections::{BinaryHeap, HashMap}; @@ -47,17 +46,13 @@ impl PathStrategy for AStarStrategy where N: NeighborStrategy, { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/a_star_increment.rs b/safe-stage/paths/src/deferred/pathing/a_star_increment.rs index bde4c2b..dd12dfe 100644 --- a/safe-stage/paths/src/deferred/pathing/a_star_increment.rs +++ b/safe-stage/paths/src/deferred/pathing/a_star_increment.rs @@ -4,8 +4,7 @@ use crate::neighbors::NeighborStrategy; use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use std::collections::{BinaryHeap, HashMap}; @@ -49,17 +48,13 @@ impl PathStrategy for AStarIncrementStrategy where N: NeighborStrategy, { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/linear.rs b/safe-stage/paths/src/deferred/pathing/linear.rs index ff6cad1..db1ee29 100644 --- a/safe-stage/paths/src/deferred/pathing/linear.rs +++ b/safe-stage/paths/src/deferred/pathing/linear.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::NaNExtension; +use models::immovable::Immovable; use models::movable::Movable; use models::position::linear::LinearState; use models::position::sixaxis::SixAxis; @@ -23,17 +22,13 @@ impl

LinearStrategy

{ } impl PathStrategy for LinearStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } @@ -59,17 +54,13 @@ impl PathStrategy for LinearStrategy { } impl PathStrategy for LinearStrategy { - fn find_path( + fn find_path( &self, from: &LinearState, to: &LinearState, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/linear_par.rs b/safe-stage/paths/src/deferred/pathing/linear_par.rs index cf61678..9f01b99 100644 --- a/safe-stage/paths/src/deferred/pathing/linear_par.rs +++ b/safe-stage/paths/src/deferred/pathing/linear_par.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::NaNExtension; +use models::immovable::Immovable; use models::movable::Movable; use models::position::linear::LinearState; use models::position::sixaxis::SixAxis; @@ -26,17 +25,13 @@ impl

LinearParallelStrategy

{ } impl PathStrategy for LinearParallelStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } @@ -63,17 +58,13 @@ impl PathStrategy for LinearParallelStrategy { } impl PathStrategy for LinearParallelStrategy { - fn find_path( + fn find_path( &self, from: &LinearState, to: &LinearState, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/rotation_height.rs b/safe-stage/paths/src/deferred/pathing/rotation_height.rs index 1d15bf3..a1b9626 100644 --- a/safe-stage/paths/src/deferred/pathing/rotation_height.rs +++ b/safe-stage/paths/src/deferred/pathing/rotation_height.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::{NaNExtension, Vector3}; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; @@ -29,17 +28,13 @@ impl SafeRotationHeightStrategy { } impl PathStrategy for SafeRotationHeightStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/rotation_height_par.rs b/safe-stage/paths/src/deferred/pathing/rotation_height_par.rs index 27eff79..65a2e43 100644 --- a/safe-stage/paths/src/deferred/pathing/rotation_height_par.rs +++ b/safe-stage/paths/src/deferred/pathing/rotation_height_par.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::{NaNExtension, Vector3}; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use rayon::prelude::*; @@ -32,17 +31,13 @@ impl SafeRotationHeightParallelStrategy { } impl PathStrategy for SafeRotationHeightParallelStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/rotation_point.rs b/safe-stage/paths/src/deferred/pathing/rotation_point.rs index 407ec38..35f8f18 100644 --- a/safe-stage/paths/src/deferred/pathing/rotation_point.rs +++ b/safe-stage/paths/src/deferred/pathing/rotation_point.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::{NaNExtension, Vector3}; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; @@ -29,17 +28,13 @@ impl SafeRotationPointStrategy { } impl PathStrategy for SafeRotationPointStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/rotation_point_par.rs b/safe-stage/paths/src/deferred/pathing/rotation_point_par.rs index e50ea2c..e5f418c 100644 --- a/safe-stage/paths/src/deferred/pathing/rotation_point_par.rs +++ b/safe-stage/paths/src/deferred/pathing/rotation_point_par.rs @@ -1,9 +1,8 @@ use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::{NaNExtension, Vector3}; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use rayon::prelude::*; @@ -32,17 +31,13 @@ impl SafeRotationPointParallelStrategy { } impl PathStrategy for SafeRotationPointParallelStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/deferred/pathing/theta_star.rs b/safe-stage/paths/src/deferred/pathing/theta_star.rs index 8a57876..bafd6ec 100644 --- a/safe-stage/paths/src/deferred/pathing/theta_star.rs +++ b/safe-stage/paths/src/deferred/pathing/theta_star.rs @@ -4,8 +4,7 @@ use crate::common::sight::line_of_sight; use crate::neighbors::NeighborStrategy; use crate::{common::heapstate::MinHeapState, path::PathResult, strategy::PathStrategy}; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use std::collections::{BinaryHeap, HashMap, HashSet}; @@ -46,7 +45,7 @@ where } #[allow(clippy::too_many_arguments)] - fn update_vertex( + fn update_vertex( &self, s: &SixAxis, sn: &SixAxis, @@ -54,12 +53,9 @@ where gscore: &mut HashMap, parent: &mut HashMap, open: &mut BinaryHeap>, - movable: &M, - immovable: &I, - ) where - M: Movable, - I: Collides>, - { + movable: &dyn Movable, + immovable: &Immovable, + ) { #[allow(deprecated)] if line_of_sight( &parent[s], @@ -96,17 +92,13 @@ impl PathStrategy for ThetaStarStrategy where N: NeighborStrategy, { - fn find_path( + fn find_path( &self, start: &SixAxis, end: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(start)) { return PathResult::InvalidStart(*start); } diff --git a/safe-stage/paths/src/eager/pathing/a_star_with_los.rs b/safe-stage/paths/src/eager/pathing/a_star_with_los.rs index b2a488c..dd5066a 100644 --- a/safe-stage/paths/src/eager/pathing/a_star_with_los.rs +++ b/safe-stage/paths/src/eager/pathing/a_star_with_los.rs @@ -5,9 +5,8 @@ use crate::eager::space::space_3d::Grid3DSpace; use crate::path::PathResult; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use std::collections::{BinaryHeap, HashMap}; @@ -76,18 +75,14 @@ impl<'a> AStar3DSpaceWithLoSStrategy<'a> { } #[inline] - fn has_line_of_sight( + fn has_line_of_sight( &self, rot: &Vector3, from: &Vector3, to: &Vector3, - movable: &M, - immovable: &I, - ) -> bool - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> bool { let sight_from = SixAxis { pos: *from, rot: *rot, @@ -102,17 +97,13 @@ impl<'a> AStar3DSpaceWithLoSStrategy<'a> { } impl PathStrategy for AStar3DSpaceWithLoSStrategy<'_> { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/eager/pathing/basic_prm.rs b/safe-stage/paths/src/eager/pathing/basic_prm.rs index fae9c83..cf365aa 100644 --- a/safe-stage/paths/src/eager/pathing/basic_prm.rs +++ b/safe-stage/paths/src/eager/pathing/basic_prm.rs @@ -1,8 +1,7 @@ use crate::{common::heapstate::MinHeapState, path::PathResult, strategy::PathStrategy}; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::{movable::Movable, position::sixaxis::SixAxis}; use std::collections::{BinaryHeap, HashMap}; @@ -55,17 +54,13 @@ impl BasicPrmStrategy { } impl PathStrategy for BasicPrmStrategy { - fn find_path( + fn find_path( &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, - ) -> PathResult - where - M: Movable + Sync, - I: Collides> + Sync + Send, - { + movable: &dyn Movable, + immovable: &Immovable, + ) -> PathResult { if immovable.collides_with(&movable.move_to(from)) { return PathResult::InvalidStart(*from); } diff --git a/safe-stage/paths/src/eager/sampling.rs b/safe-stage/paths/src/eager/sampling.rs index 6f973e8..5c832f4 100644 --- a/safe-stage/paths/src/eager/sampling.rs +++ b/safe-stage/paths/src/eager/sampling.rs @@ -1,4 +1,3 @@ -pub mod flood_sampling; pub mod grid_sampling; pub mod random_sampling; pub mod samples_graph; diff --git a/safe-stage/paths/src/eager/sampling/flood_sampling.rs b/safe-stage/paths/src/eager/sampling/flood_sampling.rs deleted file mode 100644 index d0c9895..0000000 --- a/safe-stage/paths/src/eager/sampling/flood_sampling.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::neighbors::NeighborStrategy; -use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; -use models::movable::Movable; -use models::position::sixaxis::SixAxis; -use std::collections::{HashSet, VecDeque}; - -pub fn flood_samples( - start: &SixAxis, - immovable: &I, - movable: &M, - strategy: &N, -) -> Vec -where - M: Movable, - I: Collides>, - N: NeighborStrategy, -{ - let mut samples: Vec = Vec::new(); - let mut closed: HashSet = HashSet::new(); - let mut open: VecDeque = VecDeque::new(); - - open.push_back(*start); - - while let Some(state) = open.pop_front() { - for neighbor in strategy.neighbors(&state) { - if closed.contains(&neighbor) { - continue; - } - if immovable.collides_with(&movable.move_to(&neighbor)) { - continue; - } - - samples.push(neighbor); - closed.insert(neighbor); - open.push_back(neighbor); - } - } - - samples.shrink_to_fit(); - samples -} diff --git a/safe-stage/paths/src/eager/sampling/grid_sampling.rs b/safe-stage/paths/src/eager/sampling/grid_sampling.rs index a5d47f6..0d74a60 100644 --- a/safe-stage/paths/src/eager/sampling/grid_sampling.rs +++ b/safe-stage/paths/src/eager/sampling/grid_sampling.rs @@ -1,78 +1,17 @@ use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use rayon::prelude::*; -pub fn grid_samples( +pub fn grid_samples_par( min: &SixAxis, max: &SixAxis, - immovable: &I, - movable: &M, + movable: &dyn Movable, + immovable: &Immovable, step: &SixAxis, -) -> Vec -where - M: Movable, - I: Collides>, -{ - let diff = max - min; - let (x, y, z, rx, ry, rz) = ( - range(diff.pos.x(), step.pos.x()), - range(diff.pos.y(), step.pos.y()), - range(diff.pos.z(), step.pos.z()), - range(diff.rot.x(), step.rot.x()), - range(diff.rot.y(), step.rot.y()), - range(diff.rot.z(), step.rot.z()), - ); - - let mut samples = Vec::new(); - for x in 0..x { - for y in 0..y { - for z in 0..z { - for rx in 0..rx { - for ry in 0..ry { - for rz in 0..rz { - let sample = SixAxis { - pos: Vector3::new( - min.pos.x() + x as f64 * step.pos.x(), - min.pos.y() + y as f64 * step.pos.y(), - min.pos.z() + z as f64 * step.pos.z(), - ), - rot: Vector3::new( - min.rot.x() + rx as f64 * step.rot.x(), - min.rot.y() + ry as f64 * step.rot.y(), - min.rot.z() + rz as f64 * step.rot.z(), - ), - }; - - let at_sample = movable.move_to(&sample); - if !immovable.collides_with(&at_sample) { - samples.push(sample); - } - } - } - } - } - } - } - - samples.shrink_to_fit(); - samples -} - -pub fn grid_samples_par( - min: &SixAxis, - max: &SixAxis, - immovable: &I, - movable: &M, - step: &SixAxis, -) -> Vec -where - M: Movable + Sync, - I: Sync + Collides>, -{ +) -> Vec { let diff = max - min; let (x, y, z, rx, ry, rz) = ( range(diff.pos.x(), step.pos.x()), diff --git a/safe-stage/paths/src/eager/sampling/random_sampling.rs b/safe-stage/paths/src/eager/sampling/random_sampling.rs index 330a610..ad9c2d5 100644 --- a/safe-stage/paths/src/eager/sampling/random_sampling.rs +++ b/safe-stage/paths/src/eager/sampling/random_sampling.rs @@ -1,23 +1,18 @@ use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use rand::random; use rayon::prelude::*; -pub fn random_samples( +pub fn random_samples( min: &SixAxis, max: &SixAxis, - immovable: &I, - movable: &M, + movable: &dyn Movable, + immovable: &Immovable, count: usize, -) -> Vec -where - M: Movable, - I: Collides>, -{ +) -> Vec { let range = max - min; let mut samples = Vec::with_capacity(count); while samples.len() < count { @@ -32,17 +27,13 @@ where samples } -pub fn random_samples_par( +pub fn random_samples_par( min: &SixAxis, max: &SixAxis, - immovable: &I, - movable: &M, + movable: &dyn Movable, + immovable: &Immovable, count: usize, -) -> Vec -where - M: Movable + Sync, - I: Sync + Collides>, -{ +) -> Vec { let range = max - min; (0..count) .into_par_iter() diff --git a/safe-stage/paths/src/eager/space/sampled_space_3d.rs b/safe-stage/paths/src/eager/space/sampled_space_3d.rs index c4d73b4..8b0d2d7 100644 --- a/safe-stage/paths/src/eager/space/sampled_space_3d.rs +++ b/safe-stage/paths/src/eager/space/sampled_space_3d.rs @@ -1,9 +1,8 @@ use crate::eager::space::space_3d::Grid3DSpace; use bitvec::vec::BitVec; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use rayon::prelude::*; @@ -11,18 +10,14 @@ use rayon::prelude::*; /// Samples the 3D space with the given step and rotation. /// /// Parallel version available with [sample_grid_space_3d_par]. -pub fn sample_grid_space_3d( +pub fn sample_grid_space_3d( min: &Vector3, max: &Vector3, - immovable: &I, - movable: &M, + movable: &dyn Movable, + immovable: &Immovable, step: &Vector3, rotation: &Vector3, -) -> Grid3DSpace -where - M: Movable, - I: Collides>, -{ +) -> Grid3DSpace { let diff = max - min; let (x, y, z) = ( range(diff.x(), step.x()), @@ -57,18 +52,14 @@ where /// **Runs in parallel using Rayon.** /// /// Single-threaded version available with [sample_grid_space_3d]. -pub fn sample_grid_space_3d_par( +pub fn sample_grid_space_3d_par( min: &Vector3, max: &Vector3, - immovable: &I, - movable: &M, + movable: &dyn Movable, + immovable: &Immovable, step: &Vector3, rotation: &Vector3, -) -> Grid3DSpace -where - M: Movable + Sync, - I: Sync + Collides>, -{ +) -> Grid3DSpace { let diff = max - min; let (dx, dy, dz) = ( range(diff.x(), step.x()), diff --git a/safe-stage/paths/src/postprocess.rs b/safe-stage/paths/src/postprocess.rs index fb4c5a5..4526358 100644 --- a/safe-stage/paths/src/postprocess.rs +++ b/safe-stage/paths/src/postprocess.rs @@ -1,3 +1,2 @@ pub mod granulate_path; -pub mod smooth; pub mod smooth_par; diff --git a/safe-stage/paths/src/postprocess/smooth.rs b/safe-stage/paths/src/postprocess/smooth.rs deleted file mode 100644 index d820f1e..0000000 --- a/safe-stage/paths/src/postprocess/smooth.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::common::sight::line_of_sight_step; -use crate::path::PathResult; -use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; -use models::movable::Movable; -use models::position::sixaxis::SixAxis; - -/// Smooths the path by removing intermediate nodes if there is a line of sight to a next node. -/// -/// Parallel version available with [smooth_path_par]. -pub fn smooth_path( - path: PathResult, - movable: &M, - immovable: &I, - step: &SixAxis, -) -> PathResult -where - M: Movable, - I: Collides>, -{ - path.map(|p| smooth_path_nodes(p, movable, immovable, step)) -} - -fn smooth_path_nodes( - path: &[SixAxis], - movable: &M, - immovable: &I, - step: &SixAxis, -) -> Vec -where - M: Movable, - I: Collides>, -{ - let mut smooth = vec![path[0]]; - let mut k = 0; - for i in 1..path.len() - 1 { - if !line_of_sight_step(&path[k], &path[i + 1], movable, immovable, step) { - smooth.push(path[i]); - k = i; - } - } - - smooth.push(path[path.len() - 1]); - smooth.shrink_to_fit(); - smooth -} diff --git a/safe-stage/paths/src/postprocess/smooth_par.rs b/safe-stage/paths/src/postprocess/smooth_par.rs index aff2c76..07d038d 100644 --- a/safe-stage/paths/src/postprocess/smooth_par.rs +++ b/safe-stage/paths/src/postprocess/smooth_par.rs @@ -1,8 +1,6 @@ use crate::common::sight::line_of_sight_step_par; use crate::path::PathResult; -use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; @@ -11,29 +9,21 @@ use models::position::sixaxis::SixAxis; /// **Runs in parallel using Rayon.** /// /// Single-threaded version available with [smooth_path]. -pub fn smooth_path_par( +pub fn smooth_path_par( path: PathResult, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, step: &SixAxis, -) -> PathResult -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +) -> PathResult { path.map(|p| smooth_path_nodes_par(p, movable, immovable, step)) } -fn smooth_path_nodes_par( +fn smooth_path_nodes_par( path: &[SixAxis], - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, step: &SixAxis, -) -> Vec -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +) -> Vec { let mut smooth = vec![path[0]]; let mut k = 0; for i in 1..path.len() - 1 { diff --git a/safe-stage/paths/src/resolver.rs b/safe-stage/paths/src/resolver.rs index 4f5af87..a5f26fe 100644 --- a/safe-stage/paths/src/resolver.rs +++ b/safe-stage/paths/src/resolver.rs @@ -2,11 +2,8 @@ pub mod retract; pub mod stage; use crate::path::PathResult; -use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; -use std::sync::Arc; use thiserror::Error; /// # State Update Error @@ -19,29 +16,19 @@ pub enum StateUpdateError { /// # Path Resolver /// Resolves a path between two points and holds state to do it faster. -pub trait PathResolver -where - M: Movable

+ Sync, - I: Collides> + Sync + Send, -{ - fn update_state(&mut self, new: &P, movable: &M, immovable: &I) - -> Result<(), StateUpdateError>; - - fn resolve_path(&self, from: &P, to: &P, movable: &M, immovable: &I) -> PathResult

; -} - -pub struct DynamicMovable

(pub Arc + Send + Sync>); - -impl

Movable

for DynamicMovable

{ - fn move_to(&self, position: &P) -> ColliderGroup { - self.0.move_to(position) - } -} - -pub struct DynamicImmovable(pub Arc> + Send + Sync>); - -impl Collides> for DynamicImmovable { - fn collides_with(&self, other: &ColliderGroup) -> bool { - self.0.collides_with(other) - } +pub trait PathResolver

{ + fn update_state( + &mut self, + new: &P, + movable: &dyn Movable

, + immovable: &Immovable, + ) -> Result<(), StateUpdateError>; + + fn resolve_path( + &self, + from: &P, + to: &P, + movable: &dyn Movable

, + immovable: &Immovable, + ) -> PathResult

; } diff --git a/safe-stage/paths/src/resolver/retract.rs b/safe-stage/paths/src/resolver/retract.rs index 2527607..16e96e0 100644 --- a/safe-stage/paths/src/resolver/retract.rs +++ b/safe-stage/paths/src/resolver/retract.rs @@ -1,9 +1,6 @@ -use crate::resolver::{DynamicImmovable, DynamicMovable, PathResolver}; +use crate::resolver::PathResolver; use models::position::linear::LinearState; pub mod linear; -pub trait RetractPathResolver: - PathResolver, DynamicImmovable> -{ -} +pub trait RetractPathResolver: PathResolver {} diff --git a/safe-stage/paths/src/resolver/retract/linear.rs b/safe-stage/paths/src/resolver/retract/linear.rs index 6e5de98..072407c 100644 --- a/safe-stage/paths/src/resolver/retract/linear.rs +++ b/safe-stage/paths/src/resolver/retract/linear.rs @@ -5,8 +5,7 @@ use crate::resolver::retract::RetractPathResolver; use crate::resolver::{PathResolver, StateUpdateError}; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::linear::LinearState; @@ -29,16 +28,12 @@ impl RetractLinearResolver { impl RetractPathResolver for RetractLinearResolver {} -impl PathResolver for RetractLinearResolver -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +impl PathResolver for RetractLinearResolver { fn update_state( &mut self, new: &LinearState, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> Result<(), StateUpdateError> { if immovable.collides_with(&movable.move_to(new)) { return Err(StateUpdateError::InvalidState); @@ -51,8 +46,8 @@ where &self, from: &LinearState, to: &LinearState, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> PathResult { let (path, time_to_path) = timed!({ self.strategy.find_path(from, to, movable, immovable) }); diff --git a/safe-stage/paths/src/resolver/stage.rs b/safe-stage/paths/src/resolver/stage.rs index 0b11724..70a2836 100644 --- a/safe-stage/paths/src/resolver/stage.rs +++ b/safe-stage/paths/src/resolver/stage.rs @@ -1,10 +1,7 @@ -use crate::resolver::{DynamicImmovable, DynamicMovable, PathResolver}; +use crate::resolver::PathResolver; use models::position::sixaxis::SixAxis; pub mod down_rotate_find; pub mod linear; -pub trait StagePathResolver: - PathResolver, DynamicImmovable> -{ -} +pub trait StagePathResolver: PathResolver {} diff --git a/safe-stage/paths/src/resolver/stage/down_rotate_find.rs b/safe-stage/paths/src/resolver/stage/down_rotate_find.rs index 4f4464d..81c91f8 100644 --- a/safe-stage/paths/src/resolver/stage/down_rotate_find.rs +++ b/safe-stage/paths/src/resolver/stage/down_rotate_find.rs @@ -9,9 +9,8 @@ use crate::resolver::stage::StagePathResolver; use crate::resolver::{PathResolver, StateUpdateError}; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; use maths::Vector3; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; use std::thread; @@ -66,16 +65,12 @@ impl DownRotateFindResolver { impl StagePathResolver for DownRotateFindResolver {} -impl PathResolver for DownRotateFindResolver -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +impl PathResolver for DownRotateFindResolver { fn update_state( &mut self, new: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> Result<(), StateUpdateError> { if immovable.collides_with(&movable.move_to(new)) { return Err(StateUpdateError::InvalidState); @@ -85,8 +80,8 @@ where Some(sample_grid_space_3d_par( &self.sample_min, &self.sample_max, - immovable, movable, + immovable, &self.sample_step, &new.rot, )) @@ -102,8 +97,8 @@ where &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> PathResult { let mut start = *from; let mut prepath = Vec::new(); @@ -118,8 +113,8 @@ where sample_grid_space_3d_par( &self.sample_min, &self.sample_max, - immovable, movable, + immovable, &self.sample_step, &start.rot, ) diff --git a/safe-stage/paths/src/resolver/stage/linear.rs b/safe-stage/paths/src/resolver/stage/linear.rs index e57fefc..96348cd 100644 --- a/safe-stage/paths/src/resolver/stage/linear.rs +++ b/safe-stage/paths/src/resolver/stage/linear.rs @@ -5,8 +5,7 @@ use crate::resolver::stage::StagePathResolver; use crate::resolver::{PathResolver, StateUpdateError}; use crate::strategy::PathStrategy; use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; use models::position::sixaxis::SixAxis; @@ -29,16 +28,12 @@ impl StageLinearResolver { impl StagePathResolver for StageLinearResolver {} -impl PathResolver for StageLinearResolver -where - M: Movable + Sync, - I: Collides> + Sync + Send, -{ +impl PathResolver for StageLinearResolver { fn update_state( &mut self, new: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> Result<(), StateUpdateError> { if immovable.collides_with(&movable.move_to(new)) { return Err(StateUpdateError::InvalidState); @@ -51,8 +46,8 @@ where &self, from: &SixAxis, to: &SixAxis, - movable: &M, - immovable: &I, + movable: &dyn Movable, + immovable: &Immovable, ) -> PathResult { let (path, time_to_path) = timed!({ self.strategy.find_path(from, to, movable, immovable) }); diff --git a/safe-stage/paths/src/strategy.rs b/safe-stage/paths/src/strategy.rs index ddae6b7..1a3b8ae 100644 --- a/safe-stage/paths/src/strategy.rs +++ b/safe-stage/paths/src/strategy.rs @@ -1,16 +1,16 @@ use crate::path::PathResult; -use collisions::common::Collides; -use collisions::complex::group::ColliderGroup; -use collisions::PrimaryCollider; +use models::immovable::Immovable; use models::movable::Movable; /// # Path strategy /// A path strategy that can find a path from one point to another. pub trait PathStrategy

{ /// Try finding a path from one point to another. - /// Movable `M` produces position `C` which immovable of type `I` must implement collision with. - fn find_path(&self, from: &P, to: &P, movable: &M, immovable: &I) -> PathResult

- where - M: Movable

+ Sync, - I: Collides> + Sync + Send; + fn find_path( + &self, + from: &P, + to: &P, + movable: &dyn Movable

, + immovable: &Immovable, + ) -> PathResult

; } diff --git a/safe-stage/paths/tests/complex_path.rs b/safe-stage/paths/tests/complex_path.rs new file mode 100644 index 0000000..c7443e6 --- /dev/null +++ b/safe-stage/paths/tests/complex_path.rs @@ -0,0 +1,90 @@ +use maths::Vector3; +use models::assembly::thesis::{ + ThesisChamber, ThesisDetectorAlpha, ThesisDetectorBeta, ThesisHolderCircle, ThesisStage, +}; +use models::parts::chamber::Chamber; +use models::parts::equipment::Equipment; +use models::parts::holder::Holder; +use models::parts::stage::Stage; +use models::position::sixaxis::SixAxis; +use paths::path::PathResult; +use paths::resolver::stage::down_rotate_find::DownRotateFindResolver; +use paths::resolver::stage::StagePathResolver; +use paths::timed; + +const START_POSITION: SixAxis = SixAxis { + pos: Vector3::new(0e-3, 0e-3, 55e-3), + rot: Vector3::new(0_f64.to_radians(), 0_f64.to_radians(), 0_f64.to_radians()), +}; +const END_POSITION: SixAxis = SixAxis { + pos: Vector3::new(-55e-3, 0e-3, 55e-3), + rot: Vector3::new(0_f64.to_radians(), 40_f64.to_radians(), 0_f64.to_radians()), +}; + +#[test] +fn complex_path_resolution() { + let chamber = setup_chamber(); + let equipment = setup_equipment(); + let immovable = chamber + .full() + .extended(equipment[0].collider()) + .extended(equipment[1].collider()); + + let mut stage = setup_stage(); + let holder = setup_holder(); + stage.swap_holder(Some(holder)); + + let mut stage_resolver = setup_stage_resolver(); + let (_, update_time) = timed!({ + stage_resolver + .update_state(&START_POSITION, stage.as_ref(), &immovable) + .unwrap(); + }); + println!("State updated in {:?} ms", update_time.as_millis()); + + let (path, path_time) = timed!({ + stage_resolver.resolve_path(&START_POSITION, &END_POSITION, stage.as_ref(), &immovable) + }); + println!("Path found in {:?} ms", path_time.as_millis()); + + assert!(matches!(path, PathResult::Path(_))); +} + +fn setup_chamber() -> Box { + Box::new(ThesisChamber::default()) +} + +fn setup_equipment() -> Box<[Box]> { + Box::new([ + Box::new(ThesisDetectorAlpha::default()), + Box::new(ThesisDetectorBeta::default()), + ]) +} + +fn setup_stage() -> Box { + Box::new(ThesisStage::default()) +} + +fn setup_holder() -> Box { + Box::new(ThesisHolderCircle::default()) +} + +fn setup_stage_resolver() -> Box { + Box::new(DownRotateFindResolver::new( + Vector3::ZERO, + SixAxis { + pos: Vector3::new(1.0, 1.0, 1.0), + rot: Vector3::new(1_f64.to_radians(), 1_f64.to_radians(), 1_f64.to_radians()), + }, + Vector3::new(1.0, 1.0, 1.0), + Vector3::new(-0.135, -0.125, -0.125), + Vector3::new(0.125, 0.125, 0.125), + Vector3::new(0.01, 0.01, 0.01), + Vector3::new(0.006, 0.006, 0.006), + Vector3::new(0.001, 0.001, 0.001), + SixAxis { + pos: Vector3::new(1.0, 1.0, 1.0), + rot: Vector3::new(1_f64.to_radians(), 1_f64.to_radians(), 1_f64.to_radians()), + }, + )) +} diff --git a/safe-stage/src/concrete_parts.rs b/safe-stage/src/concrete_parts.rs index 5d5e862..ae9b840 100644 --- a/safe-stage/src/concrete_parts.rs +++ b/safe-stage/src/concrete_parts.rs @@ -130,7 +130,7 @@ mod tests { } } impl Retract for TestRetract { - fn as_arc(&self) -> Arc + Send + Sync> { + fn as_movable(&self) -> Arc> { unreachable!() } } @@ -147,7 +147,7 @@ mod tests { } } impl Stage for TestStage { - fn as_arc(&self) -> Arc + Send + Sync> { + fn as_movable(&self) -> Arc> { unreachable!() } fn swap_holder(&mut self, _holder: Option>) { diff --git a/safe-stage/src/concrete_resolvers.rs b/safe-stage/src/concrete_resolvers.rs index d4151ae..a3732d8 100644 --- a/safe-stage/src/concrete_resolvers.rs +++ b/safe-stage/src/concrete_resolvers.rs @@ -66,21 +66,22 @@ concrete_resolver_impl!(ConcreteStageResolver, StagePathResolver); #[cfg(test)] mod tests { use super::*; + + use models::immovable::Immovable; + use models::movable::Movable; use models::position::linear::LinearState; use models::position::sixaxis::SixAxis; use paths::path::PathResult; - use paths::resolver::{DynamicImmovable, DynamicMovable, PathResolver, StateUpdateError}; + use paths::resolver::{PathResolver, StateUpdateError}; struct TestRetractResolver; impl RetractPathResolver for TestRetractResolver {} - impl PathResolver, DynamicImmovable> - for TestRetractResolver - { + impl PathResolver for TestRetractResolver { fn update_state( &mut self, _new: &LinearState, - _movable: &DynamicMovable, - _immovable: &DynamicImmovable, + _movable: &dyn Movable, + _immovable: &Immovable, ) -> Result<(), StateUpdateError> { unreachable!() } @@ -89,8 +90,8 @@ mod tests { &self, _from: &LinearState, _to: &LinearState, - _movable: &DynamicMovable, - _immovable: &DynamicImmovable, + _movable: &dyn Movable, + _immovable: &Immovable, ) -> PathResult { unreachable!() } @@ -103,12 +104,12 @@ mod tests { struct TestStageResolver; impl StagePathResolver for TestStageResolver {} - impl PathResolver, DynamicImmovable> for TestStageResolver { + impl PathResolver for TestStageResolver { fn update_state( &mut self, _new: &SixAxis, - _movable: &DynamicMovable, - _immovable: &DynamicImmovable, + _movable: &dyn Movable, + _immovable: &Immovable, ) -> Result<(), StateUpdateError> { unreachable!() } @@ -117,8 +118,8 @@ mod tests { &self, _from: &SixAxis, _to: &SixAxis, - _movable: &DynamicMovable, - _immovable: &DynamicImmovable, + _movable: &dyn Movable, + _immovable: &Immovable, ) -> PathResult { unreachable!() } diff --git a/safe-stage/src/microscope.rs b/safe-stage/src/microscope.rs index c65b69d..cef3eff 100644 --- a/safe-stage/src/microscope.rs +++ b/safe-stage/src/microscope.rs @@ -9,10 +9,12 @@ use crate::types::{CLinearState, CPathResultLinearState, CPathResultSixAxis, CSi use collisions::complex::group::ColliderGroup; use collisions::PrimaryCollider; use maths::Vector2; +use models::immovable::Immovable; +use models::movable::Movable; use models::position::linear::LinearState; use models::position::sixaxis::SixAxis; use models::sample::height_map::height_map_to_sample_model; -use paths::resolver::{DynamicImmovable, DynamicMovable, StateUpdateError as ResolverUpdateError}; +use paths::resolver::StateUpdateError as ResolverUpdateError; use std::collections::HashMap; use std::sync::Arc; use thiserror::Error; @@ -386,16 +388,15 @@ impl Microscope { } } - fn movable_stage(&self) -> DynamicMovable { - let movable = self.stage.get_ref().as_arc(); - DynamicMovable(movable) + fn movable_stage(&self) -> Arc> { + self.stage.get_ref().as_movable() } - fn movable_retract(&self, id: Id) -> Option> { + fn movable_retract(&self, id: Id) -> Option>> { self.retracts .inner() .get(&id) - .map(|(r, _, _)| DynamicMovable(r.get_ref().as_arc())) + .map(|(r, _, _)| r.get_ref().as_movable()) } fn add_equipment( @@ -413,30 +414,32 @@ impl Microscope { self.add_equipment(immovable) } - fn immovable_without_stage(&self) -> DynamicImmovable { + fn immovable_without_stage(&self) -> Immovable { let mut immovable = self.always_immovable(); for (r, _, s) in self.retracts.inner().values() { immovable.extend(r.get_ref().move_to(&s.into())); } - DynamicImmovable(Arc::new(immovable)) + immovable } /// Stage is considered the only relevant part for retracts - fn immovable_stage(&self) -> DynamicImmovable { + fn immovable_stage(&self) -> Immovable { let immovable = self .stage .get_ref() .move_to(&SixAxis::from(&self.stage_state)); - DynamicImmovable(Arc::new(immovable)) + immovable } fn update_stage_resolver_state(&mut self, state: &CSixAxis) -> Result<(), StateUpdateError> { let movable = self.movable_stage(); let immovable = self.immovable_without_stage(); - self.stage_resolver - .get_mut() - .update_state(&SixAxis::from(state), &movable, &immovable)?; + self.stage_resolver.get_mut().update_state( + &SixAxis::from(state), + movable.as_ref(), + &immovable, + )?; Ok(()) } @@ -454,7 +457,7 @@ impl Microscope { .unwrap() .1 .get_mut() - .update_state(&LinearState::from(state), &movable, &immovable)?; + .update_state(&LinearState::from(state), movable.as_ref(), &immovable)?; Ok(()) } @@ -498,7 +501,7 @@ impl Microscope { let result = self.stage_resolver.get_ref().resolve_path( &SixAxis::from(&from), &SixAxis::from(state), - &movable, + movable.as_ref(), &immovable, ); CPathResultSixAxis::from(result) @@ -511,7 +514,7 @@ impl Microscope { let result = self.retracts.inner()[&id].1.get_ref().resolve_path( &LinearState::from(&from), &LinearState::from(state), - &movable, + movable.as_ref(), &immovable, ); CPathResultLinearState::from(result)