Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6872283
Fix #27: Panic was being caused by invalid access to bitfield
arjo129 Apr 7, 2025
f31c9d9
Add arclength calculation
arjo129 Apr 10, 2025
2e92318
Add triage github action (#31)
luca-della-vedova Jun 16, 2025
3bd056d
Migrate to the stable Rust toolchain (#30)
mxgrey Jun 30, 2025
e5c8c41
fix: Spatial Canvas scaling boundary constraints (#33)
kalifun Jul 15, 2025
04e67d5
feat: add benchmarking infrastructure for Moving AI datasets
arjo129 Apr 7, 2026
106fc33
Merge branch 'main' into arjoc/feat/benchmark-infra
arjo129 Apr 7, 2026
fd6f287
feat: implement FOCAL search in negotiation loop and add benchmark re…
arjo129 Apr 9, 2026
a419420
chore: update focal_weight to 1.5
arjo129 Apr 9, 2026
6b25f8b
chore: run cargo fmt
arjo129 Apr 10, 2026
e859e18
feat: rename negotiate to negotiate_focal and add weight parameter
arjo129 Apr 10, 2026
32962bc
docs: Add usage docs
arjo129 Jun 18, 2026
7b3755b
docs: Add movingai related documentation
arjo129 Jun 18, 2026
59edc4c
address feedback
arjo129 Jun 18, 2026
c0e86fb
Update benchmarks
arjo129 Jun 18, 2026
3a5023f
Clean up
arjo129 Jun 18, 2026
7d777bb
Merge branch 'arjoc/feat/benchmark-infra' into arjoc/temp-benchmark-f…
arjo129 Jun 23, 2026
89e5a9c
Adds an argparse description
arjo129 Jun 26, 2026
4b0d504
More docs
arjo129 Jun 26, 2026
99a8350
Add link to full map format
mxgrey Sep 7, 2026
a738753
Merge branch 'arjoc/feat/benchmark-infra' into arjoc/temp-benchmark-f…
mxgrey Sep 7, 2026
240d560
Reduce cloning and panicking
mxgrey Sep 7, 2026
884501d
qMerge remote-tracking branch 'origin/main' into arjoc/temp-benchmark…
mxgrey Sep 8, 2026
c4c9f2d
Fix style
mxgrey Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions mapf-viz/examples/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,11 @@ impl App {

self.canvas.program.layers.3.searches.clear();

for ticket in self.search_memory.iter().take(self.debug_ticket_size as usize) {
for ticket in self
.search_memory
.iter()
.take(self.debug_ticket_size as usize)
{
if let Some(mt) = search
.memory()
.0
Expand Down Expand Up @@ -1319,9 +1323,9 @@ impl App {
let mut total_length = 0.0;
for solution in solution_node.proposals.values() {
total_length += solution.meta.trajectory.windows(2).fold(0.0, |acc, w| {
(w[0].position.translation.vector - w[1].position.translation.vector).magnitude() + acc
(w[0].position.translation.vector - w[1].position.translation.vector).magnitude()
+ acc
});

}
println!("Total length: {total_length}");
assert!(self.canvas.program.layers.3.solutions.is_empty());
Expand Down Expand Up @@ -1997,7 +2001,10 @@ impl Application for App {
.push(iced::Space::with_width(Length::Units(16)))
.push(
Column::new()
.push(Text::new(format!("Debug Paths: {}", &self.debug_ticket_size)))
.push(Text::new(format!(
"Debug Paths: {}",
&self.debug_ticket_size
)))
.push(iced::Space::with_height(Length::Units(2)))
.push(
Slider::new(
Expand Down
74 changes: 57 additions & 17 deletions mapf/src/negotiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::{
};
use std::{
cmp::Reverse,
collections::{BinaryHeap, HashMap, HashSet},
collections::{BTreeSet, HashMap, HashSet},
sync::Arc,
};

Expand All @@ -64,6 +64,21 @@ pub fn negotiate(
HashMap<usize, String>,
),
NegotiationError,
> {
negotiate_focal(scenario, queue_length_limit, 1.0)
}

pub fn negotiate_focal(
scenario: &Scenario,
queue_length_limit: Option<usize>,
weight: f64,
) -> Result<
(
NegotiationNode,
Vec<NegotiationNode>,
HashMap<usize, String>,
),
NegotiationError,
> {
let cs = scenario.cell_size;
let mut conflicts = HashMap::new();
Expand Down Expand Up @@ -200,14 +215,43 @@ pub fn negotiate(
};

for root in negotiations.values() {
let mut queue: BinaryHeap<QueueEntry> = BinaryHeap::new();
let mut queue: BTreeSet<QueueEntry> = BTreeSet::new();
let root = NegotiationNode::from_root(root, &ideal, base_env.clone(), arena.len());
arena.push(root.clone());
queue.push(QueueEntry::new(root));
queue.insert(QueueEntry::new(root));

let mut solution = None;
let mut iters = 0;
while let Some(mut top) = queue.pop() {
while !queue.is_empty() {
let mut top = {
let focal_weight = weight;

// SAFETY: We check that queue is not empty at the start of
// each loop.
let mut best_entry = queue.first().unwrap();

let min_f = best_entry.node.cost.0;
let threshold = min_f * focal_weight;

for entry in queue.iter().take_while(|e| e.node.cost.0 <= threshold) {
if entry.node.negotiation.conflicts.len()
< best_entry.node.negotiation.conflicts.len()
{
best_entry = entry;
}
}

let best_id = best_entry.node.id;
// SAFETY: best_entry was found inside queue, and queue was
// not modified before this function was called, so a node
// with this ID must still exist in the queue. Also, all IDs
// within the queue are unique.
queue
.extract_if(.., |entry| entry.node.id == best_id)
.next()
.unwrap()
};

iters += 1;
if iters % 10 == 0 {
dbg!(iters);
Expand All @@ -217,7 +261,7 @@ pub fn negotiate(

// Dump the remaining queue into the node history
println!("Queue begins at {}", arena.len() + 1);
while let Some(remainder) = queue.pop() {
while let Some(remainder) = queue.pop_first() {
arena.push(remainder.node);
}

Expand Down Expand Up @@ -395,7 +439,7 @@ pub fn negotiate(
arena.len(),
);
arena.push(node.clone());
queue.push(QueueEntry::new(node));
queue.insert(QueueEntry::new(node));
}
}

Expand Down Expand Up @@ -660,27 +704,23 @@ struct QueueEntry {

impl PartialOrd for QueueEntry {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if f64::abs(self.node.cost.0 - other.node.cost.0) < 0.1 {
Reverse(self.node.depth).partial_cmp(&Reverse(other.node.depth))
} else {
Reverse(self.node.cost).partial_cmp(&Reverse(other.node.cost))
}
Some(self.cmp(other))
}
}

impl PartialEq for QueueEntry {
fn eq(&self, other: &Self) -> bool {
self.node.cost.eq(&other.node.cost)
self.node.id == other.node.id
}
}

impl Ord for QueueEntry {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
if f64::abs(self.node.cost.0 - other.node.cost.0) < 0.1 {
self.node.depth.cmp(&self.node.depth)
} else {
Reverse(self.node.cost).cmp(&Reverse(other.node.cost))
}
self.node
.cost
.cmp(&other.node.cost)
.then_with(|| Reverse(self.node.depth).cmp(&Reverse(other.node.depth)))
.then_with(|| self.node.id.cmp(&other.node.id))
}
}
impl Eq for QueueEntry {}
Expand Down
Loading