2020#include < vector>
2121#include < unordered_map>
2222#include < memory>
23+ #include < mutex>
24+ #include < shared_mutex>
2325#include < utility>
2426
2527#include " rcpputils/asserts.hpp"
@@ -678,6 +680,7 @@ class SystemStatusPlugin : public plugin::Plugin
678680
679681 using M_VehicleInfo = std::unordered_map<uint16_t , mavros_msgs::msg::VehicleInfo>;
680682 M_VehicleInfo vehicles;
683+ mutable std::shared_mutex vehicles_mutex;
681684
682685 /* -*- mid-level helpers -*- */
683686
@@ -687,8 +690,8 @@ class SystemStatusPlugin : public plugin::Plugin
687690 return sysid << 8 | compid;
688691 }
689692
690- // Find or create vehicle info
691- inline M_VehicleInfo::iterator find_or_create_vehicle_info (uint8_t sysid, uint8_t compid)
693+ // Caller must hold vehicles_mutex exclusively.
694+ inline M_VehicleInfo::iterator find_or_create_vehicle_info_unlocked (uint8_t sysid, uint8_t compid)
692695 {
693696 auto key = get_vehicle_key (sysid, compid);
694697 M_VehicleInfo::iterator ret = vehicles.find (key);
@@ -899,26 +902,28 @@ class SystemStatusPlugin : public plugin::Plugin
899902
900903 // XXX(vooon): i assume that UAS not interested in HBs from non-target system.
901904
902- // Store generic info of all heartbeats seen
903- auto it = find_or_create_vehicle_info (msg->sysid , msg->compid );
904-
905905 auto vehicle_mode = uas->str_mode_v10 (hb.base_mode , hb.custom_mode );
906906 auto stamp = node->now ();
907907
908- // Update vehicle data
909- it->second .header .stamp = stamp;
910- it->second .available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_HEARTBEAT;
911- it->second .autopilot = hb.autopilot ;
912- it->second .type = hb.type ;
913- it->second .system_status = hb.system_status ;
914- it->second .base_mode = hb.base_mode ;
915- it->second .custom_mode = hb.custom_mode ;
916- it->second .mode = vehicle_mode;
917-
918- if (!(hb.base_mode & enum_value (MAV_MODE_FLAG::CUSTOM_MODE_ENABLED))) {
919- it->second .mode_id = hb.base_mode ;
920- } else {
921- it->second .mode_id = hb.custom_mode ;
908+ {
909+ std::unique_lock<std::shared_mutex> lock (vehicles_mutex);
910+ auto it = find_or_create_vehicle_info_unlocked (msg->sysid , msg->compid );
911+
912+ // Update vehicle data
913+ it->second .header .stamp = stamp;
914+ it->second .available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_HEARTBEAT;
915+ it->second .autopilot = hb.autopilot ;
916+ it->second .type = hb.type ;
917+ it->second .system_status = hb.system_status ;
918+ it->second .base_mode = hb.base_mode ;
919+ it->second .custom_mode = hb.custom_mode ;
920+ it->second .mode = vehicle_mode;
921+
922+ if (!(hb.base_mode & enum_value (MAV_MODE_FLAG::CUSTOM_MODE_ENABLED))) {
923+ it->second .mode_id = hb.base_mode ;
924+ } else {
925+ it->second .mode_id = hb.custom_mode ;
926+ }
922927 }
923928
924929 // Continue from here only if vehicle is my target
@@ -1094,21 +1099,26 @@ class SystemStatusPlugin : public plugin::Plugin
10941099 process_autopilot_version_normal (apv, msg->sysid , msg->compid );
10951100 }
10961101
1097- // Store generic info of all autopilot seen
1098- auto it = find_or_create_vehicle_info (msg->sysid , msg->compid );
1099-
1100- // Update vehicle data
1101- it->second .header .stamp = node->now ();
1102- it->second .available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_AUTOPILOT_VERSION;
1103- it->second .capabilities = apv.capabilities ;
1104- it->second .flight_sw_version = apv.flight_sw_version ;
1105- it->second .middleware_sw_version = apv.middleware_sw_version ;
1106- it->second .os_sw_version = apv.os_sw_version ;
1107- it->second .board_version = apv.board_version ;
1108- it->second .flight_custom_version = custom_version_to_hex_string (apv.flight_custom_version );
1109- it->second .vendor_id = apv.vendor_id ;
1110- it->second .product_id = apv.product_id ;
1111- it->second .uid = apv.uid ;
1102+ auto stamp = node->now ();
1103+ auto flight_custom_version = custom_version_to_hex_string (apv.flight_custom_version );
1104+
1105+ {
1106+ std::unique_lock<std::shared_mutex> lock (vehicles_mutex);
1107+ auto it = find_or_create_vehicle_info_unlocked (msg->sysid , msg->compid );
1108+
1109+ // Update vehicle data
1110+ it->second .header .stamp = stamp;
1111+ it->second .available_info |= mavros_msgs::msg::VehicleInfo::HAVE_INFO_AUTOPILOT_VERSION;
1112+ it->second .capabilities = apv.capabilities ;
1113+ it->second .flight_sw_version = apv.flight_sw_version ;
1114+ it->second .middleware_sw_version = apv.middleware_sw_version ;
1115+ it->second .os_sw_version = apv.os_sw_version ;
1116+ it->second .board_version = apv.board_version ;
1117+ it->second .flight_custom_version = flight_custom_version;
1118+ it->second .vendor_id = apv.vendor_id ;
1119+ it->second .product_id = apv.product_id ;
1120+ it->second .uid = apv.uid ;
1121+ }
11121122 }
11131123
11141124 void handle_battery_status (
@@ -1378,6 +1388,7 @@ class SystemStatusPlugin : public plugin::Plugin
13781388 publish_disconnection ();
13791389
13801390 // Clear known vehicles
1391+ std::unique_lock<std::shared_mutex> lock (vehicles_mutex);
13811392 vehicles.clear ();
13821393 }
13831394 }
@@ -1506,7 +1517,10 @@ class SystemStatusPlugin : public plugin::Plugin
15061517 mavros_msgs::srv::VehicleInfoGet::Response::SharedPtr res)
15071518 {
15081519 if (req->get_all ) {
1520+ std::shared_lock<std::shared_mutex> lock (vehicles_mutex);
1521+
15091522 // Send all vehicles
1523+ res->vehicles .reserve (vehicles.size ());
15101524 for (const auto & got : vehicles) {
15111525 res->vehicles .emplace_back (got.second );
15121526 }
@@ -1525,6 +1539,7 @@ class SystemStatusPlugin : public plugin::Plugin
15251539 }
15261540
15271541 uint16_t key = get_vehicle_key (req_sysid, req_compid);
1542+ std::shared_lock<std::shared_mutex> lock (vehicles_mutex);
15281543 auto it = vehicles.find (key);
15291544 if (it == vehicles.end ()) {
15301545 // Vehicle not found
0 commit comments