From 73574bf57c7771d1a7fa6c986747ccdd20dcacbc Mon Sep 17 00:00:00 2001 From: kpbaks Date: Mon, 3 Jun 2024 22:17:20 +0200 Subject: [PATCH 1/4] feat(experiments): run alot --- Cargo.lock | 2 +- .../config.toml | 10 +- .../config.toml | 2 +- .../formation.yaml | 2 +- .../Iteration Amount Experiment/config.toml | 133 ++++++++++-------- .../Schedules Experiment/config.toml | 6 +- config/simulations/Solo GP/config.toml | 44 +++--- .../config.toml | 6 +- crates/gbp_global_planner/src/lib.rs | 4 +- crates/gbp_global_planner/src/rrtstar.rs | 2 + scripts/run-collaborative-gp-experiment.fish | 101 ++++--------- ...run-communication-failure-expertiment.fish | 12 +- .../run-environment-obstacles-experiment.fish | 3 +- scripts/run-iteration-amount-experiment.fish | 33 ++++- scripts/run-schedules-experiment.fish | 2 +- scripts/run-solo-gp-experiment.fish | 3 +- ...rying-network-connectivity-experiment.fish | 4 +- 17 files changed, 187 insertions(+), 182 deletions(-) mode change 100644 => 100755 scripts/run-collaborative-gp-experiment.fish diff --git a/Cargo.lock b/Cargo.lock index fdb4818e..21b16306 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6030,7 +6030,7 @@ checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "rrt" version = "0.7.0" -source = "git+https://github.com/AU-Master-Thesis/rrt?branch=main#d4384c7ef96cde507f893d8953ce053659483f85" +source = "git+https://github.com/AU-Master-Thesis/rrt?branch=main#ad5911f51d6b85376518b8922cb53d2a66c8bd09" dependencies = [ "derive_more", "kdtree", diff --git a/config/simulations/Communications Failure Experiment/config.toml b/config/simulations/Communications Failure Experiment/config.toml index bd99fb22..bf9ba199 100644 --- a/config/simulations/Communications Failure Experiment/config.toml +++ b/config/simulations/Communications Failure Experiment/config.toml @@ -9,7 +9,7 @@ height-map = 1.0 [visualisation.draw] robots = true communication-graph = false -predicted-trajectories = true +predicted-trajectories = false waypoints = false uncertainty = false paths = false @@ -58,9 +58,9 @@ obstacle = true tracking = false [robot] -planning-horizon = 13.33 +planning-horizon = 13.329999923706055 target-speed = 15.0 -inter-robot-safety-distance-multiplier = 2.2 +inter-robot-safety-distance-multiplier = 2.200000047683716 [robot.radius] min = 2.0 @@ -68,14 +68,14 @@ max = 3.0 [robot.communication] radius = 50.0 -failure-rate = 0.7 +failure-rate = 0.3 [simulation] max-time = 10000.0 time-scale = 1.0 manual-step-factor = 1 hz = 10.0 -prng-seed = 805 +prng-seed = 0 pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true exit-application-on-scenario-finished = true diff --git a/config/simulations/Environment Obstacles Experiment/config.toml b/config/simulations/Environment Obstacles Experiment/config.toml index 1acd1637..ca8a9131 100644 --- a/config/simulations/Environment Obstacles Experiment/config.toml +++ b/config/simulations/Environment Obstacles Experiment/config.toml @@ -70,7 +70,7 @@ time-scale = 1.0 manual-step-factor = 1 hz = 10.0 # world-size = 100.0 -prng-seed = 805 +prng-seed = 805 pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true exit-application-on-scenario-finished = true diff --git a/config/simulations/Environment Obstacles Experiment/formation.yaml b/config/simulations/Environment Obstacles Experiment/formation.yaml index cfe15390..b3f5b29b 100644 --- a/config/simulations/Environment Obstacles Experiment/formation.yaml +++ b/config/simulations/Environment Obstacles Experiment/formation.yaml @@ -7,7 +7,7 @@ formations: delay: secs: 1 nanos: 0 - robots: 50 + robots: 50 planning-strategy: only-local initial-position: shape: !circle diff --git a/config/simulations/Iteration Amount Experiment/config.toml b/config/simulations/Iteration Amount Experiment/config.toml index fd83d2a6..03fc5a65 100644 --- a/config/simulations/Iteration Amount Experiment/config.toml +++ b/config/simulations/Iteration Amount Experiment/config.toml @@ -1,60 +1,65 @@ -# environment = "junction" environment_image = "empty" -environment = "./config/simulations/ClearCircle/environment.yaml" -formation_group = "./config/simulations/ClearCircle/formation.ron" - -[interaction] -ui-focus-cancels-inputs = true -default-cam-distance = 150.0 - -[visualisation.uncertainty] -max-radius = 2.5 -scale = 300.0 +environment = "./config/simulations/ClearCircle/environment.yaml" +formation_group = "./config/simulations/ClearCircle/formation.ron" [visualisation.height] -objects = 0.5 +objects = 0.5 height-map = 1.0 [visualisation.draw] -robots = true -communication-graph = false -predicted-trajectories = false -waypoints = false -uncertainty = false -paths = false -generated-map = true -height-map = false -sdf = false -communication-radius = false -obstacle-factors = false -tracking = false -interrobot-factors = false +robots = true +communication-graph = false +predicted-trajectories = false +waypoints = false +uncertainty = false +paths = false +communication-radius = false +obstacle-factors = false +tracking = false +interrobot-factors = false interrobot-factors-safety-distance = false -robot-colliders = false -environment-colliders = false -robot-robot-collisions = true -robot-environment-collisions = false +generated-map = true +sdf = false +robot-colliders = false +environment-colliders = false +robot-robot-collisions = false +robot-environment-collisions = false + +[visualisation.uncertainty] +max-radius = 2.5 +scale = 300.0 + +[interaction] +ui-focus-cancels-inputs = true +default-cam-distance = 150.0 [gbp] -sigma-pose-fixed = 1e-15 -sigma-factor-dynamics = 1.0 -sigma-factor-interrobot = 0.005 -sigma-factor-obstacle = 0.005 -sigma-factor-tracking = 0.1 -# iterations-per-timestep = 10 +sigma-pose-fixed = 0.0000000000000010000000036274937 +sigma-factor-dynamics = 1.0 +sigma-factor-interrobot = 0.004999999888241291 +sigma-factor-obstacle = 0.004999999888241291 +sigma-factor-tracking = 0.10000000149011612 lookahead-multiple = 3 +variables = 10 + +[gbp.tracking] +switch-padding = 1.0 +attraction-distance = 2.0 + [gbp.iteration-schedule] -internal = 30 -external = 30 +internal = 1 +external = 1 schedule = "interleave-evenly" +[gbp.factors-enabled] +dynamic = true +interrobot = true +obstacle = true +tracking = false + [robot] -# planning-horizon = 13.33 # 2r / initial speed -# planning-horizon = 12.4 # 2r / initial speed -planning-horizon = 7 -# planning-horizon = 10 -# planning-horizon = 6.677 # 2r / initial speed -target-speed = 10.0 +planning-horizon = 5.0 +target-speed = 10.0 inter-robot-safety-distance-multiplier = 2.5 [robot.radius] @@ -62,44 +67,50 @@ min = 2.0 max = 3.0 [robot.communication] -radius = 50.0 +radius = 50.0 failure-rate = 0.0 [simulation] -# t0 = 0.25 -max-time = 10000.0 -time-scale = 1.0 +max-time = 10000.0 +time-scale = 2.200000047683716 manual-step-factor = 1 -hz = 10.0 -# world-size = 100.0 -prng-seed = 0 -pause-on-spawn = false +hz = 10.0 +prng-seed = 227 +pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true -exit-application-on-scenario-finished = true +exit-application-on-scenario-finished = true [rrt] -max-iterations = 1000000 -step-size = 0.5 -collision-radius = 0.1 +max-iterations = 1000000 +step-size = 0.5 +collision-radius = 0.10000000149011612 neighbourhood-radius = 10.0 -# [rrt.smoothing] -# max-iterations = 500 -# step-size = 0.5 +[rrt.smoothing] +enabled = true +max-iterations = 100 +step-size = 1.0 [graphviz] export-location = "./assets/export/" [graphviz.interrobot.active] style = "dashed" -len = 8.0 +len = 8.0 color = "red" [graphviz.interrobot.inactive] style = "dashed" -len = 8.0 +len = 8.0 color = "gray" - [manual] timesteps-per-step = 1 + +[debug.on-variable-clicked] +obstacle = false +dynamic = false +interrobot = false +tracking = false +variable = false +inbox = false diff --git a/config/simulations/Schedules Experiment/config.toml b/config/simulations/Schedules Experiment/config.toml index bb08fe43..66bdedf4 100644 --- a/config/simulations/Schedules Experiment/config.toml +++ b/config/simulations/Schedules Experiment/config.toml @@ -45,8 +45,8 @@ sigma-factor-tracking = 0.1 lookahead-multiple = 3 [gbp.iteration-schedule] internal = 50 -external = 25 -schedule = 'half-beginning-half-end' +external = 20 +schedule = 'centered' [robot] # planning-horizon = 13.33 # 2r / initial speed @@ -72,7 +72,7 @@ time-scale = 1.0 manual-step-factor = 1 hz = 10.0 # world-size = 100.0 -prng-seed = 0 +prng-seed = 31 pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true exit-application-on-scenario-finished = true diff --git a/config/simulations/Solo GP/config.toml b/config/simulations/Solo GP/config.toml index aac7141a..2f9fad3d 100644 --- a/config/simulations/Solo GP/config.toml +++ b/config/simulations/Solo GP/config.toml @@ -2,14 +2,6 @@ environment_image = "junction_twoway" environment = "./config/simulations/Solo GP/environment.yaml" formation_group = "./config/simulations/Solo GP/formation.ron" -[interaction] -ui-focus-cancels-inputs = true -default-cam-distance = 300.0 - -[visualisation.uncertainty] -max-radius = 2.5 -scale = 300.0 - [visualisation.height] objects = 0.5 height-map = 2.0 @@ -21,26 +13,32 @@ predicted-trajectories = true waypoints = true uncertainty = false paths = true -height-map = false -sdf = false communication-radius = false obstacle-factors = false -tracking = false +tracking = true interrobot-factors = false interrobot-factors-safety-distance = false generated-map = true +sdf = false robot-colliders = false environment-colliders = false robot-robot-collisions = true robot-environment-collisions = true +[visualisation.uncertainty] +max-radius = 2.5 +scale = 300.0 + +[interaction] +ui-focus-cancels-inputs = true +default-cam-distance = 300.0 [gbp] -sigma-pose-fixed = 1e-15 -sigma-factor-dynamics = 0.2 -sigma-factor-interrobot = 0.01 -sigma-factor-obstacle = 0.01 -sigma-factor-tracking = 0.15 +sigma-pose-fixed = 0.0000000000000010000000036274937 +sigma-factor-dynamics = 0.10000000149011612 +sigma-factor-interrobot = 0.009999999776482582 +sigma-factor-obstacle = 0.009999999776482582 +sigma-factor-tracking = 0.15000000596046448 lookahead-multiple = 3 variables = 10 @@ -57,12 +55,12 @@ schedule = "interleave-evenly" dynamic = true interrobot = true obstacle = true -tracking = true +tracking = true [robot] planning-horizon = 5.0 target-speed = 7.0 -inter-robot-safety-distance-multiplier = 3.2 +inter-robot-safety-distance-multiplier = 3.200000047683716 [robot.radius] min = 2.0 @@ -74,13 +72,13 @@ failure-rate = 0.0 [simulation] max-time = 10000.0 -time-scale = 1.0 +time-scale = 10.0 manual-step-factor = 1 hz = 10.0 -prng-seed = 0 -pause-on-spawn = true +prng-seed = 805 +pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true -exit-application-on-scenario-finished = false +exit-application-on-scenario-finished = true [rrt] max-iterations = 5000000 @@ -113,6 +111,6 @@ timesteps-per-step = 1 obstacle = false dynamic = false interrobot = false +tracking = true variable = false -tracking = false inbox = true diff --git a/config/simulations/Varying Network Connectivity Experiment/config.toml b/config/simulations/Varying Network Connectivity Experiment/config.toml index fd18b1db..d0589766 100644 --- a/config/simulations/Varying Network Connectivity Experiment/config.toml +++ b/config/simulations/Varying Network Connectivity Experiment/config.toml @@ -51,14 +51,14 @@ schedule = "interleave-evenly" # planning-horizon = 7.0 planning-horizon = 13.33 target-speed = 15.0 -inter-robot-safety-distance-multiplier = 2.5 +inter-robot-safety-distance-multiplier = 2.2 [robot.radius] min = 2.0 max = 3.0 [robot.communication] -radius = 80.0 +radius = 80.0 failure-rate = 0.0 [simulation] @@ -68,7 +68,7 @@ time-scale = 1.0 manual-step-factor = 1 hz = 10.0 # world-size = 100.0 -prng-seed = 805 +prng-seed = 805 pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true exit-application-on-scenario-finished = true diff --git a/crates/gbp_global_planner/src/lib.rs b/crates/gbp_global_planner/src/lib.rs index 244d7eee..58d93849 100644 --- a/crates/gbp_global_planner/src/lib.rs +++ b/crates/gbp_global_planner/src/lib.rs @@ -177,9 +177,9 @@ impl CollisionProblem { !intersecting } - fn random_sample(&self, rng: &mut dyn RngCore) -> Vec { + fn random_sample(&self, mut rng: &mut dyn RngCore) -> Vec { let between = Uniform::new(-2000.0, 2000.0); - let mut rng = rng; + // let mut rng = rng; vec![between.sample(&mut rng), between.sample(&mut rng)] } } diff --git a/crates/gbp_global_planner/src/rrtstar.rs b/crates/gbp_global_planner/src/rrtstar.rs index 84d21a39..0949120e 100644 --- a/crates/gbp_global_planner/src/rrtstar.rs +++ b/crates/gbp_global_planner/src/rrtstar.rs @@ -59,6 +59,7 @@ pub fn spawn_pathfinding_task( |x| collision_solver.is_feasible(x), rrt_params.step_size.get() as f64, rrt_params.smoothing.max_iterations.get(), + &mut *rng_source, ); } resulting_path @@ -131,6 +132,7 @@ pub fn spawn_pathfinding_task_full_tree( |x| collision_solver.is_feasible(x), rrt_params.step_size.get() as f64, rrt_params.smoothing.max_iterations.get(), + &mut *rng_source, ); } resulting_path diff --git a/scripts/run-collaborative-gp-experiment.fish b/scripts/run-collaborative-gp-experiment.fish old mode 100644 new mode 100755 index c729d6db..e7e0b194 --- a/scripts/run-collaborative-gp-experiment.fish +++ b/scripts/run-collaborative-gp-experiment.fish @@ -12,7 +12,7 @@ set -l seeds 0 31 227 252 805 # --- Low Qin --- -set -l experiment "Collaborative GP Low Qin" +set -l experiment "Collaborative GP" set -l config_file "config/simulations/$experiment/config.toml" set -l formation_file "config/simulations/$experiment/formation.yaml" @@ -30,88 +30,43 @@ set -l t_start (date "+%s") printf '%sinfo%s: starting experiment\n' (set_color green) (set_color normal) >&2 -#for qin in 1 2 -# # FIXME: calculate properly -# yq eval '.formations[].repeat.every.secs = 20' --inplace $formation_file -# yq eval '.formations[].repeat.every.nanos = 20' --inplace $formation_file - for seed in $seeds sed --regexp-extended "s/prng-seed\s*=\s*([0-9]+)/prng-seed = $seed/" -i $config_file for tracking in false true sed --regexp-extended "s/tracking\s*=\s*(.*)/tracking = $tracking/" -i $config_file - - printf '%sinfo%s: testing seed: %d, tracking: %s\n' (set_color green) (set_color normal) $seed $tracking >&2 - - set -l output_file experiments/collaborative-gp-low-qin/tracking-$tracking-seed-$seed.json - - set -l t_end (date "+%s") - set -l t_diff (math "$t_end - $t_start") - if functions -q peopletime - printf '%sinfo%s: time elapsed: \n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 + set -l sigmas + if test $tracking = true + set sigmas 0.15 0.5 + else + set sigmas 0.15 end - if test -f $output_file - if not set -q _flag_force - printf '%swarn%s: %s already exists, use -f or --force to overwrite\n' (set_color yellow) (set_color normal) $output_file >&2 - continue - else - printf '%sinfo%s: overwriting %s\n' (set_color green) (set_color normal) $output_file >&2 - end - end - - RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null - set -l exported_json (printf '%s\n' export_collaborative\ gp\ low\ qin\ experiment*.json | tail -n 1) - set -l dirname (path dirname "$output_file") - command mkdir -p "$dirname" - mv "$exported_json" "$output_file" - end -end - - -# --- High Qin --- - -set -l experiment "Collaborative GP High Qin" -set -l config_file "config/simulations/$experiment/config.toml" -set -l formation_file "config/simulations/$experiment/formation.yaml" - -if not test -f $config_file - printf '%serror%s: %s does not exist!\n' (set_color red) (set_color normal) $config_file >&2 - exit 1 -end - -if not test -f $formation_file - printf '%serror%s: %s does not exist!\n' (set_color red) (set_color normal) $formation_file >&2 - exit 1 -end + for sigma_tracking in $sigmas + sed --regexp-extended "s/sigma-factor-tracking\s*=\s*(.*)/sigma-factor-tracking = $sigma_tracking/" -i $config_file + printf '%sinfo%s: testing seed: %d, tracking: %s, sigma-tracking: %s\n' (set_color green) (set_color normal) $seed $tracking $sigma_tracking >&2 -for seed in $seeds - sed --regexp-extended "s/prng-seed\s*=\s*([0-9]+)/prng-seed = $seed/" -i $config_file - for tracking in false true - sed --regexp-extended "s/tracking\s*=\s*(.*)/tracking = $tracking/" -i $config_file - - printf '%sinfo%s: testing seed: %d, tracking: %s\n' (set_color green) (set_color normal) $seed $tracking >&2 - - set -l output_file experiments/collaborative-gp-high-qin/tracking-$tracking-seed-$seed.json + set -l output_file experiments/collaborative-gp/tracking-$tracking-sigma-tracking-$sigma_tracking-seed-$seed.json - set -l t_end (date "+%s") - set -l t_diff (math "$t_end - $t_start") - if functions -q peopletime - printf '%sinfo%s: time elapsed: \n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 - end + set -l t_end (date "+%s") + set -l t_diff (math "$t_end - $t_start") + if functions -q peopletime + printf '%sinfo%s: time elapsed: \n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 + end - if test -f $output_file - if not set -q _flag_force - printf '%swarn%s: %s already exists, use -f or --force to overwrite\n' (set_color yellow) (set_color normal) $output_file >&2 - continue - else - printf '%sinfo%s: overwriting %s\n' (set_color green) (set_color normal) $output_file >&2 + if test -f $output_file + if not set -q _flag_force + printf '%swarn%s: %s already exists, use -f or --force to overwrite\n' (set_color yellow) (set_color normal) $output_file >&2 + continue + else + printf '%sinfo%s: overwriting %s\n' (set_color green) (set_color normal) $output_file >&2 + end end - end - RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null - set -l exported_json (printf '%s\n' export_collaborative\ gp\ high\ qin\ experiment*.json | tail -n 1) - set -l dirname (path dirname "$output_file") - command mkdir -p "$dirname" - mv "$exported_json" "$output_file" + RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null + set -l exported_json (printf '%s\n' export_collaborative\ gp*.json | tail -n 1) + set -l dirname (path dirname "$output_file") + command mkdir -p "$dirname" + mv "$exported_json" "$output_file" + end end end diff --git a/scripts/run-communication-failure-expertiment.fish b/scripts/run-communication-failure-expertiment.fish index 165fef56..e6204780 100755 --- a/scripts/run-communication-failure-expertiment.fish +++ b/scripts/run-communication-failure-expertiment.fish @@ -3,6 +3,16 @@ argparse f/force -- $argv; or exit 2 +set -l reset (set_color normal) +set -l bold (set_color --bold) +set -l italics (set_color --italics) +set -l red (set_color red) +set -l green (set_color green) +set -l yellow (set_color yellow) +set -l blue (set_color blue) +set -l cyan (set_color cyan) +set -l magenta (set_color magenta) + function run echo $argv | fish_indent --ansi eval $argv @@ -28,7 +38,7 @@ for seed in 0 31 227 252 805 seq 0.0 0.1 0.7 | string replace ',' '.' | while read failure_probability sed --regexp-extended "s/failure-rate\s*=\s*(.*)/failure-rate = $failure_probability/" -i $config_file printf '%sinfo%s: seed=%d v0=%d failure-probability=%s\n' (set_color green) (set_color normal) $seed $v0 $failure_probability >&2 - set -l output_file experiments/communications-failure/v0-$v0-failure-$failure_probability-seed-$seed.json + set -l output_file experiments/communications-failure-lm-3-tk-13.33/v0-$v0-failure-$failure_probability-lm-3-tk-13.33-seed-$seed.json set -l t_end (date "+%s") set -l t_diff (math "$t_end - $t_start") diff --git a/scripts/run-environment-obstacles-experiment.fish b/scripts/run-environment-obstacles-experiment.fish index 785ff1d6..21f6a0f0 100755 --- a/scripts/run-environment-obstacles-experiment.fish +++ b/scripts/run-environment-obstacles-experiment.fish @@ -37,6 +37,7 @@ for seed in 0 31 227 252 805 for num_robots in (seq 5 5 50) # sed --regexp-extended "s/robots:\s+(\d+)/robots: $num_robots/" -i $formation_file sed "s/\(\s*robots:\s*\)[0-9]\+/\1 $num_robots/" -i $formation_file + # sed --regexp-extended "s/robots\s*=\s*[0-9]+/robots = $num_robots" - printf '%sinfo%s: changed num-robots to: %d\n' $green $reset $num_robots >&2 set -l output_file experiments/environment-obstacles/num-robots-$num_robots-seed-$seed.json @@ -44,7 +45,7 @@ for seed in 0 31 227 252 805 set -l t_end (date "+%s") set -l t_diff (math "$t_end - $t_start") if functions -q peopletime - printf '%sinfo%s: time elapsed: \n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 + printf '%sinfo%s: time elapsed: %s\n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 end if test -f $output_file diff --git a/scripts/run-iteration-amount-experiment.fish b/scripts/run-iteration-amount-experiment.fish index fb178664..a8ee58b8 100755 --- a/scripts/run-iteration-amount-experiment.fish +++ b/scripts/run-iteration-amount-experiment.fish @@ -15,15 +15,41 @@ if not test -f $config_file exit 1 end +#function fib -a n +# if test $n -eq 0 +# echo 0 +# else if test $n -eq 1 +# echo 1 +# else +# set -l a (fib (math "$n - 1")) +# set -l b (fib (math "$n - 2")) +# math "$a + $b" +# end +#end + +function fib -a n + set -l a 0 + set -l b 1 + for i in (seq 1 $n) + echo $a + set -l temp $b + set b (math "$a + $b") + set a $temp + end +end + set -l t_start (date "+%s") printf '%sinfo%s: starting experiment\n' (set_color green) (set_color normal) >&2 -for seed in 0 +set -l internals (fib 10 | tail +3) +set -l externals (fib 10 | tail +3) + +for seed in 0 31 227 252 805 sed --regexp-extended "s/prng-seed\s*=\s*([0-9]+)/prng-seed = $seed/" -i $config_file - for internal in (seq 5 5 30) + for internal in $internals sed --regexp-extended "s/internal\s*=\s*(.*)/internal = $internal/" -i $config_file - for external in (seq 5 5 30) + for external in $externals sed --regexp-extended "s/external\s*=\s*(.*)/external = $external/" -i $config_file printf '%sinfo%s: testing seed: %d, internal: %s, external: %d\n' (set_color green) (set_color normal) $seed $internal $external >&2 @@ -50,6 +76,7 @@ for seed in 0 set -l dirname (path dirname "$output_file") command mkdir -p "$dirname" mv "$exported_json" "$output_file" + end end end diff --git a/scripts/run-schedules-experiment.fish b/scripts/run-schedules-experiment.fish index 757c9d2d..8c64f1e8 100755 --- a/scripts/run-schedules-experiment.fish +++ b/scripts/run-schedules-experiment.fish @@ -23,7 +23,7 @@ printf '%sinfo%s: starting experiment\n' (set_color green) (set_color normal) >& set -l internal 50 -for seed in 0 +for seed in 0 31 227 252 805 sed --regexp-extended "s/prng-seed\s*=\s*([0-9]+)/prng-seed = $seed/" -i $config_file for schedule in interleave-evenly soon-as-possible late-as-possible centered half-beginning-half-end diff --git a/scripts/run-solo-gp-experiment.fish b/scripts/run-solo-gp-experiment.fish index 5c72cbb1..5d6b4180 100755 --- a/scripts/run-solo-gp-experiment.fish +++ b/scripts/run-solo-gp-experiment.fish @@ -45,9 +45,10 @@ for seed in 0 31 227 252 805 end RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null - set -l exported_json (printf '%s\n' export_solo\ gp\ experiment*.json | tail -n 1) + set -l exported_json (printf '%s\n' export_solo\ gp*.json | tail -n 1) set -l dirname (path dirname "$output_file") command mkdir -p "$dirname" + echo mv "$exported_json" "$output_file" mv "$exported_json" "$output_file" end end diff --git a/scripts/run-varying-network-connectivity-experiment.fish b/scripts/run-varying-network-connectivity-experiment.fish index 36692180..ec29930f 100755 --- a/scripts/run-varying-network-connectivity-experiment.fish +++ b/scripts/run-varying-network-connectivity-experiment.fish @@ -42,12 +42,12 @@ for seed in 0 31 227 252 805 printf '%sinfo%s: changed comms-radius to: %d\n' $green $reset $comms_radius >&2 - set -l output_file experiments/varying-network-connectivity/comms-radius-$comms_radius-seed-$seed.json + set -l output_file experiments/varying-network-connectivity-lm-3-tk-13.33/comms-radius-$comms_radius-seed-$seed.json set -l t_end (date "+%s") set -l t_diff (math "$t_end - $t_start") if functions -q peopletime - printf '%sinfo%s: time elapsed: \n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 + printf '%sinfo%s: time elapsed: %s\n' $green $reset (peopletime (math "$t_diff * 1000")) >&2 end if test -f $output_file From ede6d0906dda19534e8d72300524738a8fc81eed Mon Sep 17 00:00:00 2001 From: kpbaks Date: Tue, 4 Jun 2024 09:26:12 +0200 Subject: [PATCH 2/4] feat: done with experiments --- .../config.toml | 108 +++++++++--------- config/simulations/test/formation.yaml | 2 +- crates/gbpplanner-rs/src/asset_loader.rs | 2 +- .../gbpplanner-rs/src/planner/collisions.rs | 18 ++- .../src/planner/visualiser/waypoints.rs | 2 +- 5 files changed, 69 insertions(+), 63 deletions(-) diff --git a/config/simulations/Communications Failure Experiment/config.toml b/config/simulations/Communications Failure Experiment/config.toml index bf9ba199..b5105288 100644 --- a/config/simulations/Communications Failure Experiment/config.toml +++ b/config/simulations/Communications Failure Experiment/config.toml @@ -1,49 +1,49 @@ environment_image = "circle_cluttered" -environment = "./config/simulations/Circle/environment.yaml" -formation_group = "./config/simulations/Circle/formation.ron" +environment = "./config/simulations/Circle/environment.yaml" +formation_group = "./config/simulations/Circle/formation.ron" [visualisation.height] -objects = 0.5 +objects = 0.5 height-map = 1.0 [visualisation.draw] -robots = true -communication-graph = false -predicted-trajectories = false -waypoints = false -uncertainty = false -paths = false -communication-radius = false -obstacle-factors = false -tracking = false -interrobot-factors = false +robots = true +communication-graph = false +predicted-trajectories = false +waypoints = false +uncertainty = false +paths = false +communication-radius = false +obstacle-factors = false +tracking = false +interrobot-factors = false interrobot-factors-safety-distance = false -generated-map = true -sdf = true -robot-colliders = false -environment-colliders = false -robot-robot-collisions = false -robot-environment-collisions = false +generated-map = true +sdf = true +robot-colliders = false +environment-colliders = false +robot-robot-collisions = false +robot-environment-collisions = false [visualisation.uncertainty] max-radius = 2.5 -scale = 300.0 +scale = 300.0 [interaction] ui-focus-cancels-inputs = true -default-cam-distance = 100.0 +default-cam-distance = 100.0 [gbp] -sigma-pose-fixed = 0.0000000000000010000000036274937 -sigma-factor-dynamics = 1.0 +sigma-pose-fixed = 0.0000000000000010000000036274937 +sigma-factor-dynamics = 1.0 sigma-factor-interrobot = 0.004999999888241291 -sigma-factor-obstacle = 0.004999999888241291 -sigma-factor-tracking = 0.10000000149011612 -lookahead-multiple = 3 -variables = 10 +sigma-factor-obstacle = 0.004999999888241291 +sigma-factor-tracking = 0.10000000149011612 +lookahead-multiple = 3 +variables = 10 [gbp.tracking] -switch-padding = 1.0 +switch-padding = 1.0 attraction-distance = 2.0 [gbp.iteration-schedule] @@ -52,14 +52,14 @@ external = 10 schedule = "interleave-evenly" [gbp.factors-enabled] -dynamic = true +dynamic = true interrobot = true -obstacle = true -tracking = false +obstacle = true +tracking = false [robot] -planning-horizon = 13.329999923706055 -target-speed = 15.0 +planning-horizon = 13.329999923706055 +target-speed = 15.0 inter-robot-safety-distance-multiplier = 2.200000047683716 [robot.radius] @@ -67,50 +67,50 @@ min = 2.0 max = 3.0 [robot.communication] -radius = 50.0 -failure-rate = 0.3 +radius = 50.0 +failure-rate = 0.7 [simulation] -max-time = 10000.0 -time-scale = 1.0 -manual-step-factor = 1 -hz = 10.0 -prng-seed = 0 -pause-on-spawn = false +max-time = 10000.0 +time-scale = 1.0 +manual-step-factor = 1 +hz = 10.0 +prng-seed = 805 +pause-on-spawn = false despawn-robot-when-final-waypoint-reached = true -exit-application-on-scenario-finished = true +exit-application-on-scenario-finished = true [rrt] -max-iterations = 1000000 -step-size = 0.5 -collision-radius = 0.10000000149011612 +max-iterations = 1000000 +step-size = 0.5 +collision-radius = 0.10000000149011612 neighbourhood-radius = 10.0 [rrt.smoothing] -enabled = true +enabled = true max-iterations = 100 -step-size = 1.0 +step-size = 1.0 [graphviz] export-location = "./assets/export/" [graphviz.interrobot.active] style = "dashed" -len = 8.0 +len = 8.0 color = "red" [graphviz.interrobot.inactive] style = "dashed" -len = 8.0 +len = 8.0 color = "gray" [manual] timesteps-per-step = 1 [debug.on-variable-clicked] -obstacle = false -dynamic = false +obstacle = false +dynamic = false interrobot = false -tracking = false -variable = false -inbox = false +tracking = false +variable = false +inbox = false diff --git a/config/simulations/test/formation.yaml b/config/simulations/test/formation.yaml index 61988944..3e3e536e 100644 --- a/config/simulations/test/formation.yaml +++ b/config/simulations/test/formation.yaml @@ -7,7 +7,7 @@ formations: delay: secs: 1 nanos: 0 - robots: 5 + robots: 2 planning-strategy: only-local initial-position: shape: !circle diff --git a/crates/gbpplanner-rs/src/asset_loader.rs b/crates/gbpplanner-rs/src/asset_loader.rs index 1e368629..2fa87d58 100644 --- a/crates/gbpplanner-rs/src/asset_loader.rs +++ b/crates/gbpplanner-rs/src/asset_loader.rs @@ -87,7 +87,7 @@ impl FromWorld for Materials { .get_resource::() .expect("CatppuccinTheme exists in the world"); ( - Color::from_catppuccin_colour_with_alpha(catppuccin_theme.maroon(), 0.5), + Color::from_catppuccin_colour_with_alpha(catppuccin_theme.maroon(), 0.8), Color::from_catppuccin_colour_with_alpha(catppuccin_theme.maroon(), 0.2), Color::from_catppuccin_colour(catppuccin_theme.text()), ) diff --git a/crates/gbpplanner-rs/src/planner/collisions.rs b/crates/gbpplanner-rs/src/planner/collisions.rs index 09d0e59d..666b8592 100644 --- a/crates/gbpplanner-rs/src/planner/collisions.rs +++ b/crates/gbpplanner-rs/src/planner/collisions.rs @@ -608,14 +608,20 @@ fn render_robot_environment_collisions( // } let aabb = &event.intersection; - let center = Vec3::new(aabb.mins.x + aabb.maxs.x, 0.0, aabb.mins.y + aabb.maxs.y) / 2.0; + let mut center = Vec3::new(aabb.mins.x + aabb.maxs.x, 0.0, aabb.mins.y + aabb.maxs.y) / 2.0; + center.y = -config.visualisation.height.objects * 2.1; + + //-config.visualisation.height.objects - 1.5, + // let half_size = Vec3::new(aabb.maxs.x - aabb.mins.x, 0.0, aabb.maxs.y - // aabb.mins.y) / 2.0; - let cuboid = Cuboid::from_size(Vec3::new( - aabb.maxs.x - aabb.mins.x, - 2.0, - aabb.maxs.y - aabb.mins.y, - )); + let cuboid = Cuboid::from_size( + Vec3::new( + aabb.maxs.x - aabb.mins.x, + config.visualisation.height.objects * 4.5, + aabb.maxs.y - aabb.mins.y, + ) * 1.05, + ); let initial_visibility = if config.visualisation.draw.robot_environment_collisions { Visibility::Visible diff --git a/crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs b/crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs index b27a4c37..8f6d3683 100644 --- a/crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs +++ b/crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs @@ -50,7 +50,7 @@ fn visualize_waypoints( let height = -config.visualisation.height.objects; for (mission, color_assoc) in &missions { let colour = theme.get_display_colour(&color_assoc.name); - let color = Color::from_catppuccin_colour_with_alpha(colour, 0.25); + let color = Color::from_catppuccin_colour_with_alpha(colour, 0.8); // let color = theme.from_catppuccin_colour(color_assoc.name.); for (wp1, wp2) in mission.waypoints().tuple_windows() { gizmos.line( From 004e2a6278586f0309eb3d15dcf64dd8afb9f801 Mon Sep 17 00:00:00 2001 From: kpbaks Date: Tue, 4 Jun 2024 09:32:12 +0200 Subject: [PATCH 3/4] feat!: rename `gbpplanner-rs` to `magics` --- Cargo.lock | 190 +- Cargo.toml | 2 +- README.md | 8 +- bacon.toml | 2 +- .../simulations/Collaborative GP/config.toml | 116 + .../Collaborative GP/environment.yaml | 18 + .../Collaborative GP/formation.yaml | 364 +++ crates/bevy_fullscreen/src/lib.rs | 2 +- crates/env_to_png/src/lib.rs | 4 +- crates/gbp_config/src/lib.rs | 2 +- .../build/windows/installer/global.json | 6 - crates/gbpplanner-rs/index.html | 33 - crates/gbpplanner-rs/src/bin/perf_ui.rs | 31 - crates/{gbpplanner-rs => magics}/Cargo.toml | 2 +- crates/{gbpplanner-rs => magics}/Trunk.toml | 0 .../assets/audio/za-warudo.ogg | Bin .../fonts/JetBrainsMonoNerdFont-Bold.ttf | Bin .../JetBrainsMonoNerdFont-BoldItalic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-ExtraBold.ttf | Bin .../JetBrainsMonoNerdFont-ExtraBoldItalic.ttf | Bin .../JetBrainsMonoNerdFont-ExtraLight.ttf | Bin ...JetBrainsMonoNerdFont-ExtraLightItalic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-Italic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-Light.ttf | Bin .../JetBrainsMonoNerdFont-LightItalic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-Medium.ttf | Bin .../JetBrainsMonoNerdFont-MediumItalic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-Regular.ttf | Bin .../fonts/JetBrainsMonoNerdFont-SemiBold.ttf | Bin .../JetBrainsMonoNerdFont-SemiBoldItalic.ttf | Bin .../fonts/JetBrainsMonoNerdFont-Thin.ttf | Bin .../JetBrainsMonoNerdFont-ThinItalic.ttf | Bin .../imgs/obstacles/circle_cluttered.png | Bin .../imgs/obstacles/circle_cluttered.sdf.png | Bin .../assets/imgs/obstacles/empty.png | Bin .../assets/imgs/obstacles/empty.sdf.png | Bin .../assets/imgs/obstacles/junction_twoway.png | Bin .../imgs/obstacles/junction_twoway.sdf.png | Bin .../assets/imgs/obstacles/roundabout.png | Bin .../assets/imgs/obstacles/roundabout.sdf.png | Bin .../assets/imgs/obstacles/very_cluttered.png | Bin .../imgs/obstacles/very_cluttered.sdf.png | Bin .../assets/models/box.glb | Bin .../assets/models/roomba.glb | Bin .../assets/shaders/line_material.wgsl | 0 crates/{gbpplanner-rs => magics}/build.rs | 0 .../build/macos/create_icns.sh | 0 .../build/macos/create_icns_linux.sh | 0 .../macos/src/Game.app/Contents/Info.plist | 0 .../Game.app/Contents/Resources/AppIcon.icns | Bin .../build/web/sound.js | 0 .../build/web/styles.css | 0 .../build/windows/icon.ico | Bin .../build/windows/icon.rc | 0 .../build/windows/installer/.gitignore | 0 .../build/windows/installer/InstallDirUi.wxs | 0 .../build/windows/installer/Installer.sln | 0 .../build/windows/installer/Installer.wixproj | 0 .../build/windows/installer/Package.en-us.wxl | 0 .../build/windows/installer/Package.wxs | 0 .../credits/CREDITS.md | 0 .../credits/licenses/Bevy_MIT_License.md | 0 .../examples/await-loading-obstacle-folder.rs | 0 .../{gbpplanner-rs => magics}/examples/dev.rs | 0 ...nite-repeating-timer-with-initial-delay.rs | 0 .../repeating-timer-with-initial-delay.rs | 0 .../examples/rrt3d.rs | 2 +- .../examples/rrtenv.rs | 2 +- .../examples/rrtstarenv.rs | 2 +- .../examples/schedule-paint.rs | 0 .../examples/switch-sdf-image.rs | 0 .../examples/system-set-run-if.rs | 0 .../src/asset_loader.rs | 0 .../src/bevy_utils.rs | 0 .../src/bin/2d_shapes.rs | 0 .../src/bin/3d-shapes.rs | 0 .../src/bin/console.rs | 0 .../src/bin/create-empty-environment.rs | 0 .../src/bin/create-signed-distance-field.rs | 0 .../{gbpplanner-rs => magics}/src/bin/dock.rs | 0 .../src/bin/draw2d.rs | 0 .../src/bin/egui-matrix.rs | 0 .../src/bin/gizmos.rs | 0 .../src/bin/repeating-timers.rs | 0 .../src/bin/schedule-paint.rs | 0 .../bin/test-stable-indices-of-petgraph.rs | 0 .../{gbpplanner-rs => magics}/src/bin/wasm.rs | 0 .../src/bin/za-warudo.rs | 0 crates/{gbpplanner-rs => magics}/src/cli.rs | 0 .../src/despawn_entity_after.rs | 0 .../src/diagnostic/mod.rs | 0 .../src/diagnostic/robot.rs | 0 .../src/environment/camera.rs | 0 .../src/environment/cursor.rs | 0 .../src/environment/follow_cameras.rs | 0 .../src/environment/map.rs | 0 .../src/environment/map_generator.rs | 0 .../src/environment/mod.rs | 0 .../src/escape_codes.rs | 0 .../{gbpplanner-rs => magics}/src/export.rs | 0 .../src/factorgraph/factor/dynamic.rs | 0 .../src/factorgraph/factor/interrobot.rs | 0 .../factor/marginalise_factor_distance.rs | 0 .../src/factorgraph/factor/mod.rs | 0 .../src/factorgraph/factor/obstacle.rs | 0 .../src/factorgraph/factor/pose.rs | 0 .../src/factorgraph/factor/tracking.rs | 0 .../src/factorgraph/factor/velocity.rs | 0 .../src/factorgraph/factorgraph.rs | 0 .../src/factorgraph/graphviz.rs | 0 .../src/factorgraph/id.rs | 0 .../src/factorgraph/message.rs | 0 .../src/factorgraph/mod.rs | 0 .../src/factorgraph/node.rs | 0 .../src/factorgraph/variable.rs | 0 .../src/goal_area.rs | 0 .../src/input/camera.rs | 0 .../src/input/general.rs | 0 .../src/input/mod.rs | 0 .../src/input/moveable_object.rs | 0 .../src/input/screenshot.rs | 0 .../{gbpplanner-rs => magics}/src/input/ui.rs | 0 crates/{gbpplanner-rs => magics}/src/lib.rs | 0 .../{gbpplanner-rs => magics}/src/macros.rs | 0 crates/{gbpplanner-rs => magics}/src/main.rs | 2 +- .../src/moveable_object.rs | 0 .../{gbpplanner-rs => magics}/src/movement.rs | 0 .../src/pause_play.rs | 0 .../src/planner/collisions.rs | 0 .../src/planner/mission.rs | 0 .../src/planner/mod.rs | 0 .../src/planner/robot.rs | 0 .../src/planner/spawner.rs | 0 .../src/planner/tracking.rs | 0 .../src/planner/visualiser/collider.rs | 0 .../src/planner/visualiser/communication.rs | 0 .../visualiser/communication_radius.rs | 0 .../src/planner/visualiser/factorgraphs.rs | 0 .../src/planner/visualiser/interrobot.rs | 0 .../src/planner/visualiser/mod.rs | 0 .../src/planner/visualiser/obstacle.rs | 0 .../src/planner/visualiser/robot.rs | 0 .../src/planner/visualiser/tracer.rs | 0 .../src/planner/visualiser/tracking.rs | 0 .../src/planner/visualiser/uncertainty.rs | 0 .../src/planner/visualiser/waypoints.rs | 0 crates/{gbpplanner-rs => magics}/src/prng.rs | 0 .../src/run_conditions.rs | 0 .../src/simulation_loader.rs | 4 +- crates/{gbpplanner-rs => magics}/src/theme.rs | 0 .../src/ui/controls.rs | 0 .../src/ui/custom.rs | 0 .../{gbpplanner-rs => magics}/src/ui/data.rs | 0 .../src/ui/decoration.rs | 0 .../src/ui/diagnostics.rs | 123 +- .../src/ui/metrics.rs | 0 .../{gbpplanner-rs => magics}/src/ui/mod.rs | 0 .../{gbpplanner-rs => magics}/src/ui/scale.rs | 0 .../src/ui/selected_entity.rs | 0 .../src/ui/settings.rs | 0 crates/{gbpplanner-rs => magics}/src/utils.rs | 0 .../analyse-iteration-amount-experiment.ipynb | 1052 ++++++++ scripts/analyse-schedules-experiment.ipynb | 408 ++++ ...tion-amount-average-distance-travelled.svg | 1847 ++++++++++++++ scripts/iteration-amount-average-ldj.svg | 2134 +++++++++++++++++ scripts/iteration-amount-average-makespan.svg | 1851 ++++++++++++++ ...eration-amount-largest-time-differense.svg | 1926 +++++++++++++++ scripts/run-circle-expertiment.fish | 2 +- scripts/run-collaborative-gp-experiment.fish | 2 +- ...run-communication-failure-expertiment.fish | 2 +- .../run-environment-obstacles-experiment.fish | 2 +- scripts/run-iteration-amount-experiment.fish | 2 +- scripts/run-schedules-experiment.fish | 2 +- scripts/run-solo-gp-experiment.fish | 2 +- ...rying-network-connectivity-experiment.fish | 2 +- scripts/run.fish | 4 +- scripts/schedules-distance_travelled.svg | 1189 +++++++++ scripts/schedules-ldj.svg | 839 +++++++ scripts/schedules-makespan.svg | 997 ++++++++ 179 files changed, 12922 insertions(+), 256 deletions(-) create mode 100644 config/simulations/Collaborative GP/config.toml create mode 100644 config/simulations/Collaborative GP/environment.yaml create mode 100644 config/simulations/Collaborative GP/formation.yaml delete mode 100644 crates/gbpplanner-rs/build/windows/installer/global.json delete mode 100644 crates/gbpplanner-rs/index.html delete mode 100644 crates/gbpplanner-rs/src/bin/perf_ui.rs rename crates/{gbpplanner-rs => magics}/Cargo.toml (99%) rename crates/{gbpplanner-rs => magics}/Trunk.toml (100%) rename crates/{gbpplanner-rs => magics}/assets/audio/za-warudo.ogg (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Bold.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-BoldItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-ExtraBold.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-ExtraBoldItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-ExtraLight.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Italic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Light.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-LightItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Medium.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-MediumItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Regular.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-SemiBold.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-SemiBoldItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-Thin.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/fonts/JetBrainsMonoNerdFont-ThinItalic.ttf (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/circle_cluttered.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/circle_cluttered.sdf.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/empty.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/empty.sdf.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/junction_twoway.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/junction_twoway.sdf.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/roundabout.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/roundabout.sdf.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/very_cluttered.png (100%) rename crates/{gbpplanner-rs => magics}/assets/imgs/obstacles/very_cluttered.sdf.png (100%) rename crates/{gbpplanner-rs => magics}/assets/models/box.glb (100%) rename crates/{gbpplanner-rs => magics}/assets/models/roomba.glb (100%) rename crates/{gbpplanner-rs => magics}/assets/shaders/line_material.wgsl (100%) rename crates/{gbpplanner-rs => magics}/build.rs (100%) rename crates/{gbpplanner-rs => magics}/build/macos/create_icns.sh (100%) rename crates/{gbpplanner-rs => magics}/build/macos/create_icns_linux.sh (100%) rename crates/{gbpplanner-rs => magics}/build/macos/src/Game.app/Contents/Info.plist (100%) rename crates/{gbpplanner-rs => magics}/build/macos/src/Game.app/Contents/Resources/AppIcon.icns (100%) rename crates/{gbpplanner-rs => magics}/build/web/sound.js (100%) rename crates/{gbpplanner-rs => magics}/build/web/styles.css (100%) rename crates/{gbpplanner-rs => magics}/build/windows/icon.ico (100%) rename crates/{gbpplanner-rs => magics}/build/windows/icon.rc (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/.gitignore (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/InstallDirUi.wxs (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/Installer.sln (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/Installer.wixproj (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/Package.en-us.wxl (100%) rename crates/{gbpplanner-rs => magics}/build/windows/installer/Package.wxs (100%) rename crates/{gbpplanner-rs => magics}/credits/CREDITS.md (100%) rename crates/{gbpplanner-rs => magics}/credits/licenses/Bevy_MIT_License.md (100%) rename crates/{gbpplanner-rs => magics}/examples/await-loading-obstacle-folder.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/dev.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/finite-repeating-timer-with-initial-delay.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/repeating-timer-with-initial-delay.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/rrt3d.rs (99%) rename crates/{gbpplanner-rs => magics}/examples/rrtenv.rs (99%) rename crates/{gbpplanner-rs => magics}/examples/rrtstarenv.rs (99%) rename crates/{gbpplanner-rs => magics}/examples/schedule-paint.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/switch-sdf-image.rs (100%) rename crates/{gbpplanner-rs => magics}/examples/system-set-run-if.rs (100%) rename crates/{gbpplanner-rs => magics}/src/asset_loader.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bevy_utils.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/2d_shapes.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/3d-shapes.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/console.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/create-empty-environment.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/create-signed-distance-field.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/dock.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/draw2d.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/egui-matrix.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/gizmos.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/repeating-timers.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/schedule-paint.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/test-stable-indices-of-petgraph.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/wasm.rs (100%) rename crates/{gbpplanner-rs => magics}/src/bin/za-warudo.rs (100%) rename crates/{gbpplanner-rs => magics}/src/cli.rs (100%) rename crates/{gbpplanner-rs => magics}/src/despawn_entity_after.rs (100%) rename crates/{gbpplanner-rs => magics}/src/diagnostic/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/diagnostic/robot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/camera.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/cursor.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/follow_cameras.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/map.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/map_generator.rs (100%) rename crates/{gbpplanner-rs => magics}/src/environment/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/escape_codes.rs (100%) rename crates/{gbpplanner-rs => magics}/src/export.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/dynamic.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/interrobot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/marginalise_factor_distance.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/obstacle.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/pose.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/tracking.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factor/velocity.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/factorgraph.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/graphviz.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/id.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/message.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/node.rs (100%) rename crates/{gbpplanner-rs => magics}/src/factorgraph/variable.rs (100%) rename crates/{gbpplanner-rs => magics}/src/goal_area.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/camera.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/general.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/moveable_object.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/screenshot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/input/ui.rs (100%) rename crates/{gbpplanner-rs => magics}/src/lib.rs (100%) rename crates/{gbpplanner-rs => magics}/src/macros.rs (100%) rename crates/{gbpplanner-rs => magics}/src/main.rs (99%) rename crates/{gbpplanner-rs => magics}/src/moveable_object.rs (100%) rename crates/{gbpplanner-rs => magics}/src/movement.rs (100%) rename crates/{gbpplanner-rs => magics}/src/pause_play.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/collisions.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/mission.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/robot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/spawner.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/tracking.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/collider.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/communication.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/communication_radius.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/factorgraphs.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/interrobot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/obstacle.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/robot.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/tracer.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/tracking.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/uncertainty.rs (100%) rename crates/{gbpplanner-rs => magics}/src/planner/visualiser/waypoints.rs (100%) rename crates/{gbpplanner-rs => magics}/src/prng.rs (100%) rename crates/{gbpplanner-rs => magics}/src/run_conditions.rs (100%) rename crates/{gbpplanner-rs => magics}/src/simulation_loader.rs (99%) rename crates/{gbpplanner-rs => magics}/src/theme.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/controls.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/custom.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/data.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/decoration.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/diagnostics.rs (56%) rename crates/{gbpplanner-rs => magics}/src/ui/metrics.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/mod.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/scale.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/selected_entity.rs (100%) rename crates/{gbpplanner-rs => magics}/src/ui/settings.rs (100%) rename crates/{gbpplanner-rs => magics}/src/utils.rs (100%) create mode 100644 scripts/analyse-iteration-amount-experiment.ipynb create mode 100644 scripts/analyse-schedules-experiment.ipynb create mode 100644 scripts/iteration-amount-average-distance-travelled.svg create mode 100644 scripts/iteration-amount-average-ldj.svg create mode 100644 scripts/iteration-amount-average-makespan.svg create mode 100644 scripts/iteration-amount-largest-time-differense.svg create mode 100644 scripts/schedules-distance_travelled.svg create mode 100644 scripts/schedules-ldj.svg create mode 100644 scripts/schedules-makespan.svg diff --git a/Cargo.lock b/Cargo.lock index 21b16306..cdbb0f98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3518,101 +3518,6 @@ dependencies = [ "bevy", ] -[[package]] -name = "gbpplanner-rs" -version = "2.0.0" -dependencies = [ - "angle", - "anyhow", - "approx", - "atty", - "bat", - "better-panic", - "bevy", - "bevy-inspector-egui", - "bevy_asset_loader", - "bevy_dev", - "bevy_dev_console", - "bevy_egui 0.26.0", - "bevy_fullscreen", - "bevy_infinite_grid", - "bevy_mod_debugdump", - "bevy_mod_picking", - "bevy_more_shapes", - "bevy_notify", - "bevy_prng", - "bevy_rand", - "bevy_touchpad", - "catppuccin", - "chrono", - "clap", - "clap_complete", - "colored", - "colorgrad", - "dark-light", - "delegate", - "derive_more", - "dhat", - "egui_dock", - "egui_extras", - "egui_graphs", - "egui_plot", - "egui_tiles", - "embed-resource 2.4.2", - "env_to_png", - "fastrand", - "gbp_config", - "gbp_environment", - "gbp_global_planner", - "gbp_linalg", - "gbp_multivariate_normal", - "gbp_schedule", - "glob", - "heck 0.5.0", - "image 0.25.1", - "indexmap", - "interleave_evenly", - "itertools 0.13.0", - "iyes_perf_ui", - "leafwing-input-manager", - "mimalloc", - "min_len_vec", - "ndarray", - "ndarray-inverse", - "num-traits", - "once_cell", - "open", - "ordered-float 4.2.0", - "parry2d", - "parry3d", - "paste", - "percentage", - "petgraph", - "pretty_assertions", - "rand", - "rand_chacha", - "repeating_array", - "ringbuf 0.3.3", - "ron", - "rrt", - "seq", - "serde", - "serde_json", - "serde_yaml", - "smol_str", - "struct_iterable", - "strum", - "strum_macros", - "tap", - "termsize", - "thiserror", - "toml 0.8.13", - "typed-builder", - "typed_floats", - "unit_interval", - "units", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -4599,6 +4504,101 @@ dependencies = [ "libc", ] +[[package]] +name = "magics" +version = "2.0.0" +dependencies = [ + "angle", + "anyhow", + "approx", + "atty", + "bat", + "better-panic", + "bevy", + "bevy-inspector-egui", + "bevy_asset_loader", + "bevy_dev", + "bevy_dev_console", + "bevy_egui 0.26.0", + "bevy_fullscreen", + "bevy_infinite_grid", + "bevy_mod_debugdump", + "bevy_mod_picking", + "bevy_more_shapes", + "bevy_notify", + "bevy_prng", + "bevy_rand", + "bevy_touchpad", + "catppuccin", + "chrono", + "clap", + "clap_complete", + "colored", + "colorgrad", + "dark-light", + "delegate", + "derive_more", + "dhat", + "egui_dock", + "egui_extras", + "egui_graphs", + "egui_plot", + "egui_tiles", + "embed-resource 2.4.2", + "env_to_png", + "fastrand", + "gbp_config", + "gbp_environment", + "gbp_global_planner", + "gbp_linalg", + "gbp_multivariate_normal", + "gbp_schedule", + "glob", + "heck 0.5.0", + "image 0.25.1", + "indexmap", + "interleave_evenly", + "itertools 0.13.0", + "iyes_perf_ui", + "leafwing-input-manager", + "mimalloc", + "min_len_vec", + "ndarray", + "ndarray-inverse", + "num-traits", + "once_cell", + "open", + "ordered-float 4.2.0", + "parry2d", + "parry3d", + "paste", + "percentage", + "petgraph", + "pretty_assertions", + "rand", + "rand_chacha", + "repeating_array", + "ringbuf 0.3.3", + "ron", + "rrt", + "seq", + "serde", + "serde_json", + "serde_yaml", + "smol_str", + "struct_iterable", + "strum", + "strum_macros", + "tap", + "termsize", + "thiserror", + "toml 0.8.13", + "typed-builder", + "typed_floats", + "unit_interval", + "units", +] + [[package]] name = "malloc_buf" version = "0.0.6" diff --git a/Cargo.toml b/Cargo.toml index 37d79767..20fd5c31 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ members = [ "crates/gbp_linalg", "crates/gbp_multivariate_normal", # "crates/bevy_undo_redo", - "crates/gbpplanner-rs", + "crates/magics", "crates/bevy_notify", "crates/units", "crates/repeating_array", diff --git a/README.md b/README.md index 383438cb..26b41aa3 100644 --- a/README.md +++ b/README.md @@ -45,10 +45,10 @@ cargo build --release ```sh -cargo run --release --bin gbpplanner-rs # Open the simulator -cargo run --release --bin gbpplanner-rs -- --list # List all available scenarios +cargo run --release --bin magics # Open the simulator +cargo run --release --bin magics -- --list # List all available scenarios # Run a specific scenario -cargo run --release --bin gbpplanner-rs -- -i -cargo run --release --bin gbpplanner-rs -- --initial-scenario +cargo run --release --bin magics -- -i +cargo run --release --bin magics -- --initial-scenario ``` diff --git a/bacon.toml b/bacon.toml index 5ddcad7d..d5a46440 100644 --- a/bacon.toml +++ b/bacon.toml @@ -15,7 +15,7 @@ command = [ "--color", "always", "--package", - "gbpplanner-rs", + "magics", ] need_stdout = false diff --git a/config/simulations/Collaborative GP/config.toml b/config/simulations/Collaborative GP/config.toml new file mode 100644 index 00000000..08bbb81f --- /dev/null +++ b/config/simulations/Collaborative GP/config.toml @@ -0,0 +1,116 @@ +environment_image = "junction_twoway" +environment = "./config/simulations/Collaborative GP/environment.yaml" +formation_group = "./config/simulations/Collaborative GP/formation.ron" + +[visualisation.height] +objects = 0.5 +height-map = 2.0 + +[visualisation.draw] +robots = true +communication-graph = true +predicted-trajectories = true +waypoints = true +uncertainty = false +paths = false +communication-radius = false +obstacle-factors = false +tracking = true +interrobot-factors = false +interrobot-factors-safety-distance = false +generated-map = true +sdf = false +robot-colliders = false +environment-colliders = false +robot-robot-collisions = true +robot-environment-collisions = true + +[visualisation.uncertainty] +max-radius = 2.5 +scale = 300.0 + +[interaction] +ui-focus-cancels-inputs = true +default-cam-distance = 300.0 + +[gbp] +sigma-pose-fixed = 0.0000000000000010000000036274937 +sigma-factor-dynamics = 0.10000000149011612 +sigma-factor-interrobot = 0.009999999776482582 +sigma-factor-obstacle = 0.009999999776482582 +sigma-factor-tracking = 0.5 +lookahead-multiple = 3 +variables = 10 + +[gbp.tracking] +switch-padding = 5.0 +attraction-distance = 1.0 + +[gbp.iteration-schedule] +internal = 10 +external = 10 +schedule = "interleave-evenly" + +[gbp.factors-enabled] +dynamic = true +interrobot = true +obstacle = true +tracking = true + +[robot] +planning-horizon = 5.0 +target-speed = 7.0 +inter-robot-safety-distance-multiplier = 4.0 + +[robot.radius] +min = 2.0 +max = 2.0 + +[robot.communication] +radius = 20.0 +failure-rate = 0.0 + +[simulation] +max-time = 10000.0 +time-scale = 2.0 +manual-step-factor = 1 +hz = 10.0 +prng-seed = 805 +pause-on-spawn = false +despawn-robot-when-final-waypoint-reached = true +exit-application-on-scenario-finished = true + +[rrt] +max-iterations = 5000000 +step-size = 5.0 +collision-radius = 3.0 +neighbourhood-radius = 8.0 + +[rrt.smoothing] +enabled = true +max-iterations = 500 +step-size = 0.5 + +[graphviz] +export-location = "./assets/export/" + +[graphviz.interrobot.active] +style = "dashed" +len = 8.0 +color = "red" + +[graphviz.interrobot.inactive] +style = "dashed" +len = 8.0 +color = "gray" + +[manual] +timesteps-per-step = 1 + +[debug.on-variable-clicked] +obstacle = false +dynamic = false +interrobot = false +tracking = true +variable = false +inbox = false diff --git a/config/simulations/Collaborative GP/environment.yaml b/config/simulations/Collaborative GP/environment.yaml new file mode 100644 index 00000000..b4deb215 --- /dev/null +++ b/config/simulations/Collaborative GP/environment.yaml @@ -0,0 +1,18 @@ +tiles: + grid: + - ' ╷ ╷ ' + - ' ┌─┼─┼─┐┌╴' + - '╶┼─┘┌┼┬┼┘ ' + - '╶┴┬─┴┼┘│ ' + - ' ┌┴┐┌┼─┴┬╴' + - ' ├─┴┘├──┘ ' + - ' ╵ ╵ ' + settings: + tile-size: 25.0 + path-width: 0.5 + obstacle-height: 2.25 + sdf: + resolution: 200 + expansion: 0.2 + blur: 0.02 +obstacles: [] diff --git a/config/simulations/Collaborative GP/formation.yaml b/config/simulations/Collaborative GP/formation.yaml new file mode 100644 index 00000000..6e647272 --- /dev/null +++ b/config/simulations/Collaborative GP/formation.yaml @@ -0,0 +1,364 @@ +formations: + +# xmin = 0.075 +# ymin = 0.1 +# xmax = 0.925 +# ymax = 0.9 + +# Formation 1: brown east->north +- repeat: + every: + secs: 10 + nanos: 0 + times: !finite 10 + delay: + secs: 0 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.925 + y: 0.357 + - x: 0.925 + y: 0.357 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.55 + y: 0.9 + - x: 0.55 + y: 0.9 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: !variable 5 + +# Formation 2: yellow east->west +- repeat: + every: + secs: 10 + nanos: 0 + times: !finite 10 + delay: + secs: 5 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.925 + y: 0.357 + - x: 0.925 + y: 0.357 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.15 + y: 0.1 + - x: 0.15 + y: 0.1 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: !variable 5 + +# Formation 3: purple south->north-east +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 0 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.55 + y: 0.1 + - x: 0.55 + y: 0.1 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.925 + y: 0.786 + - x: 0.925 + y: 0.786 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: current + +# Formation 4: red south->north +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 5 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.55 + y: 0.1 + - x: 0.55 + y: 0.1 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.55 + y: 0.9 + - x: 0.55 + y: 0.9 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: current + +# Formation 5: blue south->north-west +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 10 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.55 + y: 0.1 + - x: 0.55 + y: 0.1 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.075 + y: 0.643 + - x: 0.075 + y: 0.643 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: current + +# Formation 6: orange west->north-east +- repeat: + every: + secs: 10 + nanos: 0 + times: !finite 10 + delay: + secs: 0 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.075 + y: 0.5 + - x: 0.075 + y: 0.5 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.925 + y: 0.786 + - x: 0.925 + y: 0.786 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + distance: !meter 10 + intersects-with: current + +# Formation 7: green west->north +- repeat: + every: + secs: 10 + nanos: 0 + times: !finite 10 + delay: + secs: 5 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.075 + y: 0.5 + - x: 0.075 + y: 0.5 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.55 + y: 0.9 + - x: 0.55 + y: 0.9 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + # distance: !meter 10 + # intersects-with: !variable 5 + distance: !meter 10 + intersects-with: current + +# Formation 8: yellow north2->north-west +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 0 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.35 + y: 0.9 + - x: 0.35 + y: 0.9 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.075 + y: 0.643 + - x: 0.075 + y: 0.643 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + # distance: !meter 10 + # intersects-with: !variable 5 + distance: !meter 10 + intersects-with: current + +# Formation 9: dark purple north2->west +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 5 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.35 + y: 0.9 + - x: 0.35 + y: 0.9 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.15 + y: 0.1 + - x: 0.15 + y: 0.1 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + # distance: !meter 10 + # intersects-with: !variable 5 + distance: !meter 10 + intersects-with: current + +# Formation 10: light blue north2->north-east +- repeat: + every: + secs: 15 + nanos: 0 + times: !finite 10 + delay: + secs: 10 + nanos: 0 + robots: 1 + planning-strategy: rrt-star + initial-position: + shape: !line-segment + - x: 0.35 + y: 0.9 + - x: 0.35 + y: 0.9 + placement-strategy: !random + attempts: 1000 + waypoints: + - shape: !line-segment + - x: 0.925 + y: 0.786 + - x: 0.925 + y: 0.786 + projection-strategy: identity + # waypoint-reached-when-intersects: horizon + # finished-when-intersects: !variable 5 + waypoint-reached-when-intersects: + distance: robot-radius + intersects-with: horizon + finished-when-intersects: + # distance: !meter 10 + # intersects-with: !variable 5 + distance: !meter 10 + intersects-with: current diff --git a/crates/bevy_fullscreen/src/lib.rs b/crates/bevy_fullscreen/src/lib.rs index 8031452c..7aaa0834 100644 --- a/crates/bevy_fullscreen/src/lib.rs +++ b/crates/bevy_fullscreen/src/lib.rs @@ -9,7 +9,7 @@ //! # Examples //! ```rust //! use bevy::prelude::*; -//! use gbpplanner_rs::toggle_fullscreen::ToggleFullscreenPlugin; +//! use magics::toggle_fullscreen::ToggleFullscreenPlugin; //! //! App::new() //! .add_plugins(DefaultPlugins) diff --git a/crates/env_to_png/src/lib.rs b/crates/env_to_png/src/lib.rs index 20b3fcad..20a8f12c 100644 --- a/crates/env_to_png/src/lib.rs +++ b/crates/env_to_png/src/lib.rs @@ -1,11 +1,11 @@ -//! This crate converts an [`Environment`] Configuration from the gbpplanner_rs +//! This crate converts an [`Environment`] Configuration from the magics //! crate to a PNG image. It is possible to customize the colors of the //! different elements of the environment. And it can blur the edges to mimic an //! SDF. use std::num::NonZeroU32; -// use gbpplanner_rs::config::Environment; +// use magics::config::Environment; use gbp_environment::{Environment, PlaceableShape, RegularPolygon}; use gbp_geometry::RelativePoint; use glam::{Vec2, Vec3Swizzles}; diff --git a/crates/gbp_config/src/lib.rs b/crates/gbp_config/src/lib.rs index fbaf680a..75b7277a 100644 --- a/crates/gbp_config/src/lib.rs +++ b/crates/gbp_config/src/lib.rs @@ -849,7 +849,7 @@ impl Default for Config { // TODO: make a bit more robust // let cwd = std::env::current_dir().expect("The current working directory // exists"); let default_environment = - // cwd.join("gbpplanner-rs/assets/imgs/junction.png"); + // cwd.join("magics/assets/imgs/junction.png"); let default_environment_image = "junction".to_string(); let default_environment_config = "./config/environment.yaml".to_string(); let default_formation_config = "./config/formation.ron".to_string(); diff --git a/crates/gbpplanner-rs/build/windows/installer/global.json b/crates/gbpplanner-rs/build/windows/installer/global.json deleted file mode 100644 index 9f70a2c6..00000000 --- a/crates/gbpplanner-rs/build/windows/installer/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sdk": { - "version": "7.0.102", - "rollForward": "latestFeature" - } -} diff --git a/crates/gbpplanner-rs/index.html b/crates/gbpplanner-rs/index.html deleted file mode 100644 index 62e8a2a2..00000000 --- a/crates/gbpplanner-rs/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - GBP Planner Rust - - - - - - - - - - - - - - - - - -
-
- - Javascript and support for canvas is required - -
- - - diff --git a/crates/gbpplanner-rs/src/bin/perf_ui.rs b/crates/gbpplanner-rs/src/bin/perf_ui.rs deleted file mode 100644 index 0c922d70..00000000 --- a/crates/gbpplanner-rs/src/bin/perf_ui.rs +++ /dev/null @@ -1,31 +0,0 @@ -// https://github.com/IyesGames/iyes_perf_ui/blob/main/examples/simple.rs - -//! This example shows the simplest way to create a Perf UI. -//! (using defaults for everything) - -use bevy::prelude::*; -use iyes_perf_ui::prelude::*; - -fn main() { - App::new() - .add_plugins(DefaultPlugins) - - // we want Bevy to measure these values for us: - .add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin) - .add_plugins(bevy::diagnostic::EntityCountDiagnosticsPlugin) - .add_plugins(bevy::diagnostic::SystemInformationDiagnosticsPlugin) - - .add_plugins(PerfUiPlugin) - .add_systems(Startup, setup) - - .run(); -} - -fn setup(mut commands: Commands) { - // spawn a camera to be able to see anything - commands.spawn(Camera2dBundle::default()); - - // create a simple Perf UI with default settings - // and all entries provided by the crate: - commands.spawn(PerfUiCompleteBundle::default()); -} diff --git a/crates/gbpplanner-rs/Cargo.toml b/crates/magics/Cargo.toml similarity index 99% rename from crates/gbpplanner-rs/Cargo.toml rename to crates/magics/Cargo.toml index f6ecd855..c46352a2 100644 --- a/crates/gbpplanner-rs/Cargo.toml +++ b/crates/magics/Cargo.toml @@ -1,6 +1,6 @@ [package] edition = "2021" -name = "gbpplanner-rs" +name = "magics" description = "Rust implementation and improvement of the GBP planner algorithm" version.workspace = true repository.workspace = true diff --git a/crates/gbpplanner-rs/Trunk.toml b/crates/magics/Trunk.toml similarity index 100% rename from crates/gbpplanner-rs/Trunk.toml rename to crates/magics/Trunk.toml diff --git a/crates/gbpplanner-rs/assets/audio/za-warudo.ogg b/crates/magics/assets/audio/za-warudo.ogg similarity index 100% rename from crates/gbpplanner-rs/assets/audio/za-warudo.ogg rename to crates/magics/assets/audio/za-warudo.ogg diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Bold.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Bold.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Bold.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Bold.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-BoldItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-BoldItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-BoldItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-BoldItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraBold.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraBold.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraBold.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraBold.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraBoldItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraBoldItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraBoldItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraBoldItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraLight.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraLight.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraLight.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraLight.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-ExtraLightItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Italic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Italic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Italic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Italic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Light.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Light.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Light.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Light.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-LightItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-LightItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-LightItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-LightItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Medium.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Medium.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Medium.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Medium.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-MediumItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-MediumItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-MediumItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-MediumItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Regular.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Regular.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Regular.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Regular.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-SemiBold.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-SemiBold.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-SemiBold.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-SemiBold.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-SemiBoldItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-SemiBoldItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-SemiBoldItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-SemiBoldItalic.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Thin.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-Thin.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-Thin.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-Thin.ttf diff --git a/crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ThinItalic.ttf b/crates/magics/assets/fonts/JetBrainsMonoNerdFont-ThinItalic.ttf similarity index 100% rename from crates/gbpplanner-rs/assets/fonts/JetBrainsMonoNerdFont-ThinItalic.ttf rename to crates/magics/assets/fonts/JetBrainsMonoNerdFont-ThinItalic.ttf diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/circle_cluttered.png b/crates/magics/assets/imgs/obstacles/circle_cluttered.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/circle_cluttered.png rename to crates/magics/assets/imgs/obstacles/circle_cluttered.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/circle_cluttered.sdf.png b/crates/magics/assets/imgs/obstacles/circle_cluttered.sdf.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/circle_cluttered.sdf.png rename to crates/magics/assets/imgs/obstacles/circle_cluttered.sdf.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/empty.png b/crates/magics/assets/imgs/obstacles/empty.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/empty.png rename to crates/magics/assets/imgs/obstacles/empty.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/empty.sdf.png b/crates/magics/assets/imgs/obstacles/empty.sdf.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/empty.sdf.png rename to crates/magics/assets/imgs/obstacles/empty.sdf.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/junction_twoway.png b/crates/magics/assets/imgs/obstacles/junction_twoway.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/junction_twoway.png rename to crates/magics/assets/imgs/obstacles/junction_twoway.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/junction_twoway.sdf.png b/crates/magics/assets/imgs/obstacles/junction_twoway.sdf.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/junction_twoway.sdf.png rename to crates/magics/assets/imgs/obstacles/junction_twoway.sdf.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/roundabout.png b/crates/magics/assets/imgs/obstacles/roundabout.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/roundabout.png rename to crates/magics/assets/imgs/obstacles/roundabout.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/roundabout.sdf.png b/crates/magics/assets/imgs/obstacles/roundabout.sdf.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/roundabout.sdf.png rename to crates/magics/assets/imgs/obstacles/roundabout.sdf.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/very_cluttered.png b/crates/magics/assets/imgs/obstacles/very_cluttered.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/very_cluttered.png rename to crates/magics/assets/imgs/obstacles/very_cluttered.png diff --git a/crates/gbpplanner-rs/assets/imgs/obstacles/very_cluttered.sdf.png b/crates/magics/assets/imgs/obstacles/very_cluttered.sdf.png similarity index 100% rename from crates/gbpplanner-rs/assets/imgs/obstacles/very_cluttered.sdf.png rename to crates/magics/assets/imgs/obstacles/very_cluttered.sdf.png diff --git a/crates/gbpplanner-rs/assets/models/box.glb b/crates/magics/assets/models/box.glb similarity index 100% rename from crates/gbpplanner-rs/assets/models/box.glb rename to crates/magics/assets/models/box.glb diff --git a/crates/gbpplanner-rs/assets/models/roomba.glb b/crates/magics/assets/models/roomba.glb similarity index 100% rename from crates/gbpplanner-rs/assets/models/roomba.glb rename to crates/magics/assets/models/roomba.glb diff --git a/crates/gbpplanner-rs/assets/shaders/line_material.wgsl b/crates/magics/assets/shaders/line_material.wgsl similarity index 100% rename from crates/gbpplanner-rs/assets/shaders/line_material.wgsl rename to crates/magics/assets/shaders/line_material.wgsl diff --git a/crates/gbpplanner-rs/build.rs b/crates/magics/build.rs similarity index 100% rename from crates/gbpplanner-rs/build.rs rename to crates/magics/build.rs diff --git a/crates/gbpplanner-rs/build/macos/create_icns.sh b/crates/magics/build/macos/create_icns.sh similarity index 100% rename from crates/gbpplanner-rs/build/macos/create_icns.sh rename to crates/magics/build/macos/create_icns.sh diff --git a/crates/gbpplanner-rs/build/macos/create_icns_linux.sh b/crates/magics/build/macos/create_icns_linux.sh similarity index 100% rename from crates/gbpplanner-rs/build/macos/create_icns_linux.sh rename to crates/magics/build/macos/create_icns_linux.sh diff --git a/crates/gbpplanner-rs/build/macos/src/Game.app/Contents/Info.plist b/crates/magics/build/macos/src/Game.app/Contents/Info.plist similarity index 100% rename from crates/gbpplanner-rs/build/macos/src/Game.app/Contents/Info.plist rename to crates/magics/build/macos/src/Game.app/Contents/Info.plist diff --git a/crates/gbpplanner-rs/build/macos/src/Game.app/Contents/Resources/AppIcon.icns b/crates/magics/build/macos/src/Game.app/Contents/Resources/AppIcon.icns similarity index 100% rename from crates/gbpplanner-rs/build/macos/src/Game.app/Contents/Resources/AppIcon.icns rename to crates/magics/build/macos/src/Game.app/Contents/Resources/AppIcon.icns diff --git a/crates/gbpplanner-rs/build/web/sound.js b/crates/magics/build/web/sound.js similarity index 100% rename from crates/gbpplanner-rs/build/web/sound.js rename to crates/magics/build/web/sound.js diff --git a/crates/gbpplanner-rs/build/web/styles.css b/crates/magics/build/web/styles.css similarity index 100% rename from crates/gbpplanner-rs/build/web/styles.css rename to crates/magics/build/web/styles.css diff --git a/crates/gbpplanner-rs/build/windows/icon.ico b/crates/magics/build/windows/icon.ico similarity index 100% rename from crates/gbpplanner-rs/build/windows/icon.ico rename to crates/magics/build/windows/icon.ico diff --git a/crates/gbpplanner-rs/build/windows/icon.rc b/crates/magics/build/windows/icon.rc similarity index 100% rename from crates/gbpplanner-rs/build/windows/icon.rc rename to crates/magics/build/windows/icon.rc diff --git a/crates/gbpplanner-rs/build/windows/installer/.gitignore b/crates/magics/build/windows/installer/.gitignore similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/.gitignore rename to crates/magics/build/windows/installer/.gitignore diff --git a/crates/gbpplanner-rs/build/windows/installer/InstallDirUi.wxs b/crates/magics/build/windows/installer/InstallDirUi.wxs similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/InstallDirUi.wxs rename to crates/magics/build/windows/installer/InstallDirUi.wxs diff --git a/crates/gbpplanner-rs/build/windows/installer/Installer.sln b/crates/magics/build/windows/installer/Installer.sln similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/Installer.sln rename to crates/magics/build/windows/installer/Installer.sln diff --git a/crates/gbpplanner-rs/build/windows/installer/Installer.wixproj b/crates/magics/build/windows/installer/Installer.wixproj similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/Installer.wixproj rename to crates/magics/build/windows/installer/Installer.wixproj diff --git a/crates/gbpplanner-rs/build/windows/installer/Package.en-us.wxl b/crates/magics/build/windows/installer/Package.en-us.wxl similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/Package.en-us.wxl rename to crates/magics/build/windows/installer/Package.en-us.wxl diff --git a/crates/gbpplanner-rs/build/windows/installer/Package.wxs b/crates/magics/build/windows/installer/Package.wxs similarity index 100% rename from crates/gbpplanner-rs/build/windows/installer/Package.wxs rename to crates/magics/build/windows/installer/Package.wxs diff --git a/crates/gbpplanner-rs/credits/CREDITS.md b/crates/magics/credits/CREDITS.md similarity index 100% rename from crates/gbpplanner-rs/credits/CREDITS.md rename to crates/magics/credits/CREDITS.md diff --git a/crates/gbpplanner-rs/credits/licenses/Bevy_MIT_License.md b/crates/magics/credits/licenses/Bevy_MIT_License.md similarity index 100% rename from crates/gbpplanner-rs/credits/licenses/Bevy_MIT_License.md rename to crates/magics/credits/licenses/Bevy_MIT_License.md diff --git a/crates/gbpplanner-rs/examples/await-loading-obstacle-folder.rs b/crates/magics/examples/await-loading-obstacle-folder.rs similarity index 100% rename from crates/gbpplanner-rs/examples/await-loading-obstacle-folder.rs rename to crates/magics/examples/await-loading-obstacle-folder.rs diff --git a/crates/gbpplanner-rs/examples/dev.rs b/crates/magics/examples/dev.rs similarity index 100% rename from crates/gbpplanner-rs/examples/dev.rs rename to crates/magics/examples/dev.rs diff --git a/crates/gbpplanner-rs/examples/finite-repeating-timer-with-initial-delay.rs b/crates/magics/examples/finite-repeating-timer-with-initial-delay.rs similarity index 100% rename from crates/gbpplanner-rs/examples/finite-repeating-timer-with-initial-delay.rs rename to crates/magics/examples/finite-repeating-timer-with-initial-delay.rs diff --git a/crates/gbpplanner-rs/examples/repeating-timer-with-initial-delay.rs b/crates/magics/examples/repeating-timer-with-initial-delay.rs similarity index 100% rename from crates/gbpplanner-rs/examples/repeating-timer-with-initial-delay.rs rename to crates/magics/examples/repeating-timer-with-initial-delay.rs diff --git a/crates/gbpplanner-rs/examples/rrt3d.rs b/crates/magics/examples/rrt3d.rs similarity index 99% rename from crates/gbpplanner-rs/examples/rrt3d.rs rename to crates/magics/examples/rrt3d.rs index 61d74296..c53bb55e 100644 --- a/crates/gbpplanner-rs/examples/rrt3d.rs +++ b/crates/magics/examples/rrt3d.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; use bevy_infinite_grid::{InfiniteGridBundle, InfiniteGridPlugin, InfiniteGridSettings}; use catppuccin::Flavour; use gbp_environment::Environment; -use gbpplanner_rs::{ +use magics::{ asset_loader::AssetLoaderPlugin, cli, config::{read_config, Config, FormationGroup}, diff --git a/crates/gbpplanner-rs/examples/rrtenv.rs b/crates/magics/examples/rrtenv.rs similarity index 99% rename from crates/gbpplanner-rs/examples/rrtenv.rs rename to crates/magics/examples/rrtenv.rs index df0391f6..4c0dbee1 100644 --- a/crates/gbpplanner-rs/examples/rrtenv.rs +++ b/crates/magics/examples/rrtenv.rs @@ -10,7 +10,7 @@ use bevy_infinite_grid::InfiniteGridSettings; use bevy_notify::NotifyPlugin; use derive_more::Index; use gbp_environment::Environment; -use gbpplanner_rs::{ +use magics::{ asset_loader::{AssetLoaderPlugin, Fonts}, cli, config::{read_config, Config, FormationGroup, RrtSection}, diff --git a/crates/gbpplanner-rs/examples/rrtstarenv.rs b/crates/magics/examples/rrtstarenv.rs similarity index 99% rename from crates/gbpplanner-rs/examples/rrtstarenv.rs rename to crates/magics/examples/rrtstarenv.rs index ca660b96..6e88dced 100644 --- a/crates/gbpplanner-rs/examples/rrtstarenv.rs +++ b/crates/magics/examples/rrtstarenv.rs @@ -10,7 +10,7 @@ use gbp_config::Config; use gbp_global_planner::{ rrtstar::spawn_pathfinding_task, Colliders, Path, PathFinder, PathfindingTask, }; -use gbpplanner_rs::{ +use magics::{ asset_loader::AssetLoaderPlugin, environment::EnvironmentPlugin, input::{camera::CameraInputPlugin, general::GeneralInputPlugin, ChangingBinding}, diff --git a/crates/gbpplanner-rs/examples/schedule-paint.rs b/crates/magics/examples/schedule-paint.rs similarity index 100% rename from crates/gbpplanner-rs/examples/schedule-paint.rs rename to crates/magics/examples/schedule-paint.rs diff --git a/crates/gbpplanner-rs/examples/switch-sdf-image.rs b/crates/magics/examples/switch-sdf-image.rs similarity index 100% rename from crates/gbpplanner-rs/examples/switch-sdf-image.rs rename to crates/magics/examples/switch-sdf-image.rs diff --git a/crates/gbpplanner-rs/examples/system-set-run-if.rs b/crates/magics/examples/system-set-run-if.rs similarity index 100% rename from crates/gbpplanner-rs/examples/system-set-run-if.rs rename to crates/magics/examples/system-set-run-if.rs diff --git a/crates/gbpplanner-rs/src/asset_loader.rs b/crates/magics/src/asset_loader.rs similarity index 100% rename from crates/gbpplanner-rs/src/asset_loader.rs rename to crates/magics/src/asset_loader.rs diff --git a/crates/gbpplanner-rs/src/bevy_utils.rs b/crates/magics/src/bevy_utils.rs similarity index 100% rename from crates/gbpplanner-rs/src/bevy_utils.rs rename to crates/magics/src/bevy_utils.rs diff --git a/crates/gbpplanner-rs/src/bin/2d_shapes.rs b/crates/magics/src/bin/2d_shapes.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/2d_shapes.rs rename to crates/magics/src/bin/2d_shapes.rs diff --git a/crates/gbpplanner-rs/src/bin/3d-shapes.rs b/crates/magics/src/bin/3d-shapes.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/3d-shapes.rs rename to crates/magics/src/bin/3d-shapes.rs diff --git a/crates/gbpplanner-rs/src/bin/console.rs b/crates/magics/src/bin/console.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/console.rs rename to crates/magics/src/bin/console.rs diff --git a/crates/gbpplanner-rs/src/bin/create-empty-environment.rs b/crates/magics/src/bin/create-empty-environment.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/create-empty-environment.rs rename to crates/magics/src/bin/create-empty-environment.rs diff --git a/crates/gbpplanner-rs/src/bin/create-signed-distance-field.rs b/crates/magics/src/bin/create-signed-distance-field.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/create-signed-distance-field.rs rename to crates/magics/src/bin/create-signed-distance-field.rs diff --git a/crates/gbpplanner-rs/src/bin/dock.rs b/crates/magics/src/bin/dock.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/dock.rs rename to crates/magics/src/bin/dock.rs diff --git a/crates/gbpplanner-rs/src/bin/draw2d.rs b/crates/magics/src/bin/draw2d.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/draw2d.rs rename to crates/magics/src/bin/draw2d.rs diff --git a/crates/gbpplanner-rs/src/bin/egui-matrix.rs b/crates/magics/src/bin/egui-matrix.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/egui-matrix.rs rename to crates/magics/src/bin/egui-matrix.rs diff --git a/crates/gbpplanner-rs/src/bin/gizmos.rs b/crates/magics/src/bin/gizmos.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/gizmos.rs rename to crates/magics/src/bin/gizmos.rs diff --git a/crates/gbpplanner-rs/src/bin/repeating-timers.rs b/crates/magics/src/bin/repeating-timers.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/repeating-timers.rs rename to crates/magics/src/bin/repeating-timers.rs diff --git a/crates/gbpplanner-rs/src/bin/schedule-paint.rs b/crates/magics/src/bin/schedule-paint.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/schedule-paint.rs rename to crates/magics/src/bin/schedule-paint.rs diff --git a/crates/gbpplanner-rs/src/bin/test-stable-indices-of-petgraph.rs b/crates/magics/src/bin/test-stable-indices-of-petgraph.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/test-stable-indices-of-petgraph.rs rename to crates/magics/src/bin/test-stable-indices-of-petgraph.rs diff --git a/crates/gbpplanner-rs/src/bin/wasm.rs b/crates/magics/src/bin/wasm.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/wasm.rs rename to crates/magics/src/bin/wasm.rs diff --git a/crates/gbpplanner-rs/src/bin/za-warudo.rs b/crates/magics/src/bin/za-warudo.rs similarity index 100% rename from crates/gbpplanner-rs/src/bin/za-warudo.rs rename to crates/magics/src/bin/za-warudo.rs diff --git a/crates/gbpplanner-rs/src/cli.rs b/crates/magics/src/cli.rs similarity index 100% rename from crates/gbpplanner-rs/src/cli.rs rename to crates/magics/src/cli.rs diff --git a/crates/gbpplanner-rs/src/despawn_entity_after.rs b/crates/magics/src/despawn_entity_after.rs similarity index 100% rename from crates/gbpplanner-rs/src/despawn_entity_after.rs rename to crates/magics/src/despawn_entity_after.rs diff --git a/crates/gbpplanner-rs/src/diagnostic/mod.rs b/crates/magics/src/diagnostic/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/diagnostic/mod.rs rename to crates/magics/src/diagnostic/mod.rs diff --git a/crates/gbpplanner-rs/src/diagnostic/robot.rs b/crates/magics/src/diagnostic/robot.rs similarity index 100% rename from crates/gbpplanner-rs/src/diagnostic/robot.rs rename to crates/magics/src/diagnostic/robot.rs diff --git a/crates/gbpplanner-rs/src/environment/camera.rs b/crates/magics/src/environment/camera.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/camera.rs rename to crates/magics/src/environment/camera.rs diff --git a/crates/gbpplanner-rs/src/environment/cursor.rs b/crates/magics/src/environment/cursor.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/cursor.rs rename to crates/magics/src/environment/cursor.rs diff --git a/crates/gbpplanner-rs/src/environment/follow_cameras.rs b/crates/magics/src/environment/follow_cameras.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/follow_cameras.rs rename to crates/magics/src/environment/follow_cameras.rs diff --git a/crates/gbpplanner-rs/src/environment/map.rs b/crates/magics/src/environment/map.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/map.rs rename to crates/magics/src/environment/map.rs diff --git a/crates/gbpplanner-rs/src/environment/map_generator.rs b/crates/magics/src/environment/map_generator.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/map_generator.rs rename to crates/magics/src/environment/map_generator.rs diff --git a/crates/gbpplanner-rs/src/environment/mod.rs b/crates/magics/src/environment/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/environment/mod.rs rename to crates/magics/src/environment/mod.rs diff --git a/crates/gbpplanner-rs/src/escape_codes.rs b/crates/magics/src/escape_codes.rs similarity index 100% rename from crates/gbpplanner-rs/src/escape_codes.rs rename to crates/magics/src/escape_codes.rs diff --git a/crates/gbpplanner-rs/src/export.rs b/crates/magics/src/export.rs similarity index 100% rename from crates/gbpplanner-rs/src/export.rs rename to crates/magics/src/export.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/dynamic.rs b/crates/magics/src/factorgraph/factor/dynamic.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/dynamic.rs rename to crates/magics/src/factorgraph/factor/dynamic.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/interrobot.rs b/crates/magics/src/factorgraph/factor/interrobot.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/interrobot.rs rename to crates/magics/src/factorgraph/factor/interrobot.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/marginalise_factor_distance.rs b/crates/magics/src/factorgraph/factor/marginalise_factor_distance.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/marginalise_factor_distance.rs rename to crates/magics/src/factorgraph/factor/marginalise_factor_distance.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/mod.rs b/crates/magics/src/factorgraph/factor/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/mod.rs rename to crates/magics/src/factorgraph/factor/mod.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/obstacle.rs b/crates/magics/src/factorgraph/factor/obstacle.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/obstacle.rs rename to crates/magics/src/factorgraph/factor/obstacle.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/pose.rs b/crates/magics/src/factorgraph/factor/pose.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/pose.rs rename to crates/magics/src/factorgraph/factor/pose.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/tracking.rs b/crates/magics/src/factorgraph/factor/tracking.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/tracking.rs rename to crates/magics/src/factorgraph/factor/tracking.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factor/velocity.rs b/crates/magics/src/factorgraph/factor/velocity.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factor/velocity.rs rename to crates/magics/src/factorgraph/factor/velocity.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/factorgraph.rs b/crates/magics/src/factorgraph/factorgraph.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/factorgraph.rs rename to crates/magics/src/factorgraph/factorgraph.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/graphviz.rs b/crates/magics/src/factorgraph/graphviz.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/graphviz.rs rename to crates/magics/src/factorgraph/graphviz.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/id.rs b/crates/magics/src/factorgraph/id.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/id.rs rename to crates/magics/src/factorgraph/id.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/message.rs b/crates/magics/src/factorgraph/message.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/message.rs rename to crates/magics/src/factorgraph/message.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/mod.rs b/crates/magics/src/factorgraph/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/mod.rs rename to crates/magics/src/factorgraph/mod.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/node.rs b/crates/magics/src/factorgraph/node.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/node.rs rename to crates/magics/src/factorgraph/node.rs diff --git a/crates/gbpplanner-rs/src/factorgraph/variable.rs b/crates/magics/src/factorgraph/variable.rs similarity index 100% rename from crates/gbpplanner-rs/src/factorgraph/variable.rs rename to crates/magics/src/factorgraph/variable.rs diff --git a/crates/gbpplanner-rs/src/goal_area.rs b/crates/magics/src/goal_area.rs similarity index 100% rename from crates/gbpplanner-rs/src/goal_area.rs rename to crates/magics/src/goal_area.rs diff --git a/crates/gbpplanner-rs/src/input/camera.rs b/crates/magics/src/input/camera.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/camera.rs rename to crates/magics/src/input/camera.rs diff --git a/crates/gbpplanner-rs/src/input/general.rs b/crates/magics/src/input/general.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/general.rs rename to crates/magics/src/input/general.rs diff --git a/crates/gbpplanner-rs/src/input/mod.rs b/crates/magics/src/input/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/mod.rs rename to crates/magics/src/input/mod.rs diff --git a/crates/gbpplanner-rs/src/input/moveable_object.rs b/crates/magics/src/input/moveable_object.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/moveable_object.rs rename to crates/magics/src/input/moveable_object.rs diff --git a/crates/gbpplanner-rs/src/input/screenshot.rs b/crates/magics/src/input/screenshot.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/screenshot.rs rename to crates/magics/src/input/screenshot.rs diff --git a/crates/gbpplanner-rs/src/input/ui.rs b/crates/magics/src/input/ui.rs similarity index 100% rename from crates/gbpplanner-rs/src/input/ui.rs rename to crates/magics/src/input/ui.rs diff --git a/crates/gbpplanner-rs/src/lib.rs b/crates/magics/src/lib.rs similarity index 100% rename from crates/gbpplanner-rs/src/lib.rs rename to crates/magics/src/lib.rs diff --git a/crates/gbpplanner-rs/src/macros.rs b/crates/magics/src/macros.rs similarity index 100% rename from crates/gbpplanner-rs/src/macros.rs rename to crates/magics/src/macros.rs diff --git a/crates/gbpplanner-rs/src/main.rs b/crates/magics/src/main.rs similarity index 99% rename from crates/gbpplanner-rs/src/main.rs rename to crates/magics/src/main.rs index 63b30447..deb53955 100644 --- a/crates/gbpplanner-rs/src/main.rs +++ b/crates/magics/src/main.rs @@ -51,7 +51,7 @@ use colored::Colorize; use gbp_config::{read_config, Config, FormationGroup}; // use config::{environment::EnvironmentType, Environment}; use gbp_environment::{Environment, EnvironmentType}; -use gbpplanner_rs::AppState; +use magics::AppState; use crate::cli::DumpDefault; diff --git a/crates/gbpplanner-rs/src/moveable_object.rs b/crates/magics/src/moveable_object.rs similarity index 100% rename from crates/gbpplanner-rs/src/moveable_object.rs rename to crates/magics/src/moveable_object.rs diff --git a/crates/gbpplanner-rs/src/movement.rs b/crates/magics/src/movement.rs similarity index 100% rename from crates/gbpplanner-rs/src/movement.rs rename to crates/magics/src/movement.rs diff --git a/crates/gbpplanner-rs/src/pause_play.rs b/crates/magics/src/pause_play.rs similarity index 100% rename from crates/gbpplanner-rs/src/pause_play.rs rename to crates/magics/src/pause_play.rs diff --git a/crates/gbpplanner-rs/src/planner/collisions.rs b/crates/magics/src/planner/collisions.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/collisions.rs rename to crates/magics/src/planner/collisions.rs diff --git a/crates/gbpplanner-rs/src/planner/mission.rs b/crates/magics/src/planner/mission.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/mission.rs rename to crates/magics/src/planner/mission.rs diff --git a/crates/gbpplanner-rs/src/planner/mod.rs b/crates/magics/src/planner/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/mod.rs rename to crates/magics/src/planner/mod.rs diff --git a/crates/gbpplanner-rs/src/planner/robot.rs b/crates/magics/src/planner/robot.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/robot.rs rename to crates/magics/src/planner/robot.rs diff --git a/crates/gbpplanner-rs/src/planner/spawner.rs b/crates/magics/src/planner/spawner.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/spawner.rs rename to crates/magics/src/planner/spawner.rs diff --git a/crates/gbpplanner-rs/src/planner/tracking.rs b/crates/magics/src/planner/tracking.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/tracking.rs rename to crates/magics/src/planner/tracking.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/collider.rs b/crates/magics/src/planner/visualiser/collider.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/collider.rs rename to crates/magics/src/planner/visualiser/collider.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/communication.rs b/crates/magics/src/planner/visualiser/communication.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/communication.rs rename to crates/magics/src/planner/visualiser/communication.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/communication_radius.rs b/crates/magics/src/planner/visualiser/communication_radius.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/communication_radius.rs rename to crates/magics/src/planner/visualiser/communication_radius.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/factorgraphs.rs b/crates/magics/src/planner/visualiser/factorgraphs.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/factorgraphs.rs rename to crates/magics/src/planner/visualiser/factorgraphs.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/interrobot.rs b/crates/magics/src/planner/visualiser/interrobot.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/interrobot.rs rename to crates/magics/src/planner/visualiser/interrobot.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/mod.rs b/crates/magics/src/planner/visualiser/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/mod.rs rename to crates/magics/src/planner/visualiser/mod.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/obstacle.rs b/crates/magics/src/planner/visualiser/obstacle.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/obstacle.rs rename to crates/magics/src/planner/visualiser/obstacle.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/robot.rs b/crates/magics/src/planner/visualiser/robot.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/robot.rs rename to crates/magics/src/planner/visualiser/robot.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/tracer.rs b/crates/magics/src/planner/visualiser/tracer.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/tracer.rs rename to crates/magics/src/planner/visualiser/tracer.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/tracking.rs b/crates/magics/src/planner/visualiser/tracking.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/tracking.rs rename to crates/magics/src/planner/visualiser/tracking.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/uncertainty.rs b/crates/magics/src/planner/visualiser/uncertainty.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/uncertainty.rs rename to crates/magics/src/planner/visualiser/uncertainty.rs diff --git a/crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs b/crates/magics/src/planner/visualiser/waypoints.rs similarity index 100% rename from crates/gbpplanner-rs/src/planner/visualiser/waypoints.rs rename to crates/magics/src/planner/visualiser/waypoints.rs diff --git a/crates/gbpplanner-rs/src/prng.rs b/crates/magics/src/prng.rs similarity index 100% rename from crates/gbpplanner-rs/src/prng.rs rename to crates/magics/src/prng.rs diff --git a/crates/gbpplanner-rs/src/run_conditions.rs b/crates/magics/src/run_conditions.rs similarity index 100% rename from crates/gbpplanner-rs/src/run_conditions.rs rename to crates/magics/src/run_conditions.rs diff --git a/crates/gbpplanner-rs/src/simulation_loader.rs b/crates/magics/src/simulation_loader.rs similarity index 99% rename from crates/gbpplanner-rs/src/simulation_loader.rs rename to crates/magics/src/simulation_loader.rs index d03960be..cf080da5 100644 --- a/crates/gbpplanner-rs/src/simulation_loader.rs +++ b/crates/magics/src/simulation_loader.rs @@ -161,7 +161,7 @@ impl Plugin for SimulationLoaderPlugin { .expect("it all just works"); // let sdf_path = PathBuf::new() - // .join("crates/gbpplanner-rs/assets/imgs/obstacles") + // .join("crates/magics/assets/imgs/obstacles") // .join(format!("{}.sdf.png", config.environment_image)); // info!("sdf_path: {sdf_path:?}"); // let sdf_image_buffer = @@ -173,7 +173,7 @@ impl Plugin for SimulationLoaderPlugin { // ); // let raw_path = PathBuf::new() - // .join("crates/gbpplanner-rs/assets/imgs/obstacles") + // .join("crates/magics/assets/imgs/obstacles") // .join(format!("{}.png", config.environment_image)); // let raw_image_buffer = // image::io::Reader::open(raw_path).unwrap().decode().unwrap(); diff --git a/crates/gbpplanner-rs/src/theme.rs b/crates/magics/src/theme.rs similarity index 100% rename from crates/gbpplanner-rs/src/theme.rs rename to crates/magics/src/theme.rs diff --git a/crates/gbpplanner-rs/src/ui/controls.rs b/crates/magics/src/ui/controls.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/controls.rs rename to crates/magics/src/ui/controls.rs diff --git a/crates/gbpplanner-rs/src/ui/custom.rs b/crates/magics/src/ui/custom.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/custom.rs rename to crates/magics/src/ui/custom.rs diff --git a/crates/gbpplanner-rs/src/ui/data.rs b/crates/magics/src/ui/data.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/data.rs rename to crates/magics/src/ui/data.rs diff --git a/crates/gbpplanner-rs/src/ui/decoration.rs b/crates/magics/src/ui/decoration.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/decoration.rs rename to crates/magics/src/ui/decoration.rs diff --git a/crates/gbpplanner-rs/src/ui/diagnostics.rs b/crates/magics/src/ui/diagnostics.rs similarity index 56% rename from crates/gbpplanner-rs/src/ui/diagnostics.rs rename to crates/magics/src/ui/diagnostics.rs index cf5d17d7..f8826b22 100644 --- a/crates/gbpplanner-rs/src/ui/diagnostics.rs +++ b/crates/magics/src/ui/diagnostics.rs @@ -1,6 +1,7 @@ -use bevy::diagnostic::DiagnosticsStore; -use bevy::diagnostic::FrameTimeDiagnosticsPlugin; -use bevy::prelude::*; +use bevy::{ + diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}, + prelude::*, +}; use crate::asset_loader::SceneAssets; @@ -30,67 +31,61 @@ fn setup_fps_counter_system(mut commands: Commands, scene_assets: Res Color { // // Above 120 FPS, use green color // 120.0.. => Color::rgb(0.0, 1.0, 0.0), // // Between 60-120 FPS, gradually transition from yellow to green - // 60.0.. => Color::rgb((1.0 - (fps - 60.0) / (120.0 - 60.0)) as f32, 1.0, 0.0), - // // Between 30-60 FPS, gradually transition from red to yellow - // 30.0.. => Color::rgb(1.0, ((fps - 30.0) / (60.0 - 30.0)) as f32, 0.0), - // // Below 30 FPS, use red color + // 60.0.. => Color::rgb((1.0 - (fps - 60.0) / (120.0 - 60.0)) as f32, + // 1.0, 0.0), // Between 30-60 FPS, gradually transition from red to + // yellow 30.0.. => Color::rgb(1.0, ((fps - 30.0) / (60.0 - 30.0)) + // as f32, 0.0), // Below 30 FPS, use red color // _ => Color::rgb(1.0, 0.0, 0.0), // } } @@ -141,9 +136,9 @@ fn update_fps_text_system( // // Above 120 FPS, use green color // Color::rgb(0.0, 1.0, 0.0) // } else if value >= 60.0 { - // // Between 60-120 FPS, gradually transition from yellow to green - // Color::rgb((1.0 - (value - 60.0) / (120.0 - 60.0)) as f32, 1.0, 0.0) - // } else if value >= 30.0 { + // // Between 60-120 FPS, gradually transition from yellow to + // green Color::rgb((1.0 - (value - 60.0) / (120.0 - + // 60.0)) as f32, 1.0, 0.0) } else if value >= 30.0 { // // Between 30-60 FPS, gradually transition from red to yellow // Color::rgb(1.0, ((value - 30.0) / (60.0 - 30.0)) as f32, 0.0) // } else { diff --git a/crates/gbpplanner-rs/src/ui/metrics.rs b/crates/magics/src/ui/metrics.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/metrics.rs rename to crates/magics/src/ui/metrics.rs diff --git a/crates/gbpplanner-rs/src/ui/mod.rs b/crates/magics/src/ui/mod.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/mod.rs rename to crates/magics/src/ui/mod.rs diff --git a/crates/gbpplanner-rs/src/ui/scale.rs b/crates/magics/src/ui/scale.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/scale.rs rename to crates/magics/src/ui/scale.rs diff --git a/crates/gbpplanner-rs/src/ui/selected_entity.rs b/crates/magics/src/ui/selected_entity.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/selected_entity.rs rename to crates/magics/src/ui/selected_entity.rs diff --git a/crates/gbpplanner-rs/src/ui/settings.rs b/crates/magics/src/ui/settings.rs similarity index 100% rename from crates/gbpplanner-rs/src/ui/settings.rs rename to crates/magics/src/ui/settings.rs diff --git a/crates/gbpplanner-rs/src/utils.rs b/crates/magics/src/utils.rs similarity index 100% rename from crates/gbpplanner-rs/src/utils.rs rename to crates/magics/src/utils.rs diff --git a/scripts/analyse-iteration-amount-experiment.ipynb b/scripts/analyse-iteration-amount-experiment.ipynb new file mode 100644 index 00000000..a8a8124d --- /dev/null +++ b/scripts/analyse-iteration-amount-experiment.ipynb @@ -0,0 +1,1052 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
sys.executable = '/home/kpbaks/.nix-profile/bin/python'\n",
+       "
\n" + ], + "text/plain": [ + "sys.executable = \u001b[32m'/home/kpbaks/.nix-profile/bin/python'\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
sys.version = '3.11.9 (main, Apr  2 2024, 08:25:04) [GCC 13.2.0]'\n",
+       "
\n" + ], + "text/plain": [ + "sys.version = \u001b[32m'3.11.9 \u001b[0m\u001b[32m(\u001b[0m\u001b[32mmain, Apr 2 2024, 08:25:04\u001b[0m\u001b[32m)\u001b[0m\u001b[32m \u001b[0m\u001b[32m[\u001b[0m\u001b[32mGCC 13.2.0\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import sys\n", + "import os\n", + "\n", + "sys.path.append('scripts')\n", + "\n", + "import re\n", + "import json\n", + "import argparse\n", + "import itertools\n", + "from pathlib import Path\n", + "import collections\n", + "from dataclasses import dataclass,asdict, astuple\n", + "from concurrent.futures import ProcessPoolExecutor\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "# from matplotlib.font_manager import FontProperties\n", + "import matplotlib.font_manager as fm\n", + "from matplotlib.patches import FancyBboxPatch\n", + "from matplotlib.patches import PathPatch\n", + "from matplotlib.path import get_path_collection_extents\n", + "from matplotlib.colors import LinearSegmentedColormap, LogNorm\n", + "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", + "import seaborn as sns\n", + "\n", + "from rich import print, pretty\n", + "from typing import Iterable\n", + "import pretty_errors\n", + "from catppuccin import PALETTE\n", + "\n", + "from utils import *\n", + "from ldj import ldj\n", + "\n", + "pretty.install()\n", + "\n", + "RESULT_DIR: Path = Path(\"../experiments/iteration-amount\")\n", + "\n", + "assert RESULT_DIR.is_dir() and RESULT_DIR.exists()\n", + "\n", + "\n", + "flavor = PALETTE.latte.colors\n", + "# num-robots-10-seed-0.json\n", + "RE = re.compile(r\"internal-(\\d+)-external-(\\d+)-seed-(\\d+).json\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
STIX Two Text\n",
+       "
\n" + ], + "text/plain": [ + "STIX Two Text\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# use LaTeX for text with matplotlib\n", + "sns.set_style(\"darkgrid\")\n", + "# set background color of sns darkgrid to flavor.base.hex\n", + "plt.rcParams['axes.facecolor'] = flavor.base.hex\n", + "# set font color to flavor.text.hex\n", + "plt.rcParams['text.color'] = flavor.text.hex\n", + "\n", + "font_dirs = [\"./fonts/\"]\n", + "# go through all fonts in the font directory and add them\n", + "for font_dir in font_dirs:\n", + " for font in os.listdir(font_dir):\n", + " fm.fontManager.addfont(f\"{font_dir}/{font}\")\n", + "\n", + "prop_jbm = fm.FontProperties(fname='./fonts/JetBrainsMonoNerdFontMono-Regular.ttf')\n", + "prop = fm.FontProperties(fname='./fonts/STIXTwoText-VariableFont_wght.ttf')\n", + "\n", + "plt.rcParams.update({\n", + " # \"text.usetex\": True,\n", + " \"font.family\": prop.get_name(),\n", + " # \"font.family\": \"stix\",\n", + " # \"font.sans-serif\": prop.get_name(),\n", + " \"mathtext.fontset\": \"stix\",\n", + " # \"text.latex.preamble\": r\"\\usepackage{fontenc}\\usepackage{fontspec}\\setmainfont{JetBrainsMonoNerdFontMono-Regular}\",\n", + "})\n", + "\n", + "print(prop.get_name())\n", + "\n", + "colors = [\n", + " (flavor.lavender.hex, 1.0, (1, 0), 'o'),\n", + " (flavor.yellow.hex, 0.3, (2, 2), 'X'),\n", + " (flavor.peach.hex, 0.3, (2, 2), 'X'),\n", + " (flavor.green.hex, 1.0, (2, 2), '^')\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def flatten(lst: Iterable) -> list:\n", + " return list(itertools.chain.from_iterable(lst))\n", + "\n", + "\n", + "@dataclass(frozen=True)\n", + "class ExperimentParams:\n", + " internal: int\n", + " external: int\n", + " seed: int\n", + "\n", + "@dataclass\n", + "class ProcessedData:\n", + " distance_travelled: list[float]\n", + " finished_at: list[float]\n", + " ldj: list[float]\n", + " makespan: float\n", + " robot_collisions: int\n", + " params: ExperimentParams\n", + "\n", + "\n", + "def process_file(file) -> ProcessedData:\n", + " match = RE.match(file.name)\n", + " assert match is not None\n", + " internal = int(match.group(1))\n", + " external = int(match.group(2))\n", + " seed = int(match.group(3))\n", + "\n", + " with open(file, 'r') as file:\n", + " data = json.load(file)\n", + "\n", + " distance_travelled_of_each_robot: list[float] = []\n", + " finished_at_of_each_robot: list[float] = []\n", + " ldj_of_each_robot: list[float] = []\n", + " robot_collisions: int = len(data['collisions']['robots'])\n", + " environment_collisions: int = len(data['collisions']['environment'])\n", + "\n", + " for _, robot_data in data['robots'].items():\n", + " positions = np.array(robot_data['positions'])\n", + " distance_travelled: float = np.sum(np.linalg.norm(np.diff(positions, axis=0), axis=1))\n", + " distance_travelled_of_each_robot.append(distance_travelled)\n", + "\n", + " mission = robot_data['mission']\n", + " # robot_collisions += robot_data['collisions']['robots']\n", + "\n", + " started_at: float = mission['started_at']\n", + " finished_at: float = mission['finished_at'] if mission['finished_at'] else mission['duration'] + started_at\n", + " finished_at_of_each_robot.append(finished_at)\n", + "\n", + " timestamps: np.ndarray = np.array([measurement['timestamp'] for measurement in robot_data['velocities']])\n", + " velocities3d_bevy: np.ndarray = np.array([measurement['velocity'] for measurement in robot_data['velocities']])\n", + " velocities = velocities3d_bevy[:, [0, 2]]\n", + "\n", + " ldj_metric = ldj(velocities, timestamps)\n", + " ldj_of_each_robot.append(ldj_metric)\n", + "\n", + " makespan: float = data['makespan']\n", + "\n", + " params = ExperimentParams(\n", + " internal=internal,\n", + " external=external,\n", + " seed=seed\n", + " )\n", + "\n", + " return ProcessedData(\n", + " distance_travelled=distance_travelled_of_each_robot,\n", + " finished_at=finished_at_of_each_robot,\n", + " ldj=ldj_of_each_robot,\n", + " robot_collisions=robot_collisions,\n", + " makespan=makespan,\n", + " params=params\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
np.max(data.finished_at)=102.1 key=(1, 13)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mnp.max\u001b[0m\u001b[1m(\u001b[0mdata.finished_at\u001b[1m)\u001b[0m=\u001b[1;36m102.1\u001b[0m \u001b[33mkey\u001b[0m=\u001b[1m(\u001b[0m\u001b[1;36m1\u001b[0m, \u001b[1;36m13\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "processed_data: list[ProcessedData] = []\n", + "with ProcessPoolExecutor() as executor:\n", + " results = executor.map(process_file, RESULT_DIR.glob('*.json'))\n", + "\n", + "aggregated_data: dict[tuple[int, int], ProcessedData] = {}\n", + "for data in results:\n", + " key = (data.params.internal, data.params.external)\n", + " if key in aggregated_data:\n", + " aggregated_data[key].distance_travelled.extend(data.distance_travelled)\n", + " if np.max(data.finished_at) < 100:\n", + " aggregated_data[key].finished_at.extend(data.finished_at)\n", + " else:\n", + " print(f\"{np.max(data.finished_at)=} {key=}\")\n", + " aggregated_data[key].ldj.extend(data.ldj)\n", + " # aggregated_data[key].ldj.extend(data.ldj)\n", + " current = aggregated_data[key].robot_collisions\n", + " aggregated_data[key].robot_collisions = (current + data.robot_collisions) / 2\n", + " current = aggregated_data[key].makespan\n", + " aggregated_data[key].makespan = (current + data.makespan) / 2\n", + " else:\n", + " aggregated_data[key] = data\n", + "\n", + "\n", + "processed_data = aggregated_data.values()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
extent=[1, 34, 1, 34] nrows=8 ncols=8\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mextent\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;36m1\u001b[0m, \u001b[1;36m34\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m \u001b[33mnrows\u001b[0m=\u001b[1;36m8\u001b[0m \u001b[33mncols\u001b[0m=\u001b[1;36m8\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
xticks=array([ 1,  2,  3,  5,  8, 13, 21, 34])\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mxticks\u001b[0m=\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m5\u001b[0m, \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
yticks=array([ 1,  2,  3,  5,  8, 13, 21, 34])\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33myticks\u001b[0m=\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m3\u001b[0m, \u001b[1;36m5\u001b[0m, \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# def as_grid_index(internal: int, external: int) -> (int, int):\n", + "# assert internal % 5 == 0\n", + "# assert external % 5 == 0\n", + "# return (int(internal / 5) - 1, int(external / 5) - 1)\n", + "\n", + "\n", + "def minmax(arr: np.ndarray) -> (float, float):\n", + " return (np.min(arr), np.max(arr))\n", + "\n", + "\n", + "internals = set((it.params.internal for it in processed_data))\n", + "externals = set((it.params.external for it in processed_data))\n", + "nrows: int = len(internals)\n", + "ncols: int = len(externals)\n", + "\n", + "\n", + "# nrows: int = max((int(it.params.internal / 5) for it in processed_data))\n", + "# ncols: int = max((int(it.params.external / 5) for it in processed_data))\n", + "\n", + "extent: ((int, int), (int, int)) = (minmax([it.params.internal for it in processed_data]), minmax([it.params.external for it in processed_data]))\n", + "extent: list[int] = [*extent[0], *extent[1]]\n", + "\n", + "xticks = np.array(sorted(internals))\n", + "yticks = np.array(sorted(externals))\n", + "# xticks = np.arange(5, 35, 5)\n", + "# yticks = np.arange(5, 35, 5)\n", + "x, y = np.meshgrid(xticks, yticks)\n", + "\n", + "xtick_labels = [str(tick) for tick in xticks]\n", + "ytick_labels = [str(tick) for tick in yticks]\n", + "\n", + "def as_grid_index(params: ExperimentParams) -> (int, int):\n", + " x = np.where(xticks == params.internal)[0][0]\n", + " y = np.where(yticks == params.external)[0][0]\n", + " return (x, y)\n", + " # return (int(params.internal / 5) - 1, int(params.external / 5) - 1)\n", + "\n", + "print(f\"{extent=} {nrows=} {ncols=}\")\n", + "print(f\"{xticks=}\")\n", + "print(f\"{yticks=}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
as_grid_index(params)=(4, 1)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mas_grid_index\u001b[0m\u001b[1m(\u001b[0mparams\u001b[1m)\u001b[0m=\u001b[1m(\u001b[0m\u001b[1;36m4\u001b[0m, \u001b[1;36m1\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "params = ExperimentParams(internal=8, external=2, seed=0)\n", + "print(f\"{as_grid_index(params)=}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
it.finished_at=[231.9, 236.2, 234.2, 218.8, 227.4, 235.5, 229.5, 236.5, 225.2, 229.8, 233.6, 234.4, 230.6, 235.9, \n",
+       "235.5, 227.6, 226.5, 227.3, 234.0, 233.9, 235.7, 224.0, 227.5, 227.6, 233.0, 24.1, 27.9, 28.8, 34.9, 24.1, 30.0, \n",
+       "29.3, 26.8, 21.9, 28.8, 21.6, 29.3, 30.1, 30.3, 35.0, 28.0, 25.1, 23.1, 34.0, 29.3, 31.4, 30.7, 31.0, 24.3, 22.1]\n",
+       "
\n" + ], + "text/plain": [ + "it.\u001b[33mfinished_at\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;36m231.9\u001b[0m, \u001b[1;36m236.2\u001b[0m, \u001b[1;36m234.2\u001b[0m, \u001b[1;36m218.8\u001b[0m, \u001b[1;36m227.4\u001b[0m, \u001b[1;36m235.5\u001b[0m, \u001b[1;36m229.5\u001b[0m, \u001b[1;36m236.5\u001b[0m, \u001b[1;36m225.2\u001b[0m, \u001b[1;36m229.8\u001b[0m, \u001b[1;36m233.6\u001b[0m, \u001b[1;36m234.4\u001b[0m, \u001b[1;36m230.6\u001b[0m, \u001b[1;36m235.9\u001b[0m, \n", + "\u001b[1;36m235.5\u001b[0m, \u001b[1;36m227.6\u001b[0m, \u001b[1;36m226.5\u001b[0m, \u001b[1;36m227.3\u001b[0m, \u001b[1;36m234.0\u001b[0m, \u001b[1;36m233.9\u001b[0m, \u001b[1;36m235.7\u001b[0m, \u001b[1;36m224.0\u001b[0m, \u001b[1;36m227.5\u001b[0m, \u001b[1;36m227.6\u001b[0m, \u001b[1;36m233.0\u001b[0m, \u001b[1;36m24.1\u001b[0m, \u001b[1;36m27.9\u001b[0m, \u001b[1;36m28.8\u001b[0m, \u001b[1;36m34.9\u001b[0m, \u001b[1;36m24.1\u001b[0m, \u001b[1;36m30.0\u001b[0m, \n", + "\u001b[1;36m29.3\u001b[0m, \u001b[1;36m26.8\u001b[0m, \u001b[1;36m21.9\u001b[0m, \u001b[1;36m28.8\u001b[0m, \u001b[1;36m21.6\u001b[0m, \u001b[1;36m29.3\u001b[0m, \u001b[1;36m30.1\u001b[0m, \u001b[1;36m30.3\u001b[0m, \u001b[1;36m35.0\u001b[0m, \u001b[1;36m28.0\u001b[0m, \u001b[1;36m25.1\u001b[0m, \u001b[1;36m23.1\u001b[0m, \u001b[1;36m34.0\u001b[0m, \u001b[1;36m29.3\u001b[0m, \u001b[1;36m31.4\u001b[0m, \u001b[1;36m30.7\u001b[0m, \u001b[1;36m31.0\u001b[0m, \u001b[1;36m24.3\u001b[0m, \u001b[1;36m22.1\u001b[0m\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
it.params=ExperimentParams(internal=13, external=1, seed=0)\n",
+       "
\n" + ], + "text/plain": [ + "it.\u001b[33mparams\u001b[0m=\u001b[1;35mExperimentParams\u001b[0m\u001b[1m(\u001b[0m\u001b[33minternal\u001b[0m=\u001b[1;36m13\u001b[0m, \u001b[33mexternal\u001b[0m=\u001b[1;36m1\u001b[0m, \u001b[33mseed\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
it.makespan=33.01803112030029\n",
+       "
\n" + ], + "text/plain": [ + "it.\u001b[33mmakespan\u001b[0m=\u001b[1;36m33\u001b[0m\u001b[1;36m.01803112030029\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
t_diff=13.399999999999999\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mt_diff\u001b[0m=\u001b[1;36m13\u001b[0m\u001b[1;36m.399999999999999\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "distance_travelled_avg_im: np.ndarray = np.zeros((nrows, ncols))\n", + "distance_travelled_median_im: np.ndarray = np.zeros((nrows, ncols))\n", + "ldj_im: np.ndarray = np.zeros((nrows, ncols))\n", + "makespan_im: np.ndarray = np.zeros((nrows, ncols), dtype=np.float64)\n", + "maximum_task_completion_time_difference_im = np.zeros((nrows, ncols))\n", + "robot_collisions_im = np.zeros((nrows, ncols), dtype=np.int32)\n", + "\n", + "for it in processed_data:\n", + " x, y = as_grid_index(it.params)\n", + " # print(f\"{it.distance_travelled.shape=}\")\n", + " # if x == 6 and y == 0:\n", + " # print(f\"{it.distance_travelled=}\")\n", + " \n", + " distance_travelled_avg: float = np.mean(np.sort(it.distance_travelled)[:-1])\n", + " distance_travelled_median: float = np.median(np.sort(it.distance_travelled)[:-1])\n", + " # print(f\"{it.params.internal=} {it.params.external=} {x=} {y=} {distance_travelled_avg=}\")\n", + " # print(f\"{x=}, {y=} = {distance_travelled_avg=}\")\n", + " distance_travelled_avg_im[x, y] = distance_travelled_avg\n", + " distance_travelled_median_im[x, y] = distance_travelled_median\n", + " ldj_avg: float = np.mean(np.sort(it.ldj)[:-1])\n", + " ldj_im[x, y] = ldj_avg\n", + "\n", + " t_min, t_max = minmax(np.sort(it.finished_at))\n", + " t_min, t_max = minmax(np.sort(it.finished_at))\n", + " t_diff = t_max - t_min\n", + " if t_diff > 100:\n", + " print(f\"{it.finished_at=}\")\n", + " print(f\"{it.params=}\")\n", + " print(f\"{it.makespan=}\")\n", + " stop = int(len(it.finished_at) / 2)\n", + " t_min, t_max = minmax(np.sort(it.finished_at)[0:stop])\n", + " t_diff = t_max - t_min\n", + " print(f\"{t_diff=}\")\n", + "\n", + " maximum_task_completion_time_difference_im[x, y] = t_diff\n", + " robot_collisions_im[x, y] = it.robot_collisions\n", + " makespan_im[x, y] = it.makespan\n", + " # if x == 4 and y == 1:\n", + " # print(f\"{distance_travelled_avg=}\")\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
maximum_task_completion_time_difference_im=array([[35.9, 22.2, 21.8, 21.5, 34.1, 35.1, 42. , 42.6],\n",
+       "       [15.7, 11.7, 24.3, 18. , 14.2, 15.1, 22.3, 28.9],\n",
+       "       [15.5, 17.4, 23.6, 13.2, 16. , 11.4, 20.4, 15. ],\n",
+       "       [16.7, 16.6, 11.3, 10.5, 17. , 11.5,  9.6, 10.6],\n",
+       "       [20.3, 13.5,  9. ,  9. , 11.9,  9. , 13.3, 15.7],\n",
+       "       [13.4,  9.4, 14.3,  6.9,  8.4,  9.7, 10.4,  8.5],\n",
+       "       [21.3, 12. ,  8.6,  7.5,  7.8,  8.9,  8.4,  9.8],\n",
+       "       [13.2, 10.9,  9.2, 10.9,  8.6, 11.4,  8.9, 10.6]])\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mmaximum_task_completion_time_difference_im\u001b[0m=\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1m[\u001b[0m\u001b[1;36m35.9\u001b[0m, \u001b[1;36m22.2\u001b[0m, \u001b[1;36m21.8\u001b[0m, \u001b[1;36m21.5\u001b[0m, \u001b[1;36m34.1\u001b[0m, \u001b[1;36m35.1\u001b[0m, \u001b[1;36m42\u001b[0m. , \u001b[1;36m42.6\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m15.7\u001b[0m, \u001b[1;36m11.7\u001b[0m, \u001b[1;36m24.3\u001b[0m, \u001b[1;36m18\u001b[0m. , \u001b[1;36m14.2\u001b[0m, \u001b[1;36m15.1\u001b[0m, \u001b[1;36m22.3\u001b[0m, \u001b[1;36m28.9\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m15.5\u001b[0m, \u001b[1;36m17.4\u001b[0m, \u001b[1;36m23.6\u001b[0m, \u001b[1;36m13.2\u001b[0m, \u001b[1;36m16\u001b[0m. , \u001b[1;36m11.4\u001b[0m, \u001b[1;36m20.4\u001b[0m, \u001b[1;36m15\u001b[0m. \u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m16.7\u001b[0m, \u001b[1;36m16.6\u001b[0m, \u001b[1;36m11.3\u001b[0m, \u001b[1;36m10.5\u001b[0m, \u001b[1;36m17\u001b[0m. , \u001b[1;36m11.5\u001b[0m, \u001b[1;36m9.6\u001b[0m, \u001b[1;36m10.6\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m20.3\u001b[0m, \u001b[1;36m13.5\u001b[0m, \u001b[1;36m9\u001b[0m. , \u001b[1;36m9\u001b[0m. , \u001b[1;36m11.9\u001b[0m, \u001b[1;36m9\u001b[0m. , \u001b[1;36m13.3\u001b[0m, \u001b[1;36m15.7\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m13.4\u001b[0m, \u001b[1;36m9.4\u001b[0m, \u001b[1;36m14.3\u001b[0m, \u001b[1;36m6.9\u001b[0m, \u001b[1;36m8.4\u001b[0m, \u001b[1;36m9.7\u001b[0m, \u001b[1;36m10.4\u001b[0m, \u001b[1;36m8.5\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m21.3\u001b[0m, \u001b[1;36m12\u001b[0m. , \u001b[1;36m8.6\u001b[0m, \u001b[1;36m7.5\u001b[0m, \u001b[1;36m7.8\u001b[0m, \u001b[1;36m8.9\u001b[0m, \u001b[1;36m8.4\u001b[0m, \u001b[1;36m9.8\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m\u001b[1;36m13.2\u001b[0m, \u001b[1;36m10.9\u001b[0m, \u001b[1;36m9.2\u001b[0m, \u001b[1;36m10.9\u001b[0m, \u001b[1;36m8.6\u001b[0m, \u001b[1;36m11.4\u001b[0m, \u001b[1;36m8.9\u001b[0m, \u001b[1;36m10.6\u001b[0m\u001b[1m]\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(f\"{maximum_task_completion_time_difference_im=}\")\n", + "# print(f\"{distance_travelled_avg_im[6,0]=}\")\n", + "\n", + "# print(f\"{maximum_task_completion_time_difference_im=}\")\n", + "\n", + "# distance_travelled_avg_im[0, 0] = 5000.0\n", + "# distance_travelled_avg_im[1, 0] = 5000.0\n", + "# distance_travelled_avg_im[0, 1] = 5000.0\n", + "# distance_travelled_avg_im[-1, -1] = 3000.0\n" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
image[6, 0]=116.05462795674353 image[0,0]=216.80088265039262 image[-1, -1]=108.05752734087528\n",
+       "
\n" + ], + "text/plain": [ + "image\u001b[1m[\u001b[0m\u001b[1;36m6\u001b[0m, \u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m=\u001b[1;36m116.05462795674353\u001b[0m image\u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m,\u001b[1;36m0\u001b[0m\u001b[1m]\u001b[0m=\u001b[1;36m216.80088265039262\u001b[0m image\u001b[1m[\u001b[0m\u001b[1;36m-1\u001b[0m, \u001b[1;36m-1\u001b[0m\u001b[1m]\u001b[0m=\u001b[1;36m108.05752734087528\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbgAAAFmCAYAAAAf/o/sAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABG/0lEQVR4nO3dd1iT5xoG8DsJew8BQVRwgIo4wT3OqbPWVWdxt66qbR3tsda9tbbWVQeOtk5U3ANH3bburVgVrTJkiggCAQLJ+QONRpCRQL4k3r/r8oJvvbkzzMO33lekUCgUICIiMjBioQMQERGVBhY4IiIySCxwRERkkFjgiIjIILHAERGRQWKBIyIig8QCR0REBokFjoiIDBILHBERGSQWOCIiASlexAodwWCJ2FWXqj925UCWLWwGR3ugWxsJtoXIkfBc2CxODkDvDmJm0eEsupaHWfLn6gx0b5v/PoVivBcgfVn0xsytIVrwoISSGS4joQPomqg4IDNL2AyvC+zTuNx/QsqSMYuuZwF0Kw+zqEH6EsgoRoGjIuEhSiIiMkgscEREZJBY4IiIyCCxwBERkUFigSMiIoPEAkdERAZJr24TWLRkA06cvJDvsrWBs+Di4qgyT6FQYOLkxYiJTcCKZVNgYWGujZhERKQD9KrAfdqlFVo0r6+czsnOQeDaYBgZSWBjY5ln/aN//o07oWGY9MNwFjciog+MXhU4D49y8PAoBwDIyZHjp4XrIJfLMWvGWJibm6msm5SUjN/X70aTxnXRqGFtIeISERWJ3NIRMDIt+gamVpCUXhyDoVcF7jW5XI7FS9cjNPQh5s8dB2cnhzzrBK7ZDiiA4UN7CZCQiEh3yGTZ2Bx0AKdPX0Jaega8vTwwZHAPVKzghi1BBxC0LSTPNpYW5ti6ZSEAoFPXkXmW9+rZHv37di717JrQywK378BJnDp9GXXrVEdEZAzKlXNRWX7p0i38fe46Ro3oAwcHW4FSEhHphh07j+DkqYsYNaIPHB3tsD34MGbOXolVy6cBALyqeuDbcYOU62/bfhgREdEqbXw7dhC8vDyU09ZWeU8L6Rq9vIrS0cEOzZvVR1qaFHPnr8aiJeuVy9KlGVgZuBU1qldGu7ZNAQDHjp9Hp64jEReXKFRkIiLB3AkNQ/dubdHA3xeVK5XHqBEBiI9PRFRULJydHVHN2xNurs5wc3WGUxkHXL12B+3aNlNpw9HBTrmOm6szrK11v8Dp5R5c82b10bxZ7sUme/Ydx7rfdqJN6yao6VMVGzfuxYvkVMyc8Q1EIpHASYmIhDdn1hiV6YyMTACAmZkpWrdqrLLs73PXkZWVjZYt/FTmT52xDGKxGPb2NmjR3A99AzpCItHtM4F6WeDe1rZNU6z7bSfCwsJR06cqLl2+DX+/mrC3s0FqajoAIFPo4QGIiEpBerpUZdrY2AjGxsaFbrc56CBq1/KGq6tTnmWHDp/Bf1r6q1y4t+LXqcrfIyKisXxlEKysLNCtaxsN0pc+vSpwZ/+6AmtrK9SpXU05z9TEBACQJZMp552/cAPnL9zQdjwiIq0aNHgSpNIM5XRA7w7oE9CxwG22BB3Atet3sXDB//IsC4+Ixt1/HuHL4b1V5pd3L6vye0RkLC5cuMkCV5KOHb+AhGdJ+HXJJIjFuacPwx6GAwDKueVeaPK/7wZDliVT2e7q9bvYueuodsMSEZWyP9bNUZk2Ni74Kz145xEcCDmNOTNHw9nZMc/yw4fPwtvbE54e7sp5WVkyPEtMgpurs3KeUxl7PE9K1jB96dOrAtfxk5aYOXsl5v24Bi1b+ONlahp27DgCNzdn+NX3AQBU8/bMs11cPC8uISLDU5wOLPbsO45du//E7Jmj4enpnmd5RmYWTp66hKFDeqrMj094jhGjZuC3NbPh9OqWrGfPkuBgr/tXqOtVgfP388XECcMQvPMIli7bCHMLM9Ty9cKAfl1gZlaMmySJiD4gh46cxfoNezFuzACYm5siOiYeAGBnZwOLV+faTp+5DJFYhGZN66ls6+bqBI+KblixKgh9AjoiMfEFDoScQo9u7bT+PIpLrwocADRuVAeNG9Up1jatWzXOc6UQEdGH4syZK8jOzsaCn39TmT/66/7K78bDh8/io/82gqmpico6YrEYEycMR+Ca7Zg8dQksLMzRvl1zdOr4X63lV5feFTgiIiqeeXPGFrrOooUT3rvM1dUJ06eOKslIWsECR0QksNy+KM0KX/E1U0v2RVkEetmTCRERUWFY4IiIyCCxwBERkUFigSMiIoPEAkdERAaJBY6IiAwSCxwRERkkFjgiIjJILHBERGSQWOCIiMggsauud7g4ArJsYTOUsc/9mc9wTVr3OgOzqNKlLIBu5WGW/L0aaYa0SKRQKBRChyAi+pBl/vIpkJVe9A1MLGA6bnfpBTIQ3IN7x5rtOTqxB9frYwk27ZND6LFanR2Bfp3FzKLDWXQtD7Pkr5wL0LsDzwppEwvcO+ISgcwsoVPkik8EnsYJnSIXs+RPl7IAupWHWVSZGAv7+B8i/jlBREQGiQWOiIgMEgscEREZJBY4IiIySCxwRERkkFjgiIjIILHAERGRQdK7++DCHoZjw8a9ePgoAkYSCby9PTFwQFeUdy+rXEehUGDHrqPYtHk/5HI55s4aA19fLwFTExGRtunVHlxkVCwmTPwF0oxMDB/aC4MGfoq4uGeYMPEXvHjxEgCQnJKKGbNWYNPm/WjUsLbAiYmISCh6tQd3MOQ0TEyMMXP617AwNwMA1KlTDV8MmYQTpy6gW9c2CAk5jcdPojB31hjI5XKcO39d4NRERAWTWzgCxhZF38DYvPTCGBC9KnA1farCq2pFZXEDAEcHO9hYWyEuLrejOW9vT3T4uAVsba1x+/YDoaISEZHA9KrANWtaL8+82NhnSE5JVZ6Dq1e3hrZjERGRDtKrc3DvksvlCFy7HbY2VvhPywZCxyEiIh2iV3tw71q9NhjXrt3FlEkjYGVVjOPXREQfEJksG5uDDuD06UtIS8+At5cHhgzugYoV3HDs+HksWbYxzzaBK6fDzdUZAJCY+AKr1wbj1u37MJJI4O9XE1983l3nv3f1tsD9sX43Qg6dwaiRfeBX30foOEREOmvHziM4eeoiRo3oA0dHO2wPPoyZs1di1fJpAABHRzvMnT1GZRtnpzfDoC/4eR3kcjmmTR6JzMwsrFy9DYFrtuPbsYO0+CyKTy8L3OagA9i5+098Oaw32rVpKnQcIiKddic0DN27tUUDf18AwKgRAeg7YDyiomIBABKxWLm39q60NCnu/vMIC38aD6+qHgCAfn064dcVm7WSXRN6V+B27DqKrdtCMHRIT3zSoaXQcYiIdN6cWWNUpjMyMgEAZmamAID4hOfo1vMbGEkkKOfuggH9uqBuneoAgNTUdACArY21cntbGyukpUm1kFwzelXgjv75N9Zv2AN/v5oo5+aMq9dClcusrSzh5eWByKhY5V8lERExAIC7/zxCalrum9S4UR2t5yYiKg3p6apFxtjYCMbGhQ8dvjnoIGrX8oarqxNsbKzg7e0JAMiWZePEqYuYPXcVVi6fBmcnB5Xt5s4PhItzGeWeoK7TqwIXevcRAODylTu4fOWOyrKaPlUxb85YnD17BUHbQlSWbdqyX/n7/j0rSj8oEZEWDBo8CVJphnI6oHcH9AnoWOA2W4IO4Nr1u1i44H8AAEtLc1havrlxfLCnOy5cuInr1++iXdtmKtuO/noAJEYShD14UnJPohTpVYEbO3oAxo4eUOA6fQI6FvoGExEZgj/WzVGZNjYu+Cs9eOcRHAg5jTkzR8PZOfciktfdHNrZvTkEWaaMPZ4npeTZ/u1CqA/0qsARERkiuZUDIMss+gbGuefOLCyKXnD27DuOXbv/xOyZo+Hp6a6cv3f/cTx4EI45s0Yr5yUmvoCDvQ0AKG8FSE55CRcXx1e/pyrP3+kyvb7Rm4iICnfoyFms37AXI7/8DObmpoiOiUd0TDzSpRlo1LA27oSGYd/+E3j8OAobNu5F0osU1H3VK5SlpTlqVK+MNWuDce/ev7h56z42bdmvF7dncQ+OiMjAnTlzBdnZ2Vjw828q80d/3R+tWzXGuDEDsXV7CDZs2ofy7mUxeeKXKheYjP9uMFavDcaM2Ssgl8vh7+eLL4f11vbTKDYWOCIiAzdvztgCl7ds4Y+WLfzfu9zR0Q4/fD+0pGPhn3uPUL1a5ULXe/wkCp4e7oWu9y4eoiQiIkHs3PVnkdbbu++EWu1zD46IiARx+cptjB43D5YWZu9dJyMzC48eRWDMNwVfQZ8fFjgiIhKEuZkZTIyNIJNlv3cdiVgMS0v1OnVmgSMiIkFUrlw+Tzdi+Zm/YI1a7fMcHBERCSIjI6tI62VmFm29d7HAERGRINLSpVAoFIWu9/x5slrts8AREZEgnMrY49btBwWuc+XKHdjaWhe4zvvwHNw7XByBAs53akUZ+9yfzo4Fr6cNrzMwiypdygLoVh5myd87HfMTgObN6mPV6q2YMfUrZd+Yb3v8OArLVmxGn88+Uat9kaIo+4dERFRqUnb9CGQX4zyTkQlsun1feoG0JCdHju9/+BnhETFo2KAWPD3KwcraEmmp6bj7zyNcuXoHnh7u+HnB/yCRSIrdPgvcO9Zsz9GJPbheH0uwaZ8c8YnCZnF2BPp1FjOLDmfRtTzMkr9yLkDvDvmfFfpQCxyQO6bdqtXbcObsFZXzcSKRCE0a18XILwOUHT4XFw9RviMuEVDzgp0SF58IPI0TOkUuZsmfLmUBdCsPs6gyKXwc0g+ShYU5xo0ZhKGDeyLsYThSU9NhYWGOqlUqqH3u7TUWOCIiEsTf566haZN6AABra0vUezWCAQA8fBTBAkdERPpp1ertMDYygvk7XXXJZNnYf/AUpk0eiTuhYZBKM+Dv51vs9lngiIhIECkpLzF7XiBEorzLTE1zB1Rd9/tOxEQnYOuWhcVunwWOiIgEUcbRHlOnjIS5+fs7W/5u7OdIl2ao1T4LHBERCaJN6yZ4+DACZmYmaNqkHhQKBe7cCYNcoUDtWt4AgHLlXNRunwWOiIgE8TQ6HjGxCejd62MAwK8rtuCvv6/C3t4WzZrWQ78+nTRqn111ERGRIKKexmLMNwPg5uqM0LsPcez4OcyY9jVWLZ+Gy5dva9w+CxwREQnC2MgIoldXmGwJOoBmTeujmrcnAMDS0lzj9vXuEKVCocCOXUexafN+yOVyzJ01Br6+Xsrli5ZswImTF/Lddm3gLLi46ECndEREhJwcOU6euoiIyBj8c+9f/LpkMgDg2PHzGt8DB+hZgUtOScWixetx/cY/aNSwNs6dv55nnU+7tEKL5vWV0znZOQhcGwwjIwlsbCy1GZeIqEjkVo5AtqzoGxgZRrcovXq2x4Kf10EuV+DLYb3g5uaMXXv+RGRkLFxKoIdsvSpwISGn8fhJFObOGgO5XJ5vgfPwKAcPj3IAcv86+GnhOsjlcsyaMbbAS1GJiEi7GjaohS0bf4JcLld+P3fr2qbE2terc3De3p5YumgifHyqFLquXC7H4qXrERr6ELNnfANnjlVBRKRzTE1N8t35uHX7vsZt69Ue3Nv9lBVm34GTOHX6MurWqY6IyBiN7qUgIqKSFx+fiAsXbyItPQN4Z2CbYycuoKZPVQwf1gsWah5906sCVxyODnZo3qw+4uISMXf+anz034YYO3qg0LGIiOiVKdOXIfnFS1hZ5x0O58WLFITeDcPESYvwxefdUMvXu9jtG2yBa96sPpo3y73YZM++41j32060ad0ENX2qCpyMiIgAwM7WGquWT1PeKvC2SVMWY86sMRq1r1fn4NTVtk1TAEBYWLjASYiI6LX/tPRHVFRsvssqVnTTuH2DK3Bn/7qCGzfvqcwzNTEBAGTJinEZLhERlarWrRojPCIGj59E5Vk2bEgvjds3uEOUx45fQMKzJPy6ZBLE4tz6HfYwd8+tnBsvNCGiD49Mlo3NQQdw+vQlpKVnwNvLA0MG90DFCrl7SVeuhmLjpr14Gh2PMo52+PTTNmj36sgXAHTqOjJPm716tkf/vp01yjX3xzW4di0UIpEIUyePRL26NbBoyQaE3g3DpAnD4enprlH7elXgIqNilbuzERExAIC7/zxCalo6AKBxozro+ElLzJy9EvN+XIOWLfzxMjUNO3YcgZubM/zq+wiWnYhIKDt2HsHJUxcxakQfODraYXvwYcycvRKrlk9DfHwi5s4PRM8e7dGoYS3cu/8YK1YGwamMvcqV69+OHQQvLw/ltLWV5h1nPAwLx5RJIyEWi7A9+DDq1a2Brl0+QiVPd2zash9TJo3QqH29KnBnz15B0LYQlXmbtuxX/r5/zwr4+/li4oRhCN55BEuXbYS5hRlq+XphQL8uMDMz1XZkIiLB3QkNQ/dubdHAP3dU7FEjAtB3wHhERcXiwcNwVPJ0R0DvDgAATw93XL58G1ev3VUpcI4OdnBzdS7RXD4+VZU7HuHh0QgPj4anhzs8Pdxx8dJNjdvXqwLXJ6Aj+gR0LHS9xo3qoHGjOqUfiIhID7x7NWJGRiYAwMzMFO3aNFU5HPl6ufk7OwRTZyyDWCyGvb0NWjT3Q9+AjpBIJBrl8qlRGXFxiXBxcUSLFn44+9dVuLk54597jxAX/1yjtgE9K3BERIZIbukI5GQXfQNJ7ld3erpUZbaxsRGMjQvvp3Jz0EHUruUNV1enPMtu3rqP+w+e4OtR/ZTzVvw6Vfl7REQ0lq8MgpWVhcbdat28dR9r1u1QTotEwG+/7wIAdO+meZddLHBERHpq0OBJkEozlNMBvTsUepRrS9ABXLt+FwsX/C/Psn//jcS8H1djyOAeKsWvvHtZld8jImNx4cJNjQtcdHQ8vvmqH8TiN/fBGRkZoVw5F1SuVF6jtgEWOCIivfXHujkq08bGBX+lB+88ggMhpzFn5mg4v9Nbf3h4NKZMX4aunVvh43bNlfOzsmR4lpikcv7NqYw9nicla5y/R/d2aN6sfqG51WVw98EREX0oLCzMVf4VdHhyz77j2LX7T8ya8U2ey+8jo2IxedpSdOzQEp+9utjktfiE5xg+YjoSEt6cE3v2LAkO9rYa5zc3N31vcYuMjNG4fe7BEREZuENHzmL9hr0YN2YAzM1NER0TDwCws7NBSkoqJk9dgjq1vdGypb9ymamJCRwd7eDm6gSPim5YsSoIfQI6IjHxBQ6EnEKPbu00zrVi1VaIxWJYWKh2pizPkePQkbOYMH6oRu2zwBERGbgzZ64gOzsbC37+TWX+6K/7AwCeP0/GqdOXcer0ZeWymj5VMW/OWIjFYkycMByBa7Zj8tQlsLAwR/t2zdGp4381zpWS8hJz5gXi3a4oFQrAzNRE4/ZZ4IiIDNy8OWMLXN66VeMCl7u6OmH61FElGQkA4GBvi+lTv4L5W3twIgC79x5TdpavCRY4IiISxPBhvfPtVHno4J5YvWY7qlerrFH7vMiEiIgEkZKSmu98kUiEsEcRGrfPPTgiIhLEhk17YWtrrXKRSWamDNdv/IMXL1I0bp8F7h0ujoCsGB0KlIYy9rk/37lNRRCvMzCLKl3KAuhWHmbJn5OD0Al0z8uXafleZOJgb4uvRvXVuH2RQqFQaNwKERGpLfH6aSjkOUVeXySWwLFuy1JMpB2fD56IqVNGwtLSQjnPzNQENjZWJdI+9+DesWZ7jk7swfX6WIJN++SITxQ2i7Mj0K+zmFl0OIuu5WGW/JVzAXp34GUPbxvzzQB4emg25ltBWODeEZcIZGYJnSJXfCLwNE7oFLmYJX+6lAXQrTzMosqk8D6QPzi1a1eDTJaNa9fvIioqFsbGRqhSpSJqVNfs6snXWOCIiEgQ8QnPMXXaUkTHJMDISAJra0ukpKTBp0ZlTJ74pcZjeLLAERGRIFYGbkVamhRTJn0Jf7/cwVhlsmwE7ziMPzbswZfDemvUPg8IExGRIEJDH+KLz7spixuQOyJCn4COePLkqcbts8AREZEgjI2N4FGxXJ75UmlGidwHxwJHRESCaNO6Ce4/eKIy705oGIaNmA47exuN22eBIyIiQQzo1xlx8c/w+EmUcl5KSioqVyqPUSP6aNx+iV9k8uxZEsq87oqDiIjoPcRiMQb274qnT+Pw97nrAIAKFVxLbOSCEi9wM2Ytx7Ilk0u6WSIiMjBZWTL8/MtvuHDxFkSi3HHgAKBe3RqYMH6I9m4TGPHVDMgK6eIjMyMLKS/z7x26NIVHRGP9hj0IvfsQcrkCVSpXQP9+nUvsZkEiIip56zfswdVrd/HFoG5o2cIP8xesxXfjPkfI4TMlcptAkQucna0NqlerBGPj928izchEyKEzGgUqrqSkZPwwaRFsbKwwdHBPGBsbYf/BU5g8dQkW/jS+VLuBISIqCXIrRyjk8iKvLxIbxuUTZ/66in59OqFrl1YAAIlEDCcnBwzs3xU/TFqkcftFLnAft2+OFs39Cl3PxFi7/dH8fe46Xr5Mw4/zvkV597IAAH+/mug38HucOHkRgz9ngSMi0kUymQx1aldTToteDSsgk8mQpM3hcopS3GSybFTz9tQoUHG9fkFsrC2V88zMTGFkZKRcRkREuqeWrxfi4hPh6Zm7IyLNyMS24EM4eeoSvKpW1Lh9tfdzk5Nf4t79x7gTGqb898+9R9iy7aDGoYqjebP6KONoh+UrtyA6Jh4JCc+xem0wxCIR2rVpqtUsRERUdMOH9cbZv64iNTUdAPAyJQ07dh5F/bo1MFKo2wQOHDyFtb/twOuh5F5f+SISAZUqldc4VHHY2Fhh5vSvMXteIIaPmA4AsLe3wfSpo1CunItWsxARUdE5Othh3JiBkL86//jzT+NhW0JjwQFqFrjde47hq5F9UaN6ZRw7fh5NGteFjY0lIiJikJyi3asoIyNjMHHKElSs4IpBA7oCAEIOncHMOSsxd9YYeHjk7QaGiIh0g0QigUQiAYASLW6AmoconZwc0LpVY7i5OaNRw9p49G8EnJ0d4edXE9dv/FOiAQuzacsBmJubYtqUUWjcqA4aN6qDqZNHwsrSAlu2HtBqFiIi0h1qFThTUxOcv3ADz58nw8vLA8dPXkTU0zhERsbgTmhYSWcsUERkNCp5uqvcvmBsbIRKldwRFaUjoy0SEZHWqXWIske3tpg1ZyVq1fLG5IlfokP75hj51UyIRIC3d6WSzligsi5lEPYwAjKZDMavblGQyWQIexiBihVctZqFiIh0h1oFztfXCxvW/whjo9zjpv9p2QAWFuaIjonHf1o0KNGAhenerS0mT12CyVOXon27ZgCAI0f/RmJiEr4dO0irWYiIqOSsWRuMpBcpsLAwx1cji39Vpdq3CZiZmihPDAJAA39fdO3cCtdv3FW3SbXU9KmK2TNHw8hIgpWrtmLlqq2QSMSYM3MMu+oiItJjQ4f0xCcdWuL4iQtqba92Z8vp0gxEP41HRmamcl5amhTrft+J//6nobrNqqWmT1XMmTVGq49JRESauXb9LurVrVHgOj41qsDDw02t9tUqcMeOn8eq1dsgk8mU98C9xs5DiIiKR27hqLyvuCiK20uTTJaNzUEHcPr0JaSlZ8DbywNDBvdAxQq5hePS5dvYtHk/omPiUaaMPXp0a4vWrRort09MfIHVa4Nx6/Z9GEkk8PeriS8+7w4rK4ti5XjX6jXbsXzZFJWjgfkxV3NUAbUK3OYt+zGgX2fUrVMdpqYmyvlp6VLMnLVCrSBERFQ6duw8gpOnLmLUiD5wdLTD9uDDmDl7JVYtn4bY2ATM+3E1un/aFk2b1MWd0DAsW74ZTmXsUftVP5ELfl4HuVyOaZNHIjMzCytXb0Pgmu0aX+cQE5uAkV/PgqODbYHr/fs4qsDl76NWgXN1dULnTh/lu6wkRmElIqKScyc0DN27tUUDf18AwKgRAeg7YDyiomJx+84DuLo6o1/fTgAAT093XLt+F5eu3EHt2tWQlibF3X8eYeFP4+FV1QMA0K9PJ/y6YnOJZMvJySl0KLbi7N2+Ta0CV7VKRchk2fkOnZPw7LlaQYiIqHS8e41CRkbutRNmZqZITU3P04OIjY21sn/I1z9tbayVy21trJCWJtU4l2tZJyxfNhUSScHXO06aslit9tUqcD41qmDOvED07N4OCryprOnpGdgcdAAft2+hVhgiIiq69HTVImNsbKS8H7ggm4MOonYtb7i6OinnJSQ8x3fjf8KkH4a/d7u58wPh4lxGuSeoqUEDPy20uAG5tUUdahW4RUs3IC1NimvX894SwItMiIi0Y9DgSZBK33z5B/TugD4BHQvcZkvQAVy7fhcLF/xPZb6TkwMW/zIBdnY2wKH8tx399QBIjCQIe/BE0+gAgEYNaxe6TmjoQzwJj1arfbUKXKOGtdGrR/s8lTctXYpZc1apFYSIiIrnj3VzVKbzO230tuCdR3Ag5DTmzBwNZ2fHPMvt7Qu+2MPS0rz4ITWwfuMePH0aB38/H7W2V6vA9evbCY4OdvkuG//dYLWCEBFR8VhYFL3g7Nl3HLt2/4nZM0crBxgFACsrizyjwKSkvISLSxnlcgBITnkJFxfHV7+nwkzNS/ffdvrMZbRs4Z/vssdPojCwf1eN2lerJ5OfF/6OhYv+yHeZtkf0JiKigh06chbrN+zFyC8/g7m5KaJj4hEdE490aQbq1qmOmJh4bNq8H4+fROHAwVO4dv0u/OrXBJC711ajemWsWRuMe/f+xc1b97Fpy3741Vdvr+pta9ftwKXLt3H7zgOVfxcu3kTQVs0Hz1ZrDy4tTYr673ly585fR5PGdTUKRUREJefMmSvIzs7Ggp9/U5k/+uv+aN2qMX74fhg2bd6P3XuPwd7eBsOG9FIpYOO/G4zVa4MxY/YKyOVy+Pv54sthvTXOlfIyFbPnrspz7YZCAVhYmGncvloFbtIPw3Hk6F9Il2bAwvxNCLlcjvUb97LAERHpkHlzxha4vIG/b4FXRjo62uGH74eWdCzYWFth+rSvYG1tqZyXEP8c585ff++91sWhVoGbOz8QaelSHDpyVuWkY1qaNM9lq/rGxREo5J7DUlfGPvdnPueAte51BmZRpUtZAN3Kwyz5c3IQOoHuade2GSpXKq8yz9nJATGxCVj3+05MnDBMo/ZFCjVuEf9h0iJUqlQeVu9cUZMuzcChw2exY9tijUIREX1IImOS8/TrWxCRCCjvWvAVj/ps0pQleBodhz/WzdWoHbX24Dp+8h80bWKYhyHXbM/RiT24Xh9LsGmfHPGJwmZxdgT6dRYzy3uybD+Ug2dJwmYB+JkpLIsuvE9lnYBubQruVPhDk5Ulw9VroShbtgw8Pd5c2Tlh/BBk5+Ro3L5aBe7t4packgpbGyvIZDKIxWIM/ry7xqGEFJcIZGYJnSJXfCLwNE7oFLmYJX/PkoCYBKFTvKFLr40uZdGF96mQW9Q+SPMWrMG1a6EQiUSYOnkk6tWtgUVLNiD0bhgmTRgOezsbjdpX6zaBjMwsrFkbjJ6fjcV3/1sAAMjMlOGXxeuR+PyFRoGIiOjD8DAsHFMmjcTUySOxPfgwAKBrl4/Q6ZP/YtOW/Rq3r1aBW7FyC65ev4se3dvC2ib36hcrKws0b1Yfgau3aRyKiIgMn49PVfjV90G9ujXQsEEthIdHw9PDHV06f6TSBZm61CpwD8LCsWzxRPTu+bHKQHQuzo64dfuBxqGIiMjw+dSojLi43BO1LVr44frNfyCTZePW7fuIi9d8ZBq1jgrb29koe6x++yLMGzfvFaknayIiopu37mPNuh3KaZEI+O33XQCA7t3aaNy+WgWuYkU3rN+4Bx3at0BOjhxJSck4feYKNm3Zj/Ztm2kcioiIDF90dDy++aofxOI3XZkYGRmhXDmXPPfHqUOtAjdoQFf8+NNaDB42JXd68EQoFECjhrUwcEBXjUMREZHh69G9HZo3q5/vKAgRkTGoUN5Vo/bVKnBmZqaYNmUUIqNiERERAwDw9CgHNzdnjcIQEdGH46P/Nsx3fkLCc0ycvAib1i/QqH21Ctyx4+fRulVjlHcvi/LuZZXzHz+OwsvUNNTy9dYoFBERfXgePHiCkMNncPavq5CVQI8bahW4k6cuonWrxnnme3q6Y+781VotcLdvP8DEKYvzXbbklx9QqQSO4xIRlSapVAR5MbrqEosKX0dfZGRm4fTpSzh0+Cz+fRwFF2dHdOn8Ef7885zGbRe5wN26fR8nT10CAERFxWHJso151klJScX9B481DqWOMd8MgJ2dtcq8sq5OgmQhIqLCBa7ZjpMnLyIzS4ZGDWth0MBPUad2NQBAwwa1NG6/yAWulq83JBIJAldvR2ZWFuLinqksF4lEsLAwxzdf9dc4lDpq+lRVjjZLRES6TyrNgLm5Kb4a1RfNmtZTWebtpfng2cU6ROlTowrmzx2Lo8fOoWvnVho/OBERfbjGfDMAySmpOHr0L0yY+Avq1qmO1q0bw9HBDsE7DqNnj/YatV/sc3AWFuYFFrebN++h9qtdTG3KzMqCVJoBExMTSCRqddBCRERaZmtjhZ492qN7t7a4cPEmFi/ZgJycHNy7/1j7Be5tKSmpyHir6/20tHQsXroBv2s4ho86Rn09C0DuTYIVypdFv76d4O/3/hFqiYhId4jFYjRpXBdNGtfFw0cRmDh5scZtqlXgrlwNxfIVm/E8KVllvkKR29WKNlWqVB7z545TTqempmPf/hOYMy8QC3/6vkTuhiciotITHR2Px0+eAgAqlC+LKpUrYMa0URq3q1aBW7V6K5o0qYe6darD1PRN35Pp6RlYtnyTxqGKw9LSHD41qqjMq+XrhT79x+P8+RsscEREOiorS4aff/kNFy7egkgE5ajm9erWwITxQzRuX60CZ2dng6GDe+S7LDm5i0aBiuvp0zgoALiXc1HOMzc3g729DcemIyLSYes37MHVa3fxxaBuaNnCD/MXrMV34z5HyOEz+GPDHnw5rLdG7at1NUbVyhVURhF4m42NlUaBiit45xFMmrIY2dlvhjd/+TINSUnJcHZy0GoWIiIqujN/XUW/Pp3QtUsr2NvbQiIRw8nJAQP7d0V4eLTG7au1B9eihR/WrAvGp11a4+0yJ03PQODqbWjUsLbGwYqqTasmOHnqImbNWYlWHzVCdnYO9h84CSMjI7Ro7qe1HEREVDwymUx5YzeQez/16/lJL1I0bl+tAjdt+q/IyMzCwZDTKvOFuMjEx6cKpk0ZhW3bD2HFyiCIJWJUrVIRc4Z/hnJvHbYkIiLdUsvXC3HxifD0dAcASDMysS34EE6eugSvqhU1bl+tAlevXg183K45xO/cb5aenoFfV2zROFSx89StgXp1a2j9cYmISkJ6pghyedHXFxvIrb7Dh/XGb7/vQk2fqrCyssDLlDTs2HkUbVs3Qf/+ml/PUeQCd/7CDTRuVAcA0DegI8q/Z5yenJycfOcTERG9zdHBDuPGDIT8VXX/+afxsC3B6ziK/HfAHxv2KH9/f3GTY8PGvRqHIiIiwxdy6AwkEgmMjXNvN3tfcbt2/a5a7Rd5Dy4mJgGDh02Bvb0N3nea7cWLl4hPSFQrCBERfVg2bNoLhUIBMzPT964jk2XjwsWbap2GKtY5OIlYDGMjo/deSMI+IImIdNPtOw+wcNEfSEx8gbmzxsDX1wsAsCXoAIK2heRZ39LCHFu3LAQAdOo6Ms/yXj3bo3/fzhplkkozsHrt9kLXMzExUav9Ihc4V1cnBK6YXuh6X46aoVYQIiIqHbv3HMPmoAMY0L8L1qwNzrPcq6oHvh03SDm9bfthRESo3of27dhB8PLyUE5bW1lqnKtsWScsXjgB5uZmGreVnyIXuC8GdSvaegM/VTsMERGVvKfR8Vgw71tUqlQ+T4FzdnZENW9PuLk6A8g9JHj12h3066O6d+boYKdcp6R8N+7zUituQDEKXFFHV21QAqOwEhFRyRk1IkB5E/W7WrdqrDL997nryMrKRssWqh1lTJ2xDGKxGPb2NmjR3A99AzpCIpFolCssLBxVqxR+v9u163dL/xwcERHpjvR0qcq0sbGR8orEt72vuOXn0OEz+E9Lf5U9qxW/TlX+HhERjeUrg2BlZYFuXduokfoNnbrIhIiIdMegwZMglWYopwN6d0CfgI5qtxceEY27/zzCl8NVOzku715W5feIyFhcuHBT4wKnMxeZEBGRbvlj3RyVaWNjzb7SDx8+C29vT3h6uCvnZWXJ8CwxSeX8m1MZ+zzjgaqjbFknLPnlhwL34DTBAvcOF0dAli1shjL2uT+dHYXN8XYGZlH1OsPr90po/MzkT5feJ8dSyGBhYV5ibWVkZuHkqUsYOqSnyvz4hOcYMWoGflszG06vRmh59iwJDva2Gj/md+M+h5mZaZ4BT9/XmUhxscC9Y2gvzU6alqR+nXXnvkJmyV+vj3Xn8wLo1mujS1l07X16l1QqQk4x+qIs7i3HsXHPkJmRpZyOi0+ETXg0bG2tYWdnDQA4feYyRGIRmjWtp7Ktm6sTPCq6YcWqIPQJ6IjExBc4EHIKPbq1K16IfFSs4Ia58wPzDHhav14NfP+/IRrv2YkU7xvY7QO1ZnuOTuzB9fpYgk375IgXuGMYZ8fcL6rth3LwLEnYLK9fF13KogvvEaCb79Pe49lIfCFsFkc7oEsrIxw6I0OS5qOvaMTJHmjTNO8FIABw/lpqsQtc43pF77Pxh0mLcCc0LM/8t8/Zjf12PmrUqJLvYNYxMQkIXLMd/9x7BAsLc7T6qBECen+icecea9YG4/DRv9C/b+c8A55KpZkaD3jKPbh3xCUCmVmFr6cN8YnA0zihU+R6lgTEJAidIpcuZdGl9wjQrdcm8QUQ90zoFLmSUoCE58L+LW9kpOWxxN4yb87YQtdZtHDCe5e5ujph+tRRJRkJgOqApwBUBjz9YdIijdvXnWMIRET0QdHJAU+JiIg0VdoDnnIPjoiIBDF8WG+c/esqUlPTAUA54Gn9ujUwckQfjdvnHhwREQni9YCnOTmlM+ApCxwREQkmPT0DV67ewbNnSbCwMIevrxcq8D44IiLSZ7fvPMCcuYGQZrzpbkyhAFp/1AhfjeoLsVizs2gscEREJIjA1dtRv74PenRvC9eyToBIhKjIWGzcvA87dx1Fzx7tNWqfF5kQEZEgsnNy8O3YQfD0cIeZmSnMTE1QpUoFTJ44HOcv3tS4fe7BEREJLD1ThJycoq+v4TBsOqN6tUr5HoY0NjaG6VsjCKSmpsPKyqLY7et9gVu0ZANOnLyQ77K1gbPg4qIDPb4SEVEeFSu6IS4uMc/39JWroZBIxMjKkiEnJwdB20Ly7UKsMHpf4D7t0gotmtdXTudk5yBwbTCMjCSwsbEUMBkRERVk69YQ/Pb7rnyXiURAj95jAAD2djYfZoHz8CgHD49yAICcHDl+WrgOcrkcs2aMVRmRloiIdEutWt5o4O8Lsbh0+unU+wL3mlwux+Kl6xEa+hDz546D86txi4iISDf1DeiIihXdSq19g7mKct+Bkzh1+jI8Pd0RERkjdBwiIipEaRY3wIAKnKODHZo3q4+0NCnmzl+NRUvWCx2JiIgEZDCHKJs3q4/mzXIvNtmz7zjW/bYTbVo3QU2fqgInIyIiIRjMHtzb2rZpCgAICwsXOAkREQlF7wvc2b+u4MbNeyrzXt8gmCWTCRGJiIh0gN4fojx2/AISniXh1yWTlHfEhz3M3XMr5+YiZDQiInrHvv0nkJYmVWtbS0tzdO70UZHX1/sC1/GTlpg5eyXm/bgGLVv442VqGnbsOAI3N2f41fcROh4REb3l4KEzyClOv2RvEYvFH1aB8/fzxcQJwxC88wiWLtsIcwsz1PL1woB+XWBmZip0PCKiQkmlYmQX4zvfSI/7oizjaIc5s8aote2kKYuLtb7eFzgAaNyoDho3qiN0DCIi0iF6f5EJERHpj+lTR2ltWxY4IiLSGmNjY+XvFy/dQmLiC7W2LQqDOERJRET6Z+78QCgUgK2tNSpXKo8qlSugcuXyqFy5Qon0J8wCR0REgli6eBIePozAw4fhCHsUgd17jyE7OxsKBWBjYwlPD3fMmvGN2u2zwBERkSAqVnBDxQpuaPVRIwC5Q57dvvMAm7bsR9LzZGRladZZB8/BERGRTpBIxKhTuxp+nDsO9vY2+Kx3B43a4x4cEdEH4PadB1i46A8kJr7A3Flj4OvrBQA4dvw8lizbmGf9wJXT4ebqDABITHyB1WuDcev2fRhJJPD3q4kvPu8OKyuLUskqkUjQpXMrbN0Wgrp1qqvdDgscEZGB273nGDYHHcCA/l2wZm1wnuWOjnaYO3uMyjxnJ0fl7wt+Xge5XI5pk0ciMzMLK1dvQ+Ca7fh27CCNcoUcOoPKlcujkqd7niskLS3N8ejfSI3aZ4EjIjJwT6PjsWDet6hUqXy+BU4iFiv31t6VlibF3X8eYeFP4+FV1QMA0K9PJ/y6YrPGuQLXbINCkXtoskJ5V1SpUhFVKpeHubk5du3+E7a21hq1zwL3DhdHQJYtbIYy9rk/nR0LXk8bXmd4nUlIrzPoUhZdeI8A3XyfHO0EjQHgTQZ7GwAQCZgEsNfsu1ojo0YEQCR6//OPT3iObj2/gZFEgnLuLhjQr4vy0GBqajoAwNbmzROwtbFSu8Pkt23840c8fBSBsIfhePgwAteuheLY8XNQKAAjIwnGjh6oUfsscO8Y2kt3Onnr11l3rgHq9bHuvC66lEWX3iNAt16bLq105+vl4xbFu0FY29IyRcguxh/WRq9e2vR01SJjbGyU783QBRW3xo3qwNvbEwCQLcvGiVMXMXvuKqxcPi3PvWhz5wfCxbkMGvj7Fj1sAWxsrFCvbg3Uq1tDOS88Ihp/bNiDcm7OykGs1aU7n0AdsWZ7jk7swfX6WIK9x7NRjJv8S4WjXe4X1fZDOXiWJGyW16+LLmXRhfcIePM+HTojQ1KKsFnsbXILyuVbmUhNVwiaxcpCBP9aprh1LwNpUmGzWFuKUNPLrETbHDR4EqTSDOV0QO8O6BPQsVhtWFqaw9LSXDk92NMdFy7cxPXrd9GubTOVdUd/PQASIwnCHjzRKHdBKlZww7TJIzFpyhKc/esKmjfzU7stFrh3xCUCmVlCp8iV+AKIeyZ0ilzPkoCYBKFT5NKlLLr0HgFAUgqQ8FzYL/LXhwJT0xVIfil0llxpUgVepskFzSARl/ze/h/r5qhMGxsX/yv9xYuXAAA7uzeHIMuUscfzfP5SersQlraOn7TE9h2HNSpwunV8hYiIiszCwlzlX3H7agSAvfuP46eFv6nMS0x8AYfcE5fKWwGSU14qlyenpJbIcGRB20Jw6fJtJCUl51kmEYsRGRmrUfvcgyMiMnCxcc+QmfHm0FRcfCJswqNha2uNRg1rY9fuY9i3/wR8a3rh7F9XkfQiBXVfnReztDRHjeqVsWZtMAZ/3h2ZWTJs2rK/RAaU3rHzCGSvzgnZ29nk3jJQqTzMzUwRcvgsnDW8iosFjojIwC1ZuhF3QsPeTL+6sfv1ObtxYwZi6/YQbNi0D+Xdy2LyxC9VLjAZ/91grF4bjBmzV0Aul8PfzxdfDuutca5tW37Bk/Cnuf1RPorAo0cR2LX7T+Tk5MDB3hYjNHwMFjgiIgM3b87YApe3bOGPli3837vc0dEOP3w/tKRjwchIgiqVK6BK5QrKeXK5HFJpZomc7+M5OCIi0pq4uMQCl4vF4vcWt8K2zdNWsdYmIiLSwJJlG7S2LQscEREZJJ6DIyIirYlPeI7On45Sa1unYo7yzQJHRERa88WgbsjIyFRr2+Lee2cQBS7sYTg2bNyLh48iYCSRwNvbEwMHdEV597JCRyMiKpRUKipWF4FqdFiiM5o0rqu1x9L7c3CRUbGYMPEXSDMyMXxoLwwa+Cni4p5hwsRflF3QEBHRh0eP/w7IdTDkNExMjDFz+tewMM/tyLROnWr4YsgknDh1Ad26thE4IRERCUHvC1xNn6rwqlpRWdwAwNHBDjbWVsW+Z4KIiAyH3he4Zk3r5ZkXG/sMySmpPAdHRPQB0/tzcO+Sy+UIXLsdtjZW+E/LBkLHISIigRhcgVu9NhjXrt3F6G8GKId5ICKiD49BFbg/1u9GyKEzGDkioESGciAiIv1lMAVuc9AB7Nz9J4YP7YV2bZoKHYeIiARmEAVux66j2LotBEOH9MQnHVoKHYeIiHSA3l9FefTPv7F+wx74+9VEOTdnXL0WqlxmbWUJLy8P4cIREZFg9L7Ahd59BAC4fOUOLl+5o7Kspk/VQgf6IyISmjRThCxZ0dc3MS69LIZE7wvc2NEDMHb0AKFjEBGRjjGIc3BERETvYoEjIiKDxAJHREQGiQWOiIgMEgscEREZJBY4IiIySCxwRERkkFjgiIjIILHAERGRQdL7nkxKmosjIMsWNkMZ+9yfjnaCxgDwJsPrTEJ6nUGXsujCewS8yWFvAwAiAZO8zgBYWQib4+0MluYiCP33vIW58K/Hh0akUCgUQocgIvqQLfwtu9h9UX77RfH2T27feYCFi/5AYuILzJ01Br6+XsplV66GYuOmvXgaHY8yjnb49NM2KsOOdeo6Mk97vXq2R/++nYuVQdu4B/eOpHtXALlc0AwSMwvYVKqJy7cykZou7N8fVhYi+Ncyxb1/pZBmCJvF3EyEapXMdSpLxun1UCTHC5oFAES2zjBrORCKNZ8DsQ+EDVPWC6KhvyNn4zdA/CNhszhXhqT/Ut14XcrXgmjQSkEeeveeY9gcdAAD+nfBmrXBKsuePo3D3PmB6NmjPRo1rIV79x9jxcogOJWxR726NZTrfTt2kMroLNZWltqKrzYWuHfIpWlQyHOEjgEASE1XIPmlbuxgSzMUSEsXtvC/PsSkS1kUyfGQJ0YJnOWtg2+xD4CIm0JGeSP+ERAVWvh62qALr4uJhWAP/TQ6HgvmfYtKlcrnKXB37j5EJU93BPTuAADw9HDH5cu3cfXaXZUC5+hgBzdXZ63m1hQLHBGRgRs1IgAiUf7nANu1aapyOBIAMjIyYW5mqjJv6oxlEIvFsLe3QYvmfugb0BESiaTUMpcEFjgiIj2Vni5VmTY2NoKxcd7B4t5X3PJz89Z93H/wBF+P6qect+LXqcrfIyKisXxlEKysLNCtaxs1UmsPCxwRkZ4aNHgSpNIM5XRA7w7oE9BR7fb+/TcS835cjSGDe8DV1Uk5v7x7WZXfIyJjceHCTRY4IiIqHX+sm6MybWys/ld6eHg0pkxfhq6dW+Hjds2V87OyZHiWmKRy/s2pjD2eJyWr/Vjawhu9iYj0lIWFucq//A5PFkVkVCwmT1uKjh1a4rNXF5u8Fp/wHMNHTEdCwnPlvGfPkuBgb6tRdm3gHhwRkYGLjXuGzIws5XRcfCJswqNha2uNjMxMTJ66BHVqe6NlS39Ex+Te9mJqYgJHRzu4uTrBo6IbVqwKQp+AjkhMfIEDIafQo1s7oZ5OkbHAEREZuCVLN+JOaNib6WUbAeSes3N2dsTz58k4dfoyTp2+rFynpk9VzJszFmKxGBMnDEfgmu2YPHUJLCzM0b5dc3Tq+F+tP4/iYoEjIjJw8+aMLXB561aNC1zu6uqE6VNHlWQkreA5OCIiMkjcgyMiEpg0U4TMrMLXey1H6I589IRB7MEpFAoE7zyCLt2+QqeuI3H7tsB9zhERkeD0vsAlp6RixqwV2LR5Pxo1rC10HCIi0hF6f4gyJOQ0Hj+JwtxZYyCXy3Hu/HWhIxERkQ7Q+wLn7e2JDh+3gK2tNQ9NEhGRkt4XuLeHcyAiInpN78/BERER5YcFjoiIDBILHBERGSQWOCIiMkgscEREZJD0/irKyKhYREXFAgAiImIAAHf/eYTUtHQAQONGdYSKRkREAtL7Anf27BUEbQtRmbdpy37l7/v3rNB2JCKiYkmXFrMvypzSy2JI9L7A9QnoiD4BHYWOQUREOobn4IiIyCCxwBERkUFigSMiIoPEAkdERAaJBY6IiAwSCxwRERkkFjgiIjJILHBERGSQ9P5G75ImEkuEjgCIc//ukEgAI4HjSF49vlgMSAT+c+jVy6JTWWBkAhibCppFmQMATCwAM2ths5hYvPppDphaCZzF/NVPHXpd8mFWzI9Qcdf/UIkUCoVC6BBEREQljYcoiYjIILHAERGRQWKBIyIig8QCR0REBokFjoiIDBILHBERGSQWOCIiMkgscEREZJBY4IiIyCCxwBERkUFigSMiIoPEAkdERAaJowloQKFQYMeuo9i0eT/kcjnmzhoDX18vwfKEPQzHho178fBRBIwkEnh7e2LggK4o715WqzkWLdmAEycv5LtsbeAsuLg4ajXP7dsPMHHK4nyXLfnlB1SqVF6reQAgPCIa6zfsQejdh5DLFahSuQL69+uMGtUrl/pjF/a51eb7V5TPrLb+nxX3eSsUCkycvBgxsQlYsWwKLCzMSzwTaYYFTk3JKalYtHg9rt/4B40a1sa589cFzRMZFYsJE3+Bp6c7hg/thZwcOfbsPYYJE3/B8qVTYGenvaFCPu3SCi2a11dO52TnIHBtMIyMJLCxsdRajneN+WZAntehrKuT1nMkJSXjh0mLYGNjhaGDe8LY2Aj7D57C5KlLsPCn8fD0cC+1xy7K51Zb719RPrPa/H9W3Od99M+/cSc0DJN+GM7ipqNY4NQUEnIaj59EYe6sMZDL5YIXuIMhp2FiYoyZ07+GhbkZAKBOnWr4YsgknDh1Ad26ttFaFg+PcvDwKAcAyMmR46eF6yCXyzFrxliYv8omhJo+VbW+95ifv89dx8uXafhx3rfKPRV/v5roN/B7nDh5EYM/L70CV5TPrbbev6J8ZrX5/6w4zzspKRm/r9+NJo3rolHD2qWWiTTDAqcmb29PdPi4BWxtrXH79gOh46CmT1V4Va2o/KIAAEcHO9hYWyEuLlGQTHK5HIuXrkdo6EPMnzsOzk4OguTQNSKRCABgY/1mr8DMzBRGRkbKZaWlOJ/b0n7/ivKZFeL/WVGed+Ca7YACGD60l1YykXp4kYma6tWtAVtbgUcIfkuzpvXw0X8bqcyLjX2G5JRUrZ+De23fgZM4dfoyPD3dEREZI0iGt2VmZUEqzUBOjlzQHM2b1UcZRzssX7kF0THxSEh4jtVrgyEWidCuTdNSfezifG5L+/0rymdWiP9nhT3vS5du4e9z1zFo4KdwcLDVajYqHhY4AyWXyxG4djtsbazwn5YNBMng6GCH5s3qIy1NirnzV2PRkvWC5Hht1Nez0CtgHHr0HoPRY+fi8pXbguSwsbHCzOlfIzwiBsNHTMcXQyfj3PnrmD51FMqVcxEkU360/f7pwmcWKPh5p0szsDJwK2pUr4x2bXP/GDl2/Dw6dR0p2JESej8eojRQq9cG49q1u5gyaQSsrCwEydC8WX00b5Z70n7PvuNY99tOtGndBDV9qmo1R6VK5TF/7jjldGpqOvbtP4E58wKx8KfvUVnLV1FGRsZg4pQlqFjBFYMGdAUAhBw6g5lzVmLurDHK80BC0/b7pwufWaDg571x4168SE7FzBnflPrhZNIc9+AM0B/rdyPk0BmMHBEAv/o+QscBALR9degtLCxc649taWkOnxpVlP8aNqiFyRO/hEgkxvnzN7SeZ9OWAzA3N8W0KaPQuFEdNG5UB1Mnj4SVpQW2bD2g9TxFUdrvny5+ZoG8z/vS5dvw96sJezsbpKamIzU1HZmZWUJGpAJwD87AbA46gJ27/8SXw3qX+vmc9zn71xVYW1uhTu1qynmmJiYAgCyZTOt5nj6NgwKA+1uH/8zNzWBvb4PE5y+0niciMhqVPN1hbPzmv5+xsREqVXJHRITw5yq1/f7pwmcWKPrzPn/hBs5fuKHteKQGFjgDsmPXUWzdFoKhQ3rikw4tBctx7PgFJDxLwq9LJkEszj1IEPYw9y/gcm7aP8cUvPMIrt/4B+tWz4aRkQQA8PJlGpKSkgW5srOsSxmEPYyATCaDsbExAEAmkyHsYQQqVnDVep53afP905XPLFC05/2/7wZDlqVa5K9ev4udu45qNywVCQucmiKjYhEVFQsAyr+67/7zCKlp6QCAxo3qaDXP0T//xvoNe+DvVxPl3Jxx9Vqocpm1lSW8vDy0lqXjJy0xc/ZKzPtxDVq28MfL1DTs2HEEbm7Oghx+atOqCU6euohZc1ai1UeNkJ2dg/0HTsLIyAgtmvtpPU/3bm0xeeoSTJ66FO3bNQMAHDn6NxITk/Dt2EGl+thF+dxq6/0rymdWm//PivK8q3l75tkuLp4Xl+gqkUKhUAgdQh9tCTqAoG0h712+f88KLaYpuJuhmj5VMW/OWK3mOX/hBoJ3HkFUZCzMLcxQy9cLA/p1gZNA98Jdu34X27YfQnh4NMQSMapWqYi+AR21Wvjfdic0DEFbDyrP7VStWhF9PusIH58qpfq4Rf3cauP9K8pnVtv/z9R53seOn8eSZRsF6YaOCsYCR0REBolXURIRkUFigSMiIoPEAkdERAaJBY6IiAwSCxwRERkkFjgiIjJILHBERGSQWOCIiMggscAREZFBYoEjIiKDxAJHREQGiQWOiIgMEgscEREZJBY4IiIySCxwRERkkFjgiIjIIBkJHYCoJDx58hR79h3H8RMXYGFhhqpVKgIA5HI5XiSnIjIyBkO+6IEunT8qtK2XL9OQkPAclSqVL+3YRbJpy35cvHgTVapUxOiv+wsdh0hvsMCRQfDwKIcx3wzAkydPYWQkweyZo1WWHzp8BllZ2UVq62DIaZQpY68zBa5fn064cfMe5HKF0FGI9AoPUZJBMTc3y3d+y5YNUL1apUK3f/wkCrv2HCvpWBozNuLfokTFxf81ZPAOHT6DenV9IJNlI6Dfd0hNTYe1tSVmTPsKjx9HYfnKIJiZmWDOrDHYt/8EpNIM7Nh1FMdPXMDgz7ujSpUKiI6Jx2+/70JqajqeJyWj9UeN0atnewBA0LYQnDt3DdWrV0YD/1pY+utGtGndBP5+vtgSdACP/o3EtCkjcfjIX3j4MALZ2dkYM3oAvKp6KDMeDDmNc+evIy1NiqwsGUYM/wy+vl4CvWJEhoF7cGTQ5HI5bty8DwDw8amCX5dOhoO9LWrX8kbVKhXRtEk9eHt5YNWK6ahSuQLGjRkEAOjRrS3mzRmLKlUqIDU1HRMnL0b7ts0wf+44TJn4JbZuD8G589cBAJ/1+hhisRhRUbH4999I+Pv5wtrKEtW8PdG0aT2kpKTiyZOn+Oarfli6eCLKlXPBmrXByoy37zzAqtXb8P3/hmDxLz+gSpUKWL12u9ZfKyJDwz04MjgRkbH4YdIiAEDi8xeIiUnAF4O6AQAcHezw3bjPMXnaUly5GopLl29hzOgBsLezeW97Z85egUQigZ9fTQBA+fKuqFG9Mo4c/RtNGteFSCSChYU5ACj36l6TiHP/hmzbpqlyXp3a1fD7+t3KaVtbazRvVh82NlYAgBrVq+DsX1c1fRmIPngscGRwKpQvi3lzxiqng7YeVFnu6+uF3j3bY8as5Rj9dX+4uToX2F5EZAzi4xOVRRMAUl6mws7WWmU9JyfHIuUzNTVBZmbWW3ldMf67wcjKkuHW7Qe4dj0U2dk5RWqLiN6PBY4MXsBnnwAAIqNiUd69LABALlegTBl7HD5yFv9p2QBGRpIC23B1dVIpmiUpJycHW7YexP37j9G5439Rt051nL9ws1Qei+hDwnNw9MFYv2EPAOD8hRvIkefgl5/GIzomAb//savA7TwqlkNMTALCHoarzE9MfFEyuTbuxfETFzB96ldo0KAWjI2NS6Rdog8dCxwZlMysrHznHz9xAVJpBsIehmP/gZPoG9AJ9va2GPJFd+w7cBJnzl5RrmtpYY6Ul6lQKBR4/CQKLZrXh5OTA+bOC8TZv67i0b+ROHTkLPYfOKncJiMjEy9fpuZ53HRpRu7PdGmeeamp6QCAp0/joFAooFDk3uf2JPwpACAnRw6ZTJbbfmYmpK+2I6KiESle/68i0mOPn0Th4MHT+PP4OZibmcHb2xNA7lWUic+TERkZAwAwMjKClZUFZkwdhUqVymPMuHl49G8kxGIxvhjUDV06f4SNm/fhz2PnULdOdfQN6AhnZ0fExj3DmrXBuH37AUxNTdCiuR8GDfwUxsZGGD/hZ/xz718AQOVK5TH+f4Ph5uqMgyGnsXHTPqSlS1HWpQy+HTsIN27ew649xyCVZqCsSxlM+mE40tKlWLxkA4xNjOFVtSLq1qmOlau2olYtL/Tr2xlr1gbjxs17EItFqFfPB9MmjxTsdSbSJyxwRERkkHiIkoiIDBILHBERGSQWOCIiMkgscEREZJBY4IiIyCCxwBERkUFigSMiIoPEAkdERAaJBY6IiAwSCxwRERkkFjgiIjJILHBERGSQWOCIiMgg/R8vqB4UnflQfQAAAABJRU5ErkJggg==",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 45\u001b[0m\u001b[1;36m0x450\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 45\u001b[0m\u001b[1;36m0x450\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 45\u001b[0m\u001b[1;36m0x450\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 45\u001b[0m\u001b[1;36m0x450\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "\n",
+    "\n",
+    "nplots = 3\n",
+    "\n",
+    "# print(f\"{distance_travelled_avg_im.shape=}\")\n",
+    "# print(f\"{nrows=} {ncols=}\")\n",
+    "\n",
+    "cmap_name = 'gray_to_red'\n",
+    "custom_cmap = LinearSegmentedColormap.from_list(cmap_name, [flavor.peach.hex, flavor.mantle.hex, flavor.lavender.hex], N=32)\n",
+    "\n",
+    "# x, y = np.meshgrid(xticks, yticks)\n",
+    "# hist2d_args = dict(\n",
+    "#     x=x.flatten(),\n",
+    "#     y=y.flatten(),\n",
+    "#     bins=[nrows, ncols],\n",
+    "#     # cmap='viridis'\n",
+    "#     # cmap=custom_cmap,\n",
+    "# )\n",
+    "\n",
+    "figsize = (5, 5)\n",
+    "ax_set_args = dict(\n",
+    "    # xlabel='External',\n",
+    "    # ylabel='Internal',\n",
+    "    # yticks=yticks,\n",
+    "    # xticks=xticks,\n",
+    "    \n",
+    "    # yticklabels=(yticks, fontproperties=prop_jbm, fontdict=dict(color=flavor.text.hex))\n",
+    ")\n",
+    "\n",
+    "# names = ['Average Distance Travelled', 'Average LDJ', 'Average Makespan']\n",
+    "names = ['average-distance-travelled', 'average-ldj', 'average-makespan', 'largest-time-differense']\n",
+    "units = [\"Distance Travelled [$m$]\", \"Log Dimensionless Jerk [$m/s^3$]\", \"Makespan [$s$]\", 'Finished At Difference [$s$]']\n",
+    "# ims = [distance_travelled_median_im, ldj_im, makespan_im, maximum_task_completion_time_difference_im]\n",
+    "ims = [distance_travelled_avg_im, ldj_im, makespan_im, maximum_task_completion_time_difference_im]\n",
+    "colors = [flavor.red.hex, flavor.green.hex, flavor.blue.hex]\n",
+    "\n",
+    "cmap_name = \"my_cmap\"\n",
+    "color_good = flavor.sapphire.hex\n",
+    "color_good = flavor.lavender.hex\n",
+    "# color_good = flavor.teal.hex\n",
+    "color_bad  = flavor.peach.hex\n",
+    "color_middle = flavor.mantle.hex\n",
+    "\n",
+    "colors = [color_good, flavor.mantle.hex, color_bad]\n",
+    "cmap = LinearSegmentedColormap.from_list(cmap_name, colors, N=32)\n",
+    "cmaps = [\n",
+    "    LinearSegmentedColormap.from_list(name, colors, N=24)\n",
+    "    for name, colors in zip([\"foo\", \"bar\", \"baz\", \"karl\"], [\n",
+    "        [color_good, color_middle, color_bad],\n",
+    "        [color_bad, color_middle, color_good],\n",
+    "        [color_good, color_middle, color_bad],\n",
+    "        [color_good, color_middle, color_bad],\n",
+    "        \n",
+    "\n",
+    "        # [flavor.peach.hex, flavor.mantle.hex, flavor.lavender.hex],\n",
+    "        # [flavor.maroon.hex, flavor.mantle.hex, flavor.sapphire.hex],\n",
+    "        # [flavor.flamingo.hex, flavor.mantle.hex, flavor.sky.hex]\n",
+    "    ])\n",
+    "]\n",
+    "\n",
+    "for name, unit, image, cmap in zip(names, units, ims, cmaps):\n",
+    "    # fig, ax = plt.subplots(figsize=figsize)\n",
+    "    fig, ax = plt.subplots(figsize=(4.5, 4.5))\n",
+    "    # hist = ax.hist2d(weights=image.flatten(), **hist2d_args, cmap=cmap, norm=LogNorm())\n",
+    "    if name == 'average-distance-travelled':\n",
+    "        print(f\"{image[6, 0]=} {image[0,0]=} {image[-1, -1]=}\")\n",
+    "\n",
+    "# x, y = np.meshgrid(xticks, yticks)\n",
+    "# hist2d_args = dict(\n",
+    "#     x=x.flatten(),\n",
+    "#     y=y.flatten(),\n",
+    "#     bins=[nrows, ncols],\n",
+    "#     # cmap='viridis'\n",
+    "#     # cmap=custom_cmap,\n",
+    "# )\n",
+    "    cell_width = 4\n",
+    "    r = np.arange(cell_width, 9 * cell_width, cell_width)\n",
+    "    x, y = np.meshgrid(r, r)\n",
+    "    # print(f\"{xticks=}, {yticsks=}\")\n",
+    "    hist = ax.hist2d(x=x.flatten(), y=y.flatten(), bins=[nrows, ncols], weights=image.flatten(), cmap=cmap, norm=\"linear\")\n",
+    "    # ax.set_title(name, fontsize=12, fontproperties=prop_jbm, fontdict={'color': flavor.text.hex})\n",
+    "    ax.set(**ax_set_args)\n",
+    "    ax.set_xticks([])\n",
+    "    ax.set_yticks([])\n",
+    "    ax.set_xlabel(\"External\", fontsize=12, labelpad=30, fontproperties=prop, fontdict=dict(color=flavor.text.hex))\n",
+    "    ax.set_ylabel(\"Internal\", fontsize=12, labelpad=30, fontproperties=prop, fontdict=dict(color=flavor.text.hex))\n",
+    "    ax.axis('square')\n",
+    "    # ax.grid(True)\n",
+    "\n",
+    "    # Create a divider for existing axes instance\n",
+    "    divider = make_axes_locatable(ax)\n",
+    "    cax = divider.append_axes(\"right\", size=\"5%\", pad=0.05)\n",
+    "\n",
+    "    # Create colorbar\n",
+    "    cbar = plt.colorbar(hist[3], cax=cax)\n",
+    "    cbar.ax.tick_params(labelsize=10, color=flavor.text.hex)\n",
+    "    cbar.set_label(unit, rotation=270, labelpad=20, fontsize=12, fontproperties=prop, fontdict=dict(color=flavor.text.hex))\n",
+    "    tick_labels = cbar.ax.get_yticklabels()\n",
+    "    plt.setp(tick_labels, fontsize=10, fontweight='bold', color=flavor.text.hex, fontproperties=prop_jbm)\n",
+    "\n",
+    "\n",
+    "    # cbar = plt.colorbar(hist[3], ax=ax)\n",
+    "    # # cbar = plt.colorbar(hist[3], ax=ax, fraction=0.046, pad=0.025)  # Adjust fraction and pad to move the colorbar closer\n",
+    "    # cbar.ax.tick_params(labelsize=10, color=flavor.text.hex)  # Customize colorbar ticks\n",
+    "    # cbar.set_label(unit, rotation=270, labelpad=20, fontsize=12, fontproperties=prop, fontdict=dict(color=flavor.text.hex))  # Add label\n",
+    "    # # cbar.ax.tick_params(labelsize=12, labelcolor='red', direction='in', length=10, width=2)\n",
+    "    # tick_labels = cbar.ax.get_yticklabels()\n",
+    "    # plt.setp(tick_labels, fontsize=10, fontweight='bold', color=flavor.text.hex, fontproperties=prop_jbm)\n",
+    "    # # ax.text(0, 0, 'Text at (5, 5)', color='red', fontsize=12, ha='center', va='center')\n",
+    "\n",
+    "\n",
+    "    initial_width_offset = 5.5\n",
+    "    width = 3.55\n",
+    "    cursor = initial_width_offset\n",
+    "    for xtick in xticks:\n",
+    "        ax.text(cursor, 2, str(xtick), color=flavor.text.hex, fontproperties=prop_jbm, fontsize=12, ha='center', va='center')\n",
+    "        cursor += width\n",
+    "\n",
+    "    initial_height_offset = 2.8\n",
+    "    height = 3.55\n",
+    "    cursor = initial_width_offset\n",
+    "    for ytick in yticks:\n",
+    "        ax.text(2.5, cursor, str(ytick), color=flavor.text.hex, fontproperties=prop_jbm, fontsize=12, ha='center', va='center')\n",
+    "        cursor += width\n",
+    "\n",
+    "    # ax.hlines(y=7.5,xmin=0, xmax=50, linewidth=2, color='white')\n",
+    "    # ax.hlines(y=11,xmin=0, xmax=50, linewidth=2, color='white')\n",
+    "    # ax.hlines(y=14.5,xmin=0, xmax=50, linewidth=2, color='white')\n",
+    "    for i in range(ncols):\n",
+    "        ax.hlines(y=7.5 + i * 3.5,xmin=0, xmax=50, linewidth=1, color='white')\n",
+    "        ax.vlines(x=7.5 + i * 3.5,ymin=0, ymax=50, linewidth=1, color='white')\n",
+    "        # xs = []\n",
+    "        # ys = []\n",
+    "        # ax.hline(xs, ys)\n",
+    "\n",
+    "\n",
+    "    # ax.text(2.8, -0.5, '1', color='red', fontsize=12, ha='center', va='center')\n",
+    "    # ax.text(0, 1, '1', color=flavor.text.hex, fontsize=12, ha='center', va='center')\n",
+    "\n",
+    "    \n",
+    "    fig.tight_layout()\n",
+    "    output = Path(f\"iteration-amount-{name}.svg\")\n",
+    "    fig.savefig(output)\n",
+    "\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
x=array([[ 5, 10, 15, 20, 25, 30],\n",
+       "       [ 5, 10, 15, 20, 25, 30],\n",
+       "       [ 5, 10, 15, 20, 25, 30],\n",
+       "       [ 5, 10, 15, 20, 25, 30],\n",
+       "       [ 5, 10, 15, 20, 25, 30],\n",
+       "       [ 5, 10, 15, 20, 25, 30]])\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mx\u001b[0m=\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m,\n", + " \u001b[1m[\u001b[0m \u001b[1;36m5\u001b[0m, \u001b[1;36m10\u001b[0m, \u001b[1;36m15\u001b[0m, \u001b[1;36m20\u001b[0m, \u001b[1;36m25\u001b[0m, \u001b[1;36m30\u001b[0m\u001b[1m]\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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/fffG126dDG2bdtm7Nmzx2jXrp1RVFRkFBUVGVFRUca+ffsMwzCMwsJCIzIy0nj99deNL7/80li9erWxbt06o0+fPoZhGMbx48eNNm3aGHl5eYZhGMbu3buNyMhI4//+7/+MwsJCY+XKlUZkZKSRkJBgFBcXG0lJSUavXr2ccT311FPGmjVrDMMwjMzMTOPqq6820tPTDcMwjBtvvNH417/+5bz2jjvuMHbv3m0YhmFs3rzZ6Ny5s5Gbm2sYhmFcf/31xvPPP2988803xgcffHDR9+HGG280kpKSXPKeAkB1wJxEAGXyzjvvqFatWvLz89OiRYvUpk0bORwOrVy5Ul5eXsrNzZWfn5+OHz+uli1bOucrDho0SOHh4ZKkwsJC/eMf/5BUUqF0OBzKyclRaGioAgICJEn33HOPJKlDhw6SpOHDh0uSevbsqcmTJ0uSCgoKtGrVKjVo0ED//ve/JUlRUVE6dOiQwsLCSsX9888/a+fOnUpOTlZycrKKi4vVqlUrHTt2TP7+/vL29tatt96qzp07q3PnzhX4DgJA9UKSCKBMHn30UbVq1apUm9Vq1S+//KIpU6aoRYsWMgxDhmGUuub8xS02m00HDhzQe++9p4iICEkyXX9+37997XA4JEknT56UJD377LPy9fX93bizs7MVHBysZ5555qLXVNUFOADgTsxJBHDZduzYoZEjR2rUqFEaPny4ateu/bvXr127VjNnztS4ceM0ePDgy/65QUFB8vb21pYtW0q1nzhxwnRtw4YNlZOTo/379zvbioqKdPr06cv++QDgCUgSAfyu4uJiSSWJ1W9t3rxZVqtVvr6+ysnJ0dGjR1VcXKzTp087q37n7pekTZs2yc/PT97e3srIyHD2m5ub66wo/va+cz/33Ovi4mLZbDb169dPkyZN0rfffquff/5ZM2bMcC6mqV27tk6dOqUDBw6ocePGioqK0rPPPqtdu3Zp3759mjJlirNfh8NRKsbfex/OxQYAnoAkEcBF7du3TzNmzJAkvfbaa0pLSyt1vk+fPvL29tYdd9yhJUuWaODAgXrllVeUlZXl3IbmzTff1H/+8x9J0oABA5SRkaG7775bqampuv766/Xcc8/JbrfrnXfekSS9+uqrOnLkiHNl8rRp00q9fuWVVyRJkyZNUvv27fXwww/rgQceULt27ZzD4X/84x81efJkffTRR7LZbHrjjTdUr149DRs2TE8++aRuvfVWBQUF6b333tOxY8c0f/58ffPNNxd8D7766itNnjxZhw8fVkJCgt59990LViwBoKaxGBebEAQAAACPRSURAAAAJiSJAAAAMCFJBAAAgAlJIgAAAExIEgEAAGBCkggAAAATkkQAAACYkCQCAADAhCQRAAAAJiSJAAAAMCFJBAAAgMn/A8LHpnFpizVlAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 80\u001b[0m\u001b[1;36m0x600\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "data = np.array([\n",
+    "    [155.5, 110.1, 505.2, 120.3, 125.4, 190.5],\n",
+    "    [106.6, 111.2, 116.3, 121.4, 126.5, 131.6],\n",
+    "    [107.7, 112.3, 117.4, 122.5, 127.6, 132.7],\n",
+    "    [108.8, 113.4, 218.5, 123.6, 128.7, 133.8],\n",
+    "    [2299.9, 114.5, 119.6, 124.7, 129.8, 204.9],\n",
+    "    [111.0, 115.6, 120.7, 125.8, 130.9, 1000.0]\n",
+    "])\n",
+    "\n",
+    "# Generate x and y coordinates for the data points\n",
+    "x = np.arange(5, 35, 5)\n",
+    "y = np.arange(5, 35, 5)\n",
+    "x, y = np.meshgrid(x, y)\n",
+    "\n",
+    "\n",
+    "fig, ax = plt.subplots(figsize=(8, 6))\n",
+    "\n",
+    "# Create the 2D histogram\n",
+    "hist = ax.hist2d(x.flatten(), y.flatten(), bins=[6, 6], weights=data.flatten(), cmap='viridis')\n",
+    "\n",
+    "# Add color bar\n",
+    "plt.colorbar(hist[3], ax=ax)\n",
+    "\n",
+    "# Set axis labels\n",
+    "ax.set_xlabel('Parameter 1')\n",
+    "ax.set_ylabel('Parameter 2')\n",
+    "ax.set_title('2D Histogram of Measurements')\n",
+    "\n",
+    "# Customize grid lines color\n",
+    "ax.grid(which='both', color='gray', linestyle='-', linewidth=2)\n",
+    "\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "\n",
+       "\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m,\n",
+       "       \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m,  \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m8\u001b[0m, \u001b[1;36m13\u001b[0m, \u001b[1;36m21\u001b[0m, \u001b[1;36m34\u001b[0m\u001b[1m]\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "x = [1, 2, 3, 5, 8, 13, 21, 34]\n",
+    "y = [1, 2, 3, 5, 8, 13, 21, 34]\n",
+    "# print(f\"{x=}\")\n",
+    "x, y = np.meshgrid(x, y)\n",
+    "\n",
+    "x"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
Q1=1.5\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[33mQ1\u001b[0m=\u001b[1;36m1\u001b[0m\u001b[1;36m.5\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Original data: [  1   2   3   4   5   6   7   8   9  10 100]\n",
+       "
\n" + ], + "text/plain": [ + "Original data: \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;36m2\u001b[0m \u001b[1;36m3\u001b[0m \u001b[1;36m4\u001b[0m \u001b[1;36m5\u001b[0m \u001b[1;36m6\u001b[0m \u001b[1;36m7\u001b[0m \u001b[1;36m8\u001b[0m \u001b[1;36m9\u001b[0m \u001b[1;36m10\u001b[0m \u001b[1;36m100\u001b[0m\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Filtered data: [  1   2   3   4   5   6   7   8   9  10 100]\n",
+       "
\n" + ], + "text/plain": [ + "Filtered data: \u001b[1m[\u001b[0m \u001b[1;36m1\u001b[0m \u001b[1;36m2\u001b[0m \u001b[1;36m3\u001b[0m \u001b[1;36m4\u001b[0m \u001b[1;36m5\u001b[0m \u001b[1;36m6\u001b[0m \u001b[1;36m7\u001b[0m \u001b[1;36m8\u001b[0m \u001b[1;36m9\u001b[0m \u001b[1;36m10\u001b[0m \u001b[1;36m100\u001b[0m\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Sample data\n", + "data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100])\n", + "\n", + "# Calculate the first quartile (Q1) and the third quartile (Q3)\n", + "Q1 = np.percentile(data, 5)\n", + "Q3 = np.percentile(data, 95)\n", + "print(f\"{Q1=}\")\n", + "\n", + "# Calculate the Interquartile Range (IQR)\n", + "IQR = Q3 - Q1\n", + "\n", + "# Determine the lower and upper bounds for outliers\n", + "lower_bound = Q1 - 1.5 * IQR\n", + "upper_bound = Q3 + 1.5 * IQR\n", + "\n", + "# Filter the data to remove top outliers\n", + "filtered_data = data[data <= upper_bound]\n", + "\n", + "print(\"Original data:\", data)\n", + "print(\"Filtered data:\", filtered_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m \u001b[1;36m2\u001b[0m,  \u001b[1;36m3\u001b[0m,  \u001b[1;36m4\u001b[0m,  \u001b[1;36m5\u001b[0m,  \u001b[1;36m6\u001b[0m,  \u001b[1;36m7\u001b[0m,  \u001b[1;36m8\u001b[0m,  \u001b[1;36m9\u001b[0m, \u001b[1;36m10\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "\n",
+    "data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100])\n",
+    "\n",
+    "data[1:-1]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": [
+       "\u001b[1;35marray\u001b[0m\u001b[1m(\u001b[0m\u001b[1m[\u001b[0m\u001b[1;36m0\u001b[0m, \u001b[1;36m1\u001b[0m, \u001b[1;36m2\u001b[0m, \u001b[1;36m3\u001b[0m\u001b[1m]\u001b[0m\u001b[1m)\u001b[0m"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a = np.array([1, 3, 2, 0])\n",
+    "np.sort(a)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/scripts/analyse-schedules-experiment.ipynb b/scripts/analyse-schedules-experiment.ipynb
new file mode 100644
index 00000000..eb070e4e
--- /dev/null
+++ b/scripts/analyse-schedules-experiment.ipynb
@@ -0,0 +1,408 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import sys\n",
+    "import os\n",
+    "\n",
+    "sys.path.append('scripts')\n",
+    "\n",
+    "import re\n",
+    "import json\n",
+    "import argparse\n",
+    "import itertools\n",
+    "from pathlib import Path\n",
+    "import collections\n",
+    "import math\n",
+    "from dataclasses import dataclass,asdict, astuple\n",
+    "from concurrent.futures import ProcessPoolExecutor\n",
+    "\n",
+    "import numpy as np\n",
+    "import matplotlib.pyplot as plt\n",
+    "# from matplotlib.font_manager import FontProperties\n",
+    "import matplotlib.font_manager as fm\n",
+    "from matplotlib.patches import FancyBboxPatch\n",
+    "from matplotlib.patches import PathPatch\n",
+    "from matplotlib.path import get_path_collection_extents\n",
+    "import seaborn as sns\n",
+    "\n",
+    "from rich import print, pretty\n",
+    "from typing import  Iterable, List\n",
+    "import pretty_errors\n",
+    "from catppuccin import PALETTE\n",
+    "\n",
+    "from utils import *\n",
+    "from ldj import ldj\n",
+    "\n",
+    "pretty.install()\n",
+    "\n",
+    "RESULT_DIR: Path = Path(\"../experiments/schedules\")\n",
+    "\n",
+    "assert RESULT_DIR.is_dir() and RESULT_DIR.exists()\n",
+    "\n",
+    "flavor = PALETTE.latte.colors\n",
+    "# num-robots-10-seed-0.json\n",
+    "# experiments/schedules/schedule-centered-internal-50-external-5-seed-0.json\n",
+    "# RE = re.compile(r\"schedule-(\\w-)-internal-(\\d+)-external-(\\d+)-seed-(\\d+).json\")\n",
+    "RE = re.compile(r'schedule-([\\w-]+)-internal-(\\d+)-external-(\\d+)-seed-(\\d+)\\.json')\n",
+    "\n",
+    "\n",
+    "# use LaTeX for text with matplotlib\n",
+    "sns.set_style(\"darkgrid\")\n",
+    "# set background color of sns darkgrid to flavor.base.hex\n",
+    "plt.rcParams['axes.facecolor'] = flavor.base.hex\n",
+    "# set font color to flavor.text.hex\n",
+    "plt.rcParams['text.color'] = flavor.text.hex\n",
+    "\n",
+    "font_dirs = [\"./fonts/\"]\n",
+    "# go through all fonts in the font directory and add them\n",
+    "for font_dir in font_dirs:\n",
+    "    for font in os.listdir(font_dir):\n",
+    "        fm.fontManager.addfont(f\"{font_dir}/{font}\")\n",
+    "\n",
+    "prop_jbm = fm.FontProperties(fname='./fonts/JetBrainsMonoNerdFontMono-Regular.ttf')\n",
+    "prop = fm.FontProperties(fname='./fonts/STIXTwoText-VariableFont_wght.ttf')\n",
+    "\n",
+    "plt.rcParams.update({\n",
+    "    # \"text.usetex\": True,\n",
+    "    \"font.family\": prop.get_name(),\n",
+    "    # \"font.family\": \"stix\",\n",
+    "    # \"font.sans-serif\": prop.get_name(),\n",
+    "    \"mathtext.fontset\": \"stix\",\n",
+    "    # \"text.latex.preamble\": r\"\\usepackage{fontenc}\\usepackage{fontspec}\\setmainfont{JetBrainsMonoNerdFontMono-Regular}\",\n",
+    "})\n",
+    "\n",
+    "\n",
+    "colors = [\n",
+    "    (flavor.lavender.hex, 1.0, (1, 0), 'o'),\n",
+    "    (flavor.yellow.hex, 0.3, (2, 2), 'X'),\n",
+    "    (flavor.peach.hex, 0.3, (2, 2), 'X'),\n",
+    "    (flavor.green.hex, 1.0, (2, 2), '^')\n",
+    "]\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "def flatten(lst: Iterable) -> list:\n",
+    "    return list(itertools.chain.from_iterable(lst))\n",
+    "\n",
+    "\n",
+    "@dataclass(frozen=True)\n",
+    "class ExperimentParams:\n",
+    "    schedule: str\n",
+    "    internal: int\n",
+    "    external: int\n",
+    "    seed: int\n",
+    "\n",
+    "@dataclass\n",
+    "class ProcessedData:\n",
+    "    distance_travelled: list[float]\n",
+    "    finished_at: list[float]\n",
+    "    ldj: list[float]\n",
+    "    makespan: float\n",
+    "    robot_collisions: int\n",
+    "    params: ExperimentParams\n",
+    "\n",
+    "\n",
+    "def process_file(file) -> ProcessedData:\n",
+    "    print(f\"{file.name=}\")\n",
+    "    match = RE.match(file.name)\n",
+    "    assert match is not None\n",
+    "    schedule = str(match.group(1))\n",
+    "    internal = int(match.group(2))\n",
+    "    external = int(match.group(3))\n",
+    "    seed = int(match.group(4))\n",
+    "\n",
+    "    with open(file, 'r') as file:\n",
+    "        data = json.load(file)\n",
+    "\n",
+    "    distance_travelled_of_each_robot: list[float] = []\n",
+    "    finished_at_of_each_robot: list[float] = []\n",
+    "    ldj_of_each_robot: list[float] = []\n",
+    "    robot_collisions: int = len(data['collisions']['robots'])\n",
+    "    environment_collisions: int = len(data['collisions']['environment'])\n",
+    "\n",
+    "    for _, robot_data in data['robots'].items():\n",
+    "        positions = np.array(robot_data['positions'])\n",
+    "        distance_travelled: float = np.sum(np.linalg.norm(np.diff(positions, axis=0), axis=1))\n",
+    "        distance_travelled_of_each_robot.append(distance_travelled)\n",
+    "\n",
+    "        mission = robot_data['mission']\n",
+    "        # robot_collisions += robot_data['collisions']['robots']\n",
+    "\n",
+    "        started_at: float = mission['started_at']\n",
+    "        finished_at: float = mission['finished_at'] if mission['finished_at'] else mission['duration'] + started_at\n",
+    "        finished_at_of_each_robot.append(finished_at)\n",
+    "\n",
+    "        timestamps: np.ndarray = np.array([measurement['timestamp'] for measurement in robot_data['velocities']])\n",
+    "        velocities3d_bevy: np.ndarray = np.array([measurement['velocity'] for measurement in robot_data['velocities']])\n",
+    "        velocities = velocities3d_bevy[:, [0, 2]]\n",
+    "\n",
+    "        ldj_metric = ldj(velocities, timestamps)\n",
+    "        ldj_of_each_robot.append(ldj_metric)\n",
+    "\n",
+    "    makespan: float = data['makespan']\n",
+    "\n",
+    "    params = ExperimentParams(\n",
+    "        internal=internal,\n",
+    "        external=external,\n",
+    "        seed=seed,\n",
+    "        schedule=schedule\n",
+    "    )\n",
+    "\n",
+    "    return ProcessedData(\n",
+    "        distance_travelled=distance_travelled_of_each_robot,\n",
+    "        finished_at=finished_at_of_each_robot,\n",
+    "        ldj=ldj_of_each_robot,\n",
+    "        robot_collisions=robot_collisions,\n",
+    "        makespan=makespan,\n",
+    "        params=params\n",
+    "    )\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "processed_data: list[ProcessedData] = []\n",
+    "with ProcessPoolExecutor() as executor:\n",
+    "    results = executor.map(process_file, RESULT_DIR.glob('*.json'))\n",
+    "\n",
+    "\n",
+    "processed_data = [data for data in results]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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3bvT09OTAwcOpL+/P0888UTa2tom9t19991Zu3Ztbrnllrz++utZt25dnnzyyVx55ZXn5A0AAADAdNH07eL79u1LZ2dnenp6kiRr1qzJ8PBwBgYGJvYcPXo0zzzzTG688cYkybx587J8+fLs3bu37KkBAABgGmr6k+yDBw+mu7t74rqtrS3VajWDg4NZuXJlkvduJ58zZ06uuOKKiX3d3d0ZHByc8sEqc2dP+TVwsTHntAJzTisw57QCcw7NafqT7Hq9nvb29klrHR0dqdfrU9oDAAAAl6qmI7tSqWRsbGzS2unTp9PZ2fmhe86cOZNKpfLxTgkAAAAXgaYje8mSJanVahPXjUYjtVotS5cunVjr7e3NO++8kxMnTkysHT58OMuWLSt0XAAAAJi+mo7svr6+jI6O5tChQ0mS/fv3Z/HixVm0aFH6+/tTq9Uyf/783HDDDXnqqaeSJCdOnMjg4GDWrVt3bk4PAAAA00hbo9FoNLv5pZdeygMPPJCFCxdmZGQk99xzT956661s2LAhDz30UFasWJHR0dFs3bo1V155ZWq1WjZu3JhVq1ady/cAAAAA08KUIhsAAAD415q+XRwAAAD4cCIbAAAAChHZAAAAUIjIBgAAgEJENgAAABRy2YX6jYeGhrJz584sWLAgR44cyZYtW1KtViftOXXqVO67777Mnz8/hw8fzvr163PttddeoBPD1DUz54cPH87WrVvz4osv5r/8l/+Se++9N9ddd90FOjFMXTNz/v9322235Zprrskdd9xxHk8JH0+zc95oNLJ379787W9/y9VXX51bb701M2b4TIOLQzNz/uKLL+bRRx9NT09PXnvttVx33XVZu3btBToxTM3evXtz4MCB/PnPf86ePXvy2c9+9gP3fewObVwA9Xq9sWbNmsb//t//u9FoNBr79+9v3HzzzY1333130r5NmzY1Hn/88Uaj0Wj8n//zfxr/7b/9t8axY8fO+3nho2h2zv/H//gfjePHjzfOnj3b2LFjR2P58uXmnItGs3P+fz366KON//pf/2vjf/2v/3U+jwkfS7Nzfvbs2cYdd9zR+O///b833n777QtxVPjImp3z66+/vvEf//EfjUaj0Thz5kzj2muvbbz55pvn/bzwURw5cqTxH//xH42rrrqq8fLLL//LfR+3Qy/Ij1b37duXzs7O9PT0JEnWrFmT4eHhDAwMTOw5evRonnnmmdx4441Jknnz5mX58uXZu3fvhTgyTFkzc3727Nl897vfTVdXV2bMmJFvfvObOXPmTF599dULdGqYmmbm/P965ZVXcvLkyXzmM585z6eEj6fZOd+9e3eOHTuWe++9N5dddsFuFoSPpNk5P3PmTF5++eUk7925MXPmzHR0dJzv48JHUq1WU6lUPnRPiQ69IJF98ODBdHd3T1y3tbWlWq1mcHBwYm1oaChz5szJFVdcMbHW3d09aQ9MZ83M+cyZM9PV1TVxfezYsXziE59Ib2/veT0rfFTNzHmSvP3223nkkUfyb//2b+f7iPCxNTvne/bsyTXXXJONGzfmpptuyiOPPHK+jwofWbNzfuedd+ZHP/pRHn744Tz44IP52c9+lssvv/x8HxfOmRIdekF+zFqv19Pe3j5praOjI/V6fUp7YDr7KDP82GOPZfPmzf/Pn7DBdNHsnP/617/Ot771rffthYtBM3P+5ptvZnh4ODNmzMhvfvObvPDCC7n11ltz1VVX5frrrz/fR4Ypa/Z/z9evX59XXnkljzzySD71qU/la1/72vk8JpxzJTr0gnySXalUMjY2Nmnt9OnT6ezs/NA9Z86cER9cNJqZ8/+/Z599NmfPns1tt912Po4HRTQz5y+88ELa29tz9dVXn+/jQRHNzPn4+HiS5Ctf+UpmzJiRz3/+81m1alX+8pe/nNezwkfV7H+3PPzww+nq6sqBAweyYsWKbNiwIUeOHDmfR4VzqkSHXpDIXrJkSWq12sR1o9FIrVbL0qVLJ9Z6e3vzzjvv5MSJExNrhw8fzrJly87rWeGjambO/6/nn38+f/rTn7J169Yk7z0LAheDZub88ccfz/3335/e3t709vbmH//4R375y1+mr6/vQhwZpqyZOZ83b15mzZqVN954Y2Ltk5/85Hk9J3wczcx5vV7Pz3/+83zjG9/IrFmzsm3btnz605/O008/fSGODOdEiQ69IJHd19eX0dHRHDp0KEmyf//+LF68OIsWLUp/f39qtVrmz5+fG264IU899VSS5MSJExkcHMy6desuxJFhypqZ8yT5+9//nscffzwbN25MrVbL888/n8cee+xCHh2a1sycb9u2Lf/85z8n/lmxYkX6+/v9RxkXjWbm/PLLL89NN92U5557Lsl7gfLyyy9n9erVF/Lo0LRm5nzGjBlpb2/PsWPHkrz33HZXV9e/vEsPpqN333130r+TZGxsrGiHXpBnsmfNmpVdu3Zl+/btWbhwYUZGRrJjx46cPHkyAwMDOX78eKrVan76059m69atefXVV1Or1fLggw9O+pIomM6amfOZM2fm9ttvT71ez+9///uJ127btu0Cnhya1+z/nsPFrNk537p1a+699978z//5P/Pmm2/m5ptvzhe+8IULfXxoSrNz/qtf/Sq/+MUvsnz58tTr9Sxbtixf/vKXL/TxoSm/+93v8sc//jHJe/+9/cUvfjEbNmwo3qFtjUajca7eBAAAALSSC3K7OAAAAFyKRDYAAAAUIrIBAACgEJENAAAAhYhsAAAAKERkAwAAQCEiGwAAAAoR2QAAAFCIyAYAAIBCRDYAAAAUIrIBAACgkP8PqzHetmK7CJQAAAAASUVORK5CYII=",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 120\u001b[0m\u001b[1;36m0x1200\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m3\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 60\u001b[0m\u001b[1;36m0x200\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 60\u001b[0m\u001b[1;36m0x200\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "\u001b[1m<\u001b[0m\u001b[1;95mFigure\u001b[0m\u001b[39m size 60\u001b[0m\u001b[1;36m0x200\u001b[0m\u001b[39m with \u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m Axes\u001b[0m\u001b[1m>\u001b[0m"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Group data by schedule type and external value\n",
+    "grouped_data = {}\n",
+    "for data in processed_data:\n",
+    "    key = (data.params.schedule, data.params.external)\n",
+    "    if key not in grouped_data:\n",
+    "        grouped_data[key] = {'ldj': [], 'distance_travelled': [], 'makespan': [], 'robot_collisions': []}\n",
+    "    grouped_data[key]['ldj'].extend(data.ldj)\n",
+    "    grouped_data[key]['distance_travelled'].extend(data.distance_travelled)\n",
+    "    grouped_data[key]['makespan'].append(data.makespan)\n",
+    "    # grouped_data[key]['robot_collisions'].append(data.robot_collisions)\n",
+    "\n",
+    "# Schedule types and external values\n",
+    "schedule_types = sorted(set(data.params.schedule for data in processed_data))\n",
+    "external_values = sorted(set(data.params.external for data in processed_data))\n",
+    "\n",
+    "# Plotting\n",
+    "fig, axes = plt.subplots(3, 1, figsize=(12, 12), sharex=True)\n",
+    "\n",
+    "bar_width = 0.15\n",
+    "group_width = bar_width * len(external_values) + 0.3\n",
+    "index = np.arange(len(schedule_types)) * group_width\n",
+    "opacity = 0.8\n",
+    "\n",
+    "nbars_per_group: int = len(external_values)\n",
+    "center_bar_index: int = math.ceil(nbars_per_group / 2)\n",
+    "\n",
+    "metrics = ['ldj', 'distance_travelled', 'makespan']\n",
+    "titles = ['LDJ Metric Value', 'Distance Travelled', 'Makespan']\n",
+    "y_labels = ['LDJ', 'Distance Travelled [$m$]', 'Makespan [$s$]']\n",
+    "\n",
+    "# Custom y-axis limits to make differences more pronounced\n",
+    "y_limits = [(-15, -8), (100, 120), (0, 40), (0, 10)]\n",
+    "\n",
+    "# Colors for different external values\n",
+    "base_colors = [flavor.mauve.hex, flavor.maroon.hex, flavor.yellow.hex, flavor.teal.hex, flavor.lavender.hex]\n",
+    "\n",
+    "# for ax, metric, title, ylabel, y_limit in zip(axes, metrics, titles, y_labels, y_limits):\n",
+    "for  metric, title, ylabel, y_limit in zip( metrics, titles, y_labels, y_limits):\n",
+    "    fig, ax = plt.subplots(figsize=(6, 2))\n",
+    "    \n",
+    "    for j, schedule_type in enumerate(schedule_types):\n",
+    "        # print(f\"{schedule_type=}\")\n",
+    "        for i, external_value in enumerate(external_values):\n",
+    "            # metric_values = np.mean(grouped_data[(schedule_type, external_value)][metric])\n",
+    "            metric_values = np.median(grouped_data[(schedule_type, external_value)][metric])\n",
+    "            bar_positions = index[j] + i * bar_width\n",
+    "            color = base_colors[j % len(base_colors)]\n",
+    "            alpha_value = 0.2 + (i * 0.2)\n",
+    "            ax.bar(bar_positions, metric_values, bar_width, alpha=alpha_value, color=color, label=f'External {external_value}' if i == 0 else \"\")\n",
+    "    # ax.set_ylabel(ylabel)\n",
+    "    ax.set_ylabel(ylabel, fontsize=12, fontdict={'color': flavor.text.hex})\n",
+    "\n",
+    "    # ax.set_title(title)\n",
+    "    ax.set_ylim(y_limit)\n",
+    "    # ax.legend()\n",
+    "    match metric:\n",
+    "        case 'ldj':\n",
+    "            # yticks = np.arange(-14, -6, -1)\n",
+    "            yticks = np.arange(-8, -16, -1)\n",
+    "            ax.set_yticks(yticks)\n",
+    "            ax.set_yticklabels(yticks, fontproperties=prop_jbm, fontdict=dict(color=flavor.text.hex))\n",
+    "            # pass\n",
+    "        case 'distance_travelled':\n",
+    "            # yticks = np.arange(100, 122.5, 2.5)\n",
+    "            yticks = np.arange(100, 125, 5)\n",
+    "            ax.set_yticks(yticks)\n",
+    "            ax.set_yticklabels(yticks, fontproperties=prop_jbm, fontdict=dict(color=flavor.text.hex))\n",
+    "            # pass\n",
+    "        case 'makespan':\n",
+    "            yticks = np.arange(0, 40, 5)\n",
+    "            ax.set_yticks(yticks)\n",
+    "            ax.set_yticklabels(yticks, fontproperties=prop_jbm, fontdict=dict(color=flavor.text.hex))\n",
+    "            # pass\n",
+    "\n",
+    "    if metric == 'ldj':\n",
+    "        ax.invert_yaxis()  # Invert y-axis for LDJ metric\n",
+    "\n",
+    "    # Annotate mean values below each group\n",
+    "    for j, schedule_type in enumerate(schedule_types):\n",
+    "        aggregated_value = np.mean([np.mean(grouped_data[(schedule_type, external_value)][metric]) for external_value in external_values])\n",
+    "\n",
+    "        x = index[j] + (group_width - bar_width  * center_bar_index) / 2\n",
+    "        y = y_limit[0] - (y_limit[0] - y_limit[1]) * 0.90\n",
+    "        if metric == 'ldj':\n",
+    "            y = y_limit[1] - (y_limit[1] - y_limit[0]) * 0.90\n",
+    "\n",
+    "        color = base_colors[j % len(base_colors)]\n",
+    "        ax.text(x, y, f'{aggregated_value:.2f}', ha='center', va='top', fontproperties=prop_jbm, fontdict=dict(color=color))\n",
+    "    \n",
+    "    ax.set_xticks([])\n",
+    "\n",
+    "    output = Path(f\"schedules-{metric}.svg\")\n",
+    "    fig.patch.set_facecolor((0, 0, 0, 0))\n",
+    "    # Draw optimal line\n",
+    "    # ax.axhline(y=100, color=flavor.overlay2.hex, linestyle='--', linewidth=1.5)\n",
+    "\n",
+    "    fig.tight_layout()\n",
+    "    fig.savefig(output)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/scripts/iteration-amount-average-distance-travelled.svg b/scripts/iteration-amount-average-distance-travelled.svg
new file mode 100644
index 00000000..570eb150
--- /dev/null
+++ b/scripts/iteration-amount-average-distance-travelled.svg
@@ -0,0 +1,1847 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+     
+     
+      
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+       
+      
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+   
+    
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+ 
+
diff --git a/scripts/iteration-amount-average-ldj.svg b/scripts/iteration-amount-average-ldj.svg
new file mode 100644
index 00000000..5d1d2fc6
--- /dev/null
+++ b/scripts/iteration-amount-average-ldj.svg
@@ -0,0 +1,2134 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+     
+     
+      
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+       
+      
+      
+       
+      
+     
+     
+      
+      
+       
+        
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+   
+    
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+ 
+
diff --git a/scripts/iteration-amount-average-makespan.svg b/scripts/iteration-amount-average-makespan.svg
new file mode 100644
index 00000000..be50ece5
--- /dev/null
+++ b/scripts/iteration-amount-average-makespan.svg
@@ -0,0 +1,1851 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+     
+     
+      
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+       
+      
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+   
+    
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+ 
+
diff --git a/scripts/iteration-amount-largest-time-differense.svg b/scripts/iteration-amount-largest-time-differense.svg
new file mode 100644
index 00000000..600cfd81
--- /dev/null
+++ b/scripts/iteration-amount-largest-time-differense.svg
@@ -0,0 +1,1926 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+     
+     
+      
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+   
+    
+    
+     
+     
+    
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+       
+      
+      
+       
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+       
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+   
+   
+   
+    
+   
+  
+ 
+ 
+  
+   
+  
+  
+   
+  
+ 
+
diff --git a/scripts/run-circle-expertiment.fish b/scripts/run-circle-expertiment.fish
index c9e69126..66e0083b 100755
--- a/scripts/run-circle-expertiment.fish
+++ b/scripts/run-circle-expertiment.fish
@@ -37,7 +37,7 @@ for seed in 0 31 227 252 805
             end
         end
 
-        RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i 'Circle Experiment' 2>/dev/null
+        RUST_LOG=magics=error ./target/release/magics -i 'Circle Experiment' 2>/dev/null
         set -l exported_json (printf '%s\n' export_circle\ experiment*.json | tail -n 1)
         # command mkdir -p (path basename "$output_file")
         mv "$exported_json" "$output_file"
diff --git a/scripts/run-collaborative-gp-experiment.fish b/scripts/run-collaborative-gp-experiment.fish
index e7e0b194..e4cca1c8 100755
--- a/scripts/run-collaborative-gp-experiment.fish
+++ b/scripts/run-collaborative-gp-experiment.fish
@@ -62,7 +62,7 @@ for seed in $seeds
                 end
             end
 
-            RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null
+            RUST_LOG=magics=error ./target/release/magics -i "$experiment" 2>/dev/null
             set -l exported_json (printf '%s\n' export_collaborative\ gp*.json | tail -n 1)
             set -l dirname (path dirname "$output_file")
             command mkdir -p "$dirname"
diff --git a/scripts/run-communication-failure-expertiment.fish b/scripts/run-communication-failure-expertiment.fish
index e6204780..eb661302 100755
--- a/scripts/run-communication-failure-expertiment.fish
+++ b/scripts/run-communication-failure-expertiment.fish
@@ -55,7 +55,7 @@ for seed in 0 31 227 252 805
                 end
             end
 
-            RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i 'Communications Failure Experiment' 2>/dev/null
+            RUST_LOG=magics=error ./target/release/magics -i 'Communications Failure Experiment' 2>/dev/null
             set -l exported_json (printf '%s\n' export_communications\ failure\ experiment*.json | tail -n 1)
             set -l dirname (path dirname "$output_file")
             command mkdir -p "$dirname"
diff --git a/scripts/run-environment-obstacles-experiment.fish b/scripts/run-environment-obstacles-experiment.fish
index 21f6a0f0..9637772c 100755
--- a/scripts/run-environment-obstacles-experiment.fish
+++ b/scripts/run-environment-obstacles-experiment.fish
@@ -57,7 +57,7 @@ for seed in 0 31 227 252 805
             end
         end
 
-        RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i 'Environment Obstacles Experiment' 2>/dev/null
+        RUST_LOG=magics=error ./target/release/magics -i 'Environment Obstacles Experiment' 2>/dev/null
         set -l exported_json (printf '%s\n' export_environment\ obstacles\ experiment*.json | tail -n 1)
         set -l dirname (path dirname "$output_file")
         command mkdir -p "$dirname"
diff --git a/scripts/run-iteration-amount-experiment.fish b/scripts/run-iteration-amount-experiment.fish
index a8ee58b8..a0be6b9e 100755
--- a/scripts/run-iteration-amount-experiment.fish
+++ b/scripts/run-iteration-amount-experiment.fish
@@ -71,7 +71,7 @@ for seed in 0 31 227 252 805
                 end
             end
 
-            RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i 'Iteration Amount Experiment' 2>/dev/null
+            RUST_LOG=magics=error ./target/release/magics -i 'Iteration Amount Experiment' 2>/dev/null
             set -l exported_json (printf '%s\n' export_iteration\ amount\ experiment*.json | tail -n 1)
             set -l dirname (path dirname "$output_file")
             command mkdir -p "$dirname"
diff --git a/scripts/run-schedules-experiment.fish b/scripts/run-schedules-experiment.fish
index 8c64f1e8..8d0ab647 100755
--- a/scripts/run-schedules-experiment.fish
+++ b/scripts/run-schedules-experiment.fish
@@ -51,7 +51,7 @@ for seed in 0 31 227 252 805
                 end
             end
 
-            RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i $experiment 2>/dev/null
+            RUST_LOG=magics=error ./target/release/magics -i $experiment 2>/dev/null
             set -l exported_json (printf '%s\n' export_schedules\ experiment*.json | tail -n 1)
             set -l dirname (path dirname "$output_file")
             command mkdir -p "$dirname"
diff --git a/scripts/run-solo-gp-experiment.fish b/scripts/run-solo-gp-experiment.fish
index 5d6b4180..17815a20 100755
--- a/scripts/run-solo-gp-experiment.fish
+++ b/scripts/run-solo-gp-experiment.fish
@@ -44,7 +44,7 @@ for seed in 0 31 227 252 805
             end
         end
 
-        RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i "$experiment" 2>/dev/null
+        RUST_LOG=magics=error ./target/release/magics -i "$experiment" 2>/dev/null
         set -l exported_json (printf '%s\n' export_solo\ gp*.json | tail -n 1)
         set -l dirname (path dirname "$output_file")
         command mkdir -p "$dirname"
diff --git a/scripts/run-varying-network-connectivity-experiment.fish b/scripts/run-varying-network-connectivity-experiment.fish
index ec29930f..0a351277 100755
--- a/scripts/run-varying-network-connectivity-experiment.fish
+++ b/scripts/run-varying-network-connectivity-experiment.fish
@@ -59,7 +59,7 @@ for seed in 0 31 227 252 805
             end
         end
 
-        RUST_LOG=gbpplanner_rs=error ./target/release/gbpplanner-rs -i 'Varying Network Connectivity Experiment' 2>/dev/null
+        RUST_LOG=magics=error ./target/release/magics -i 'Varying Network Connectivity Experiment' 2>/dev/null
         set -l exported_json (printf '%s\n' export_varying\ network\ connectivity\ experiment*.json | tail -n 1)
         set -l dirname (path dirname "$output_file")
         command mkdir -p "$dirname"
diff --git a/scripts/run.fish b/scripts/run.fish
index d8d6244b..fbea82cb 100755
--- a/scripts/run.fish
+++ b/scripts/run.fish
@@ -8,5 +8,5 @@ function run
 end
 
 set -l jobs (math (nproc) - 1) # leave one CPU core for interactivity
-set -lx RUST_LOG error, gbpplanner_rs=info
-cargo run --jobs=$jobs --bin gbpplanner-rs -- $argv
+set -lx RUST_LOG error, magics=info
+cargo run --jobs=$jobs --bin magics -- $argv
diff --git a/scripts/schedules-distance_travelled.svg b/scripts/schedules-distance_travelled.svg
new file mode 100644
index 00000000..7d8e4313
--- /dev/null
+++ b/scripts/schedules-distance_travelled.svg
@@ -0,0 +1,1189 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+      
+       
+        
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+  
+ 
+ 
+  
+   
+  
+ 
+
diff --git a/scripts/schedules-ldj.svg b/scripts/schedules-ldj.svg
new file mode 100644
index 00000000..699b29ff
--- /dev/null
+++ b/scripts/schedules-ldj.svg
@@ -0,0 +1,839 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+      
+       
+        
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+      
+      
+      
+      
+     
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+     
+    
+   
+  
+ 
+ 
+  
+   
+  
+ 
+
diff --git a/scripts/schedules-makespan.svg b/scripts/schedules-makespan.svg
new file mode 100644
index 00000000..a66e5886
--- /dev/null
+++ b/scripts/schedules-makespan.svg
@@ -0,0 +1,997 @@
+
+
+
+ 
+  
+   
+    
+    1980-01-01T00:00:00+00:00
+    image/svg+xml
+    
+     
+      Matplotlib v3.8.4, https://matplotlib.org/
+     
+    
+   
+  
+ 
+ 
+  
+ 
+ 
+  
+   
+  
+  
+   
+    
+   
+   
+   
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+        
+       
+       
+       
+      
+     
+    
+    
+     
+      
+     
+     
+      
+      
+       
+       
+      
+     
+    
+    
+     
+     
+      
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+       
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+     
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+   
+   
+    
+    
+     
+      
+      
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+      
+     
+     
+     
+     
+     
+     
+    
+   
+   
+    
+    
+     
+     
+     
+     
+     
+    
+   
+  
+ 
+ 
+  
+   
+  
+ 
+

From 4b8508b4b8b294639f0d15d2b08828b797f766d5 Mon Sep 17 00:00:00 2001
From: kpbaks 
Date: Tue, 4 Jun 2024 09:34:01 +0200
Subject: [PATCH 4/4] feat: handle merge

---
 config/simulations/Screenshot/config.toml     | 101 ++++++++++
 .../simulations/Screenshot/environment.yaml   |  12 ++
 config/simulations/Screenshot/formation.yaml  | 178 ++++++++++++++++++
 3 files changed, 291 insertions(+)
 create mode 100644 config/simulations/Screenshot/config.toml
 create mode 100644 config/simulations/Screenshot/environment.yaml
 create mode 100644 config/simulations/Screenshot/formation.yaml

diff --git a/config/simulations/Screenshot/config.toml b/config/simulations/Screenshot/config.toml
new file mode 100644
index 00000000..ff0e27e7
--- /dev/null
+++ b/config/simulations/Screenshot/config.toml
@@ -0,0 +1,101 @@
+# environment = "junction"
+environment_image = "junction_twoway"
+environment       = "./config/simulations/Intersection/environment.yaml"
+formation_group   = "./config/simulations/Intersection/formation.ron"
+
+[interaction]
+ui-focus-cancels-inputs = true
+default-cam-distance    = 150.0
+
+[visualisation.uncertainty]
+max-radius = 2.5
+scale      = 30.0
+
+[visualisation.height]
+objects    = 0.5
+height-map = 1.0
+
+[visualisation.draw]
+robots                             = true
+communication-graph                = false
+predicted-trajectories             = false
+waypoints                          = true
+uncertainty                        = false
+paths                              = false
+generated-map                      = true
+height-map                         = false
+sdf                                = false
+communication-radius               = false
+obstacle-factors                   = false
+tracking                           = false
+interrobot-factors                 = false
+interrobot-factors-safety-distance = false
+robot-colliders                    = false
+environment-colliders              = false
+robot-robot-collisions             = false
+robot-environment-collisions       = false
+
+
+[gbp]
+sigma-pose-fixed        = 1e-15
+sigma-factor-dynamics   = 0.5
+sigma-factor-interrobot = 0.005
+sigma-factor-obstacle   = 0.005
+sigma-factor-tracking   = 0.01
+lookahead-multiple      = 3
+
+[gbp.iteration-schedule]
+internal = 50
+external = 10
+schedule = "interleave-evenly"
+
+[robot]
+planning-horizon                       = 2.0
+target-speed                           = 15.0
+inter-robot-safety-distance-multiplier = 2.2
+
+[robot.radius]
+min = 2.5
+max = 2.5
+
+[robot.communication]
+radius       = 20.0
+failure-rate = 0.0
+
+[simulation]
+max-time           = 61.0
+time-scale         = 5.0
+manual-step-factor = 1
+hz                 = 10.0
+# world-size                                = 100.0
+prng-seed                                 = 805
+pause-on-spawn                            = false
+despawn-robot-when-final-waypoint-reached = true
+
+[rrt]
+max-iterations       = 1000000
+step-size            = 0.5
+collision-radius     = 0.1
+neighbourhood-radius = 10.0
+
+[rrt.smoothing]
+enabled        = true
+max-iterations = 500
+step-size      = 0.5
+
+[graphviz]
+export-location = "./assets/export/"
+
+[graphviz.interrobot.active]
+style = "dashed"
+len   = 8.0
+color = "red"
+
+[graphviz.interrobot.inactive]
+style = "dashed"
+len   = 8.0
+color = "gray"
+
+
+[manual]
+timesteps-per-step = 1
diff --git a/config/simulations/Screenshot/environment.yaml b/config/simulations/Screenshot/environment.yaml
new file mode 100644
index 00000000..ead4abfc
--- /dev/null
+++ b/config/simulations/Screenshot/environment.yaml
@@ -0,0 +1,12 @@
+tiles:
+  grid:
+  - ┼
+  settings:
+    tile-size: 100.0
+    path-width: 0.16
+    obstacle-height: 2.0
+    sdf:
+      resolution: 200
+      expansion: 0.025
+      blur: 0.01
+obstacles: []
diff --git a/config/simulations/Screenshot/formation.yaml b/config/simulations/Screenshot/formation.yaml
new file mode 100644
index 00000000..156e4882
--- /dev/null
+++ b/config/simulations/Screenshot/formation.yaml
@@ -0,0 +1,178 @@
+formations:
+- repeat:
+    every:
+      secs: 1
+      nanos: 0
+    times: !infinite
+  delay:
+    secs: 0
+    nanos: 500000000
+  robots: 1
+  planning-strategy: only-local
+  initial-position:
+    shape: !line-segment
+    - x: -0.0
+      y: 0.45
+    - x: -0.0
+      y: 0.55
+    placement-strategy: !random
+      attempts: 2000
+  waypoints:
+  - shape: !line-segment
+    - x: 1.15
+      y: 0.45
+    - x: 1.15
+      y: 0.55
+    projection-strategy: identity
+  # waypoint-reached-when-intersects: horizon
+  # finished-when-intersects: horizon
+
+  waypoint-reached-when-intersects:
+    distance: robot-radius
+    intersects-with: horizon
+  finished-when-intersects:
+    distance: robot-radius
+    intersects-with: horizon
+
+- repeat:
+    every:
+      secs: 1
+      nanos: 0
+    times: !infinite
+  delay:
+    secs: 0
+    nanos: 0
+  robots: 1
+  planning-strategy: only-local
+  initial-position:
+    shape: !line-segment
+    - x: 0.45
+      y: 1.0
+    - x: 0.55
+      y: 1.0
+    placement-strategy: !random
+      attempts: 1000
+  waypoints:
+  - shape: !line-segment
+    - x: 0.45
+      y: -0.15
+    - x: 0.55
+      y: -0.15
+    projection-strategy: identity
+  # waypoint-reached-when-intersects: horizon
+  # finished-when-intersects: !variable 4
+  # finished-when-intersects: horizon
+  waypoint-reached-when-intersects:
+    distance: robot-radius
+    intersects-with: horizon
+  finished-when-intersects:
+    distance: robot-radius
+    intersects-with: horizon
+
+# - repeat:
+#     every:
+#       secs: 1
+#       nanos: 0
+#     times: !finite 25
+#   delay:
+#     secs: 0
+#     nanos: 500000000
+#   robots: 1
+#   planning-strategy: only-local
+#   initial-position:
+#     shape: !line-segment
+#     - x: -0.05
+#       y: 0.45
+#     - x: -0.05
+#       y: 0.45
+#     placement-strategy: !random
+#       attempts: 1000
+#   waypoints:
+#   - shape: !line-segment
+#     - x: 1.3
+#       y: 0.45
+#     - x: 1.3
+#       y: 0.45
+#     projection-strategy: identity
+#   waypoint-reached-when-intersects: horizon
+#
+# - repeat:
+#     every:
+#       secs: 1
+#       nanos: 0
+#     times: !finite 20
+#   delay:
+#     secs: 0
+#     nanos: 0
+#   robots: 1
+#   planning-strategy: only-local
+#   initial-position:
+#     shape: !line-segment
+#     - x: -0.05
+#       y: 0.55
+#     - x: -0.05
+#       y: 0.55
+#     placement-strategy: !random
+#       attempts: 1000
+#   waypoints:
+#   - shape: !line-segment
+#     - x: 1.3
+#       y: 0.55
+#     - x: 1.3
+#       y: 0.55
+#     projection-strategy: identity
+#   waypoint-reached-when-intersects: horizon
+#
+# - repeat:
+#     every:
+#       secs: 1
+#       nanos: 500000000
+#     times: !finite 10
+#   delay:
+#     secs: 0
+#     nanos: 500000000
+#   robots: 1
+#   planning-strategy: only-local
+#   initial-position:
+#     shape: !line-segment
+#     - x: 0.45
+#       y: 1.05
+#     - x: 0.45
+#       y: 1.05
+#     placement-strategy: !random
+#       attempts: 1000
+#   waypoints:
+#   - shape: !line-segment
+#     - x: 0.45
+#       y: -0.3
+#     - x: 0.45
+#       y: -0.3
+#     projection-strategy: identity
+#   waypoint-reached-when-intersects: horizon
+#
+# - repeat:
+#     every:
+#       secs: 2
+#       nanos: 0
+#     times: !finite 10
+#   delay:
+#     secs: 0
+#     nanos: 0
+#   robots: 1
+#   planning-strategy: only-local
+#   initial-position:
+#     shape: !line-segment
+#     - x: 0.55
+#       y: 1.05
+#     - x: 0.55
+#       y: 1.05
+#     placement-strategy: !random
+#       attempts: 1000
+#   waypoints:
+#   - shape: !line-segment
+#     - x: 0.55
+#       y: -0.3
+#     - x: 0.55
+#       y: -0.3
+#     projection-strategy: identity
+#   waypoint-reached-when-intersects: horizon