-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add reset() support to the Transaction object #199
Comments
I am definitely not opposed to streamlining the reset operation. Adding a reset option to the transaction is an interesting idea, but I'll need to spend some time to fully understand all of the ramifications. But a few immediate thoughts:
|
If Boost Serialization versioning works well, yes, I totally agree. 👍
I admit I didn't think about that this time, but I actually gave that a thought some time ago and I just forgot to check what I wrote down and share it. This is what I came with, which I believe it'd address the need for a reset hook: Currently, the fixed lag smoother relies on a reset service to reset the optimizer state: https://github.com/clearpathrobotics/fuse/blob/e9366b2a15bbaccb84f060f17d45fd0972c52e79/fuse_optimizers/src/fixed_lag_smoother.cpp#L395 This means the ignition sensor models must call that reset service, which looks a bit sketchy: https://github.com/clearpathrobotics/fuse/blob/e9366b2a15bbaccb84f060f17d45fd0972c52e79/fuse_models/src/unicycle_2d_ignition.cpp#L236 Instead of that, we could have a reset callback in the sensor models, so the reset service doesn't have to be called. We can still have the reset service, but the ignition sensor models wouldn't have to use it. Instead, they can use a cleaner and more efficient mechanism. This should be relatively easy to implement:
In principle, this should also allow to re-implement the
First of all, the motivation is to make the reset logic faster, but actually in the sense that we don't miss measurements while resetting, which happens with the existing We need to be careful if we end up clearing the callback queue, since IIRC that could leave things in a bad state, probably only if done from inside a callback. Either way, I believe any transaction generated by the sensor models would be filtered out in the optimizer, since it'd be older than the reset transaction, which would have a logic similar to the current one for the ignition sensor models. I think we still need that part. Transmitting the reset time to the sensor/motion models might be an option. But TBH I don't want to push for a change that would make things more complex.
Makes sense and this sounds similar to what I'm proposing above, with the Thanks for creating an issue to discuss this. What are your thoughts about the |
From @efernandez
I've been thinking of some changes for the ignition/reset logic. Below I try to explain my proposed changes in brief:
fuse/fuse_core/src/graph.cpp
Lines 69 to 95 in da477ad
The actual way we request all variables or constraints to be removed from the graphs could be done hiding the detail of the special UUID value used to indicate that. That means we could have:
or probably only allow to remove all variables if also all constraints are removed, in which case we could simply expose a method to do transaction.removeAll(); or transaction.clear();, or something similar.
where clearConstraints() and clearVariables() could be new pure virtual methods:
that could be efficiently implemented as follows for the fuse_graphs::HashGraph:
I believe Transaction::merge() should work as is:
fuse/fuse_core/src/transaction.cpp
Lines 215 to 235 in da477ad
It shouldn't be a problem to have more than one fuse_core::uuid::NIL removed variable or constraint, although it'd be handled as a single one. Similarly, with the implementation proposed above for the Graph::update() method, the removal of all variables or constraints in the graph would happen before any additions. This allows an ignition sensor to create a new prior constraint at the same time it request the current graph to be cleared. For instance, the fuse_models::Unicycle2DIgnition that sends this transaction:
fuse/fuse_models/src/unicycle_2d_ignition.cpp
Lines 317 to 332 in da477ad
Would simply have to add this to that transaction before calling sendTransaction:
It shouldn't be a problem if this transactions get merged with others, that would add more variables and constraints, because the graph would be cleared before adding any variables or constraints. This will still rely on the optimizer to purge any transaction before the ignition one. If we want, I think it'd be possible to detect a transaction has fuse_core::uuid::NIL, and consider that as an ignition transaction, or a non-mergeable transaction. Technically, it can get merged with future transaction, but not with past ones. But if we never merge it, it'd be fine, and equivalent to what we do now.
I believe this would allow us to get rid of the reset logic in the ignition sensor models:
fuse/fuse_models/src/unicycle_2d_ignition.cpp
Lines 227 to 241 in da477ad
This would make them easier to implement. It'd also make things faster to update and we wouldn't lose any transactions that we currently lose when we call the reset service. That happens because it takes time to reset, and it stops all the plugins, so they stop receiving measurements. The approach proposed here is equivalent to not using the reset service, which can actually be used now. So certainly, this functionality already exists. The only difference is that with this change we can indicate we want the graph to be cleared at the transaction level, which I believe we can't do now.
I wonder if ignition sensor really have to support calling the reset service. After all, if the graph gets cleared, all plugins will get notified about that. Maybe it's too late and some sensor models could have already generated constraints that reference variables from the graph before clearing it. 🤔
The text was updated successfully, but these errors were encountered: