diff --git a/.gitignore b/.gitignore index 63aca47b..3e582a4d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ *.dot screenshot_*.png +.bacon-locations diff --git a/config/formation.ron b/config/formation.ron index 8e977818..bbec9d5a 100644 --- a/config/formation.ron +++ b/config/formation.ron @@ -3,7 +3,7 @@ ( repeat: false, delay: 1.0, - robots: 2, + robots: 1, waypoints: [ ( shape: line((( diff --git a/gbpplanner-rs/src/planner/factorgraph.rs b/gbpplanner-rs/src/planner/factorgraph.rs index 8c33263a..579dcb65 100644 --- a/gbpplanner-rs/src/planner/factorgraph.rs +++ b/gbpplanner-rs/src/planner/factorgraph.rs @@ -5,7 +5,6 @@ use bevy::prelude::*; use gbp_linalg::{Float, Matrix, Vector}; // use itertools::Itertools; use ndarray::s; -use num_traits::Zero; use petgraph::Undirected; use crate::planner::message::{Eta, Lam, Mu}; @@ -777,6 +776,7 @@ impl FactorGraph { messages_to_external_variables } + // TODO: move into Factor struct fn update_factor(&mut self, factor_index: FactorIndex) -> MessagesToVariables { // TODO: do not hardcode let dofs = 4; @@ -898,17 +898,14 @@ impl FactorGraph { pub fn variable_iteration(&mut self) -> Vec { // TODO: calculate capacity beforehand let mut messages_to_external_factors: Vec = Vec::new(); - for node_index in self.graph.node_indices().collect::>() { + for &node_index in self.variable_indices.iter() { let node = &mut self.graph[node_index]; - if node.is_factor() { - continue; - } - let variable = node .as_variable_mut() - .expect("variable_index should point to a Variable in the graph"); + .expect("self.variable_indices should only contain indices that point to Variables in the graph"); let variable_index = VariableIndex(node_index); - let factor_messages = variable.update_belief_and_create_responses(); + + let factor_messages = variable.update_belief_and_create_factor_responses(); if factor_messages.is_empty() { panic!( "The factorgraph {:?} with variable {:?} did not receive any messages from its connected factors", @@ -922,17 +919,12 @@ impl FactorGraph { let in_internal_graph = factor_id.factorgraph_id == self.id; if in_internal_graph { // Send the messages to the connected factors within the same factorgraph - // dbg!(&factor_id); - // dbg!(&self); - println!( - "trying to access factor with id: {:?} in factorgraph {:?}", - factor_id, self.id - ); - let factor = self.graph[factor_id.factor_index.as_node_index()] + self.graph[factor_id.factor_index.as_node_index()] .as_factor_mut() - .expect("A factor can only have variables as neighbors"); - factor.send_message(variable_id, message); + .expect("A factor can only have variables as neighbours") + .send_message(variable_id, message); } else { + // Append to the list of messages to be sent to the connected factors in other factorgraphs messages_to_external_factors.push(VariableToFactorMessage { from: variable_id, to: factor_id, @@ -942,6 +934,8 @@ impl FactorGraph { } } + // Return the messages to be sent to the connected factors in other factorgraphs + // The caller is responsible for sending these messages to the correct factorgraphs messages_to_external_factors } @@ -949,12 +943,12 @@ impl FactorGraph { &mut self, variable_index: VariableIndex, new_mean: Vector, - ) -> Vec { + ) -> Vec { let variable_id = VariableId::new(self.id, variable_index); let variable = self.variable_mut(variable_id.variable_index); let factor_messages = variable.change_prior(new_mean); - let mut messages_to_external_factors: Vec = Vec::new(); + let mut messages_to_external_factors: Vec = Vec::new(); for (factor_id, message) in factor_messages { let in_internal_graph = factor_id.factorgraph_id == self.id; @@ -962,9 +956,9 @@ impl FactorGraph { let factor = self.factor_mut(factor_id.factor_index); factor.send_message(variable_id, message); } else { - messages_to_external_factors.push(FactorToVariableMessage { - from: factor_id, - to: variable_id, + messages_to_external_factors.push(VariableToFactorMessage { + from: variable_id, + to: factor_id, message, }); } @@ -1048,63 +1042,4 @@ impl FactorGraph { println!("after {:?}", variable.inbox.keys().collect::>()); } } - - // fn adjacent_variables(&self, factor_index: FactorIndex) -> AdjacentVariables<'_> { - // AdjacentVariables::new(&self.graph, factor_index) - // } - - // /// TODO: should probably not be a method on the graph, but on the robot, but whatever - // pub(crate) fn delete_interrobot_factor_connected_to( - // &mut self, - // other: RobotId, - // ) -> Result<(), &'static str> { - // let node_idx = self - // .graph - // .node_indices() - // .filter_map(|node_idx| { - // let node = &self.graph[node_idx]; - // let Some(factor) = node.as_factor() else { - // return None; - // }; - - // let Some(interrobot) = factor.kind.as_inter_robot() else { - // return None; - // }; - - // Some((node_idx, interrobot)) - // }) - // .find(|(_, interrobot)| interrobot.id_of_robot_connected_with == other) - // .map(|(node_idx, _)| node_idx); - - // let Some(node_idx) = node_idx else { - // return Err("not found"); - // }; - - // self.graph.remove_node(node_idx).expect( - // "The node index was retrieved from the graph in the previous statement", - // ); - - // Ok(()) - - // // let node_idx = self - // // .graph - // // .raw_nodes() - // // .iter() - // // .filter_map(|node| node.weight.as_factor()) - // // .filter_map(|factor| factor.kind.as_inter_robot()) - // // .find(|&interrobot| interrobot.id_of_robot_connected_with == other) - // // .ok_or("not found")?; - // } - - // fn update_variable( - // &mut self, - // variable_index: NodeIndex, - // indices_of_adjacent_factors: Vec, - // ) -> HashMap { - // let adjacent_factors = self.graph.neighbors(variable_index); - // // // Update variable belief and create outgoing messages - // // variable.update_belief(&adjacent_factors, &mut self.graph); - - // todo!() - // } } diff --git a/gbpplanner-rs/src/planner/robot.rs b/gbpplanner-rs/src/planner/robot.rs index 45bd6440..491ec5cf 100644 --- a/gbpplanner-rs/src/planner/robot.rs +++ b/gbpplanner-rs/src/planner/robot.rs @@ -49,13 +49,13 @@ impl Plugin for RobotPlugin { // FixedUpdate, Update, ( - update_robot_neighbours_system, - delete_interrobot_factors_system, - create_interrobot_factors_system, - update_failed_comms_system, - iterate_gbp_system, - update_prior_of_horizon_state_system, - update_prior_of_current_state_system, + update_robot_neighbours, + delete_interrobot_factors, + create_interrobot_factors, + update_failed_comms, + iterate_gbp, + update_prior_of_horizon_state, + update_prior_of_current_state, ) .chain() .run_if(time_is_not_paused), @@ -292,7 +292,7 @@ impl RobotBundle { } /// Called `Simulator::calculateRobotNeighbours` in **gbpplanner** -fn update_robot_neighbours_system( +fn update_robot_neighbours( // query: Query<(Entity, &Transform, &mut RobotState)>, robots: Query<(Entity, &Transform), With>, mut states: Query<(Entity, &Transform, &mut RobotState)>, @@ -319,13 +319,10 @@ fn update_robot_neighbours_system( } }) .collect(); - // .for_each(|other_entity_id| { - // state.ids_of_robots_within_comms_range.push(other_entity_id) - // }); } } -fn delete_interrobot_factors_system(mut query: Query<(Entity, &mut FactorGraph, &mut RobotState)>) { +fn delete_interrobot_factors(mut query: Query<(Entity, &mut FactorGraph, &mut RobotState)>) { // the set of robots connected with will (possibly) be mutated // the robots factorgraph will (possibly) be mutated // the other robot with an interrobot factor connected will be mutated @@ -350,7 +347,7 @@ fn delete_interrobot_factors_system(mut query: Query<(Entity, &mut FactorGraph, } } - dbg!(&robots_to_delete_interrobot_factors_between); + // dbg!(&robots_to_delete_interrobot_factors_between); for (robot1, robot2) in robots_to_delete_interrobot_factors_between { // Will delete both interrobot factors as, @@ -392,7 +389,7 @@ fn delete_interrobot_factors_system(mut query: Query<(Entity, &mut FactorGraph, } } -fn create_interrobot_factors_system( +fn create_interrobot_factors( mut query: Query<(Entity, &mut FactorGraph, &mut RobotState)>, config: Res, variable_timesteps: Res, @@ -510,14 +507,14 @@ fn create_interrobot_factors_system( } /// Called `Simulator::setCommsFailure` in **gbpplanner** -fn update_failed_comms_system(mut query: Query<&mut RobotState>, config: Res) { +fn update_failed_comms(mut query: Query<&mut RobotState>, config: Res) { for mut state in query.iter_mut() { state.interrobot_comms_active = config.robot.communication.failure_rate > rand::random::(); } } -fn iterate_gbp_system(mut query: Query<(Entity, &mut FactorGraph), With>) { +fn iterate_gbp(mut query: Query<(Entity, &mut FactorGraph), With>) { let messages_to_external_variables = query .iter_mut() .map(|(robot_id, mut factorgraph)| factorgraph.factor_iteration()) @@ -530,25 +527,11 @@ fn iterate_gbp_system(mut query: Query<(Entity, &mut FactorGraph), With>) { -// let mode = MessagePassingMode::Internal; -// -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.factor_iteration(robot_id, mode); -// } -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.variable_iteration(robot_id, mode); -// } -// } -// -// fn iterate_gbp_external_system(mut query: Query<(Entity, &mut FactorGraph), With>) { -// let mode = MessagePassingMode::External; -// -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.factor_iteration(robot_id, mode); -// } -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.variable_iteration(robot_id, mode); -// } -// } -// -// pub fn iterate_gbp_internal_system( -// mut query: Query<(Entity, &mut FactorGraph), With>, -// config: Res, -// ) { -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.variable_iteration(robot_id, MessagePassingMode::Internal); -// } -// -// for (robot_id, mut factorgraph) in query.iter_mut() { -// factorgraph.factor_iteration(robot_id, MessagePassingMode::Internal); -// } -// -// // query -// // .par_iter_mut() -// // .for_each(|(robot_id, mut factorgraph)| { -// // factorgraph.variable_iteration(robot_id, MessagePassingMode::Internal); -// // }); -// // query -// // .par_iter_mut() -// // .for_each(|(robot_id, mut factorgraph)| { -// // factorgraph.factor_iteration(robot_id, MessagePassingMode::Internal); -// // }); -// } - -// iterate_gbp_impl!(iterate_gbp_internal_system, MessagePassingMode::Internal); -// iterate_gbp_impl!(iterate_gbp_external_system, MessagePassingMode::External); - -// fn iterate_gbp_system( -// mut query: Query<(Entity, &mut FactorGraph), With>, -// config: Res, -// ) { - -// query.par_iter_mut().for_each(|(robot_id, mut factorgraph)| { -// factorgraph.factor_iteration(robot_id, MessagePassingMode::Internal); -// }); -// query.par_iter_mut().for_each(|(robot_id, mut factorgraph)| { -// factorgraph.variable_iteration(robot_id, MessagePassingMode::Internal); -// }); -// // for (robot_id, mut factorgraph) in query.par_iter_mut() { -// // factorgraph.factor_iteration(robot_id, MessagePassingMode::Internal); -// // } -// // for (robot_id, mut factorgraph) in query.iter_mut() { -// // factorgraph.variable_iteration(robot_id, MessagePassingMode::Internal); -// // } -// } - -// fn iterate_gbp(query: Query<&mut FactorGraph>, config: Res) {} - /// Called `Robot::updateHorizon` in **gbpplanner** -fn update_prior_of_horizon_state_system( +fn update_prior_of_horizon_state( mut query: Query<(Entity, &mut FactorGraph, &mut Waypoints), With>, config: Res, time: Res