-
Notifications
You must be signed in to change notification settings - Fork 111
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
[RST-2128] fixed lag smoother reset #61
Changes from all commits
dfa9cf9
9030c87
c97ed67
3510fc6
4fa11e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ set(build_depends | |
fuse_graphs | ||
pluginlib | ||
roscpp | ||
std_srvs | ||
) | ||
|
||
find_package(catkin REQUIRED COMPONENTS | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,26 +88,19 @@ FixedLagSmoother::FixedLagSmoother( | |
transaction_timeout_.fromSec(transaction_timeout); | ||
|
||
private_node_handle_.getParam("ignition_sensors", ignition_sensors_); | ||
if (ignition_sensors_.empty()) | ||
{ | ||
// No ignition sensors were provided. Auto-start. | ||
started_ = true; | ||
start_time_ = ros::Time(0, 0); | ||
ROS_INFO_STREAM("No ignition sensors were specified. Optimization will begin immediately."); | ||
} | ||
else | ||
// Sort the sensors for efficient lookups | ||
std::sort(ignition_sensors_.begin(), ignition_sensors_.end()); | ||
// Warn about possible configuration errors | ||
for (const auto& sensor_model_name : ignition_sensors_) | ||
{ | ||
for (const auto& sensor_model_name : ignition_sensors_) | ||
if (sensor_models_.find(sensor_model_name) == sensor_models_.end()) | ||
{ | ||
if (sensor_models_.find(sensor_model_name) == sensor_models_.end()) | ||
{ | ||
ROS_WARN_STREAM("Sensor '" << sensor_model_name << "' is configured as an ignition sensor, but no sensor " | ||
"model with that name currently exists. This is likely a configuration error."); | ||
} | ||
ROS_WARN_STREAM("Sensor '" << sensor_model_name << "' is configured as an ignition sensor, but no sensor " | ||
"model with that name currently exists. This is likely a configuration error."); | ||
} | ||
// Sort the sensors for efficient lookups | ||
std::sort(ignition_sensors_.begin(), ignition_sensors_.end()); | ||
} | ||
// Test for auto-start | ||
autostart(); | ||
|
||
// Start the optimization thread | ||
optimization_thread_ = std::thread(&FixedLagSmoother::optimizationLoop, this); | ||
|
@@ -117,6 +110,9 @@ FixedLagSmoother::FixedLagSmoother( | |
optimization_period_, | ||
&FixedLagSmoother::optimizerTimerCallback, | ||
this); | ||
|
||
// Advertise a service that resets the optimizer to its initial state | ||
reset_service_server_ = private_node_handle_.advertiseService("reset", &FixedLagSmoother::resetServiceCallback, this); | ||
} | ||
|
||
FixedLagSmoother::~FixedLagSmoother() | ||
|
@@ -131,6 +127,17 @@ FixedLagSmoother::~FixedLagSmoother() | |
} | ||
} | ||
|
||
void FixedLagSmoother::autostart() | ||
{ | ||
if (ignition_sensors_.empty()) | ||
{ | ||
// No ignition sensors were provided. Auto-start. | ||
started_ = true; | ||
start_time_ = ros::Time(0, 0); | ||
ROS_INFO_STREAM("No ignition sensors were specified. Optimization will begin immediately."); | ||
} | ||
} | ||
|
||
void FixedLagSmoother::preprocessMarginalization(const fuse_core::Transaction& new_transaction) | ||
{ | ||
timestamp_tracking_.addNewTransaction(new_transaction); | ||
|
@@ -179,27 +186,31 @@ void FixedLagSmoother::optimizationLoop() | |
// Apply motion models | ||
auto new_transaction = fuse_core::Transaction::make_shared(); | ||
processQueue(*new_transaction); | ||
// Prepare for selecting the marginal variables | ||
preprocessMarginalization(*new_transaction); | ||
// Combine the new transactions with any marginal transaction from the end of the last cycle | ||
new_transaction->merge(marginal_transaction); | ||
// Update the graph | ||
graph_->update(*new_transaction); | ||
// Optimize the entire graph | ||
graph_->optimize(); | ||
// Optimization is complete. Notify all the things about the graph changes. | ||
notify(std::move(new_transaction), graph_->clone()); | ||
// Compute a transaction that marginalizes out those variables. | ||
marginal_transaction = fuse_constraints::marginalizeVariables(computeVariablesToMarginalize(), *graph_); | ||
// Perform any post-marginal cleanup | ||
postprocessMarginalization(marginal_transaction); | ||
// Note: The marginal transaction will not be applied until the next optimization iteration | ||
// Log a warning if the optimization took too long | ||
auto optimization_complete = ros::Time::now(); | ||
if (optimization_complete > optimization_deadline) | ||
// Optimize | ||
{ | ||
ROS_WARN_STREAM("Optimization exceeded the configured duration by " << | ||
(optimization_complete - optimization_deadline) << "s"); | ||
std::lock_guard<std::mutex> lock(optimization_mutex_); | ||
// Prepare for selecting the marginal variables | ||
preprocessMarginalization(*new_transaction); | ||
// Combine the new transactions with any marginal transaction from the end of the last cycle | ||
new_transaction->merge(marginal_transaction); | ||
// Update the graph | ||
graph_->update(*new_transaction); | ||
// Optimize the entire graph | ||
graph_->optimize(); | ||
// Optimization is complete. Notify all the things about the graph changes. | ||
notify(std::move(new_transaction), graph_->clone()); | ||
// Compute a transaction that marginalizes out those variables. | ||
marginal_transaction = fuse_constraints::marginalizeVariables(computeVariablesToMarginalize(), *graph_); | ||
// Perform any post-marginal cleanup | ||
postprocessMarginalization(marginal_transaction); | ||
// Note: The marginal transaction will not be applied until the next optimization iteration | ||
// Log a warning if the optimization took too long | ||
auto optimization_complete = ros::Time::now(); | ||
if (optimization_complete > optimization_deadline) | ||
{ | ||
ROS_WARN_STREAM("Optimization exceeded the configured duration by " << | ||
(optimization_complete - optimization_deadline) << "s"); | ||
} | ||
} | ||
// Clear the request flag now that this optimization cycle is complete | ||
optimization_request_ = false; | ||
|
@@ -268,6 +279,28 @@ void FixedLagSmoother::processQueue(fuse_core::Transaction& transaction) | |
} | ||
} | ||
|
||
bool FixedLagSmoother::resetServiceCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&) | ||
{ | ||
started_ = false; | ||
start_time_ = ros::TIME_MAX; | ||
optimization_request_ = false; | ||
// Clear all pending transactions | ||
{ | ||
std::lock_guard<std::mutex> lock(pending_transactions_mutex_); | ||
pending_transactions_.clear(); | ||
} | ||
// Clear the graph and marginal tracking states | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And there's no weird state that we can get into from a transaction getting somehow inserted in between these two blocks? Just checking. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so. |
||
{ | ||
std::lock_guard<std::mutex> lock(optimization_mutex_); | ||
graph_->clear(); | ||
timestamp_tracking_.clear(); | ||
} | ||
// Test for auto-start | ||
autostart(); | ||
|
||
return true; | ||
} | ||
|
||
void FixedLagSmoother::transactionCallback( | ||
const std::string& sensor_name, | ||
fuse_core::Transaction::SharedPtr transaction) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is necessary because the reset request will come from another thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Previously the
graph_
was only modified by the optimizer thread. Now I am modifying thegraph_
from the ROS callback thread as well.