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

Add support for spawning robots in locations #123

Closed
wants to merge 3 commits into from
Closed
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
62 changes: 62 additions & 0 deletions rmf_site_editor/src/site/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use bevy::prelude::*;
// experience z-fighting.
const LOCATION_LAYER_HEIGHT: f32 = LANE_LAYER_LIMIT + SELECTED_LANE_OFFSET / 2.0;

#[derive(Component, Debug, Clone)]
pub struct LocationRobotModel(Entity);

// TODO(MXG): Refactor this implementation with should_display_lane using traits and generics
fn should_display_point(
point: &Point<Entity>,
Expand Down Expand Up @@ -86,6 +89,65 @@ pub fn add_location_visuals(
}
}

pub fn add_robot_to_spawn_location(
mut commands: Commands,
locations: Query<
(
Entity,
&Point<Entity>,
&LocationTags,
Option<&LocationRobotModel>,
),
Changed<LocationTags>,
>,
levels: Query<(), With<LevelProperties>>,
mut models: Query<(&mut NameInSite, &mut AssetSource), With<ModelMarker>>,
anchors: AnchorParams,
parents: Query<&Parent>,
) {
for (e, point, location_tags, location_model) in &locations {
let position = anchors
.point_in_parent_frame_of(point.0, Category::Location, e)
.unwrap();

let parent = AncestorIter::new(&parents, point.0).find(|p| levels.get(*p).is_ok());

if let Some(parent) = parent {
if let Some(m) = location_tags.iter().find_map(|l| match l {
LocationTag::SpawnRobot(m) => Some(m),
_ => None,
}) {
if let Some(location_model) = location_model {
// Update existing model
if let Ok((mut name, mut source)) = models.get_mut(location_model.0) {
*name = m.name.clone();
*source = m.source.clone();
}
} else {
// Spawn new model
let mut model = m.clone();
model.pose = Pose {
trans: position.into(),
..default()
};
// TODO(luca) there should be a marker component to denote this is a robot
// as well as set it non static
// Robots should probably be made non deletable, since their spawning is
// controlled by the location property
let child = commands.spawn(model).id();
commands.entity(parent).push_children(&[child]);
commands.entity(e).insert(LocationRobotModel(child));
}
} else {
if let Some(location_model) = location_model {
commands.entity(location_model.0).despawn_recursive();
commands.entity(e).remove::<LocationRobotModel>();
}
}
}
}
}

pub fn update_changed_location(
mut locations: Query<
(
Expand Down
1 change: 1 addition & 0 deletions rmf_site_editor/src/site/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl Plugin for SitePlugin {
.with_system(update_floor_visibility)
.with_system(add_lane_visuals)
.with_system(add_location_visuals)
.with_system(add_robot_to_spawn_location)
.with_system(update_level_visibility)
.with_system(update_changed_lane)
.with_system(update_lane_for_moved_anchor)
Expand Down
11 changes: 8 additions & 3 deletions rmf_site_editor/src/site/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,10 @@ pub fn update_model_scenes(

pub fn update_model_tentative_formats(
mut commands: Commands,
changed_models: Query<Entity, (Changed<AssetSource>, With<ModelMarker>)>,
changed_models: Query<
(Entity, &AssetSource, Option<&ModelScene>),
(Changed<AssetSource>, With<ModelMarker>),
>,
mut loading_models: Query<
(
Entity,
Expand All @@ -272,9 +275,11 @@ pub fn update_model_tentative_formats(
>,
asset_server: Res<AssetServer>,
) {
for e in changed_models.iter() {
for (e, source, scene) in changed_models.iter() {
// Reset to the first format
commands.entity(e).insert(TentativeModelFormat::default());
if !scene.is_some_and(|r| &r.source == source) {
commands.entity(e).insert(TentativeModelFormat::default());
}
}
// Check from the asset server if any format failed, if it did try the next
for (e, mut tentative_format, h, source) in loading_models.iter_mut() {
Expand Down
2 changes: 1 addition & 1 deletion rmf_site_format/src/legacy/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Vertex {
if !me.spawn_robot_name.is_empty() && !me.spawn_robot_type.is_empty() {
tags.push(LocationTag::SpawnRobot(Model {
name: NameInSite(me.spawn_robot_name.1.clone()),
source: AssetSource::Search(me.spawn_robot_type.1.clone()),
source: AssetSource::Search("OpenRobotics/".to_string() + &me.spawn_robot_type.1),
pose: Pose::default(),
is_static: IsStatic(false),
constraints: ConstraintDependents::default(),
Expand Down