-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Hi there,
I've been using forester for the last few days, nice work creating a library that's well documented with a full feature set.
My use case will involve re-running the same tree several times a second, and so it would be excellent for the library to support this in an efficient way. Crucially, I would like to avoid restarting the daemons each time the tree is re-run.
I've outlined a few potential designs for how this might be achieved below, roughly in order of usability I think they'd expose to the user:
- Expose API for
forester_rs::runtime::forester::Foresterto separate ticking the tree from cleaning up the tree, which could be done either by:- Exposing a way to manually tick the tree (and so use forester less as a framework and more as a standalone behavior tree library), e.g.
// Build the tree let mut forester = fb.build().unwrap(); // Tick until Success or failure is reached let mut tick_result = forester_rs::runtime::TickResult::Running; while tick_result == forester_rs::runtime::TickResult::Running { tick_result = forester.tick().unwrap(); // Do other jobs here... } // Shutdown the HTTP server and daemons forester.cleanup().unwrap();
- Store a flag in the
Foresterstruct to avoid shutting down the HTTP server and daemons afterrun()returns (I think this would be the easiest to implement), e.g.
// Disable automatic cleanup fb.use_manual_cleanup(); // Build the tree let mut forester = fb.build().unwrap(); // Run until failure is reached while forester.run().unwrap() == forester_rs::runtime::TickResult::Success { // Rerun the tree at 20Hz std::thread::sleep(std::time::Duration::from_millis(50)); } // Shutdown the HTTP server and daemons forester.cleanup().unwrap();
- Implement a
KeepRunningUntilFailuredecorator, as implemented by BehaviorTree.CPP.- This is my personal least favorite solutions, since the daemons will be terminated without any context of why the tree exited.
- This could work if it was combined with manual cleanup of daemons (like above) or perhaps if the result of
forester.run()was made available to daemons.
I'm more than happy to contribute this change as a PR myself, I just wanted to collaborate on which method you thought would be most idiomatic for Forester. I'm personally in favour of 1.ii followed by 1.i.
I've also got a handful of minor improvements I've noted while using the library, if you're receptive to it I'm happy to submit these as PRs.