Skip to content

Commit b26a573

Browse files
iche033mjcarrollahcorde
authored
Optimize sensor updates (#1480)
Signed-off-by: Ian Chen <[email protected]> Co-authored-by: Michael Carroll <[email protected]> Co-authored-by: Alejandro Hernández Cordero <[email protected]>
1 parent 67c41c9 commit b26a573

File tree

8 files changed

+193
-0
lines changed

8 files changed

+193
-0
lines changed

src/systems/air_pressure/AirPressure.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ void AirPressure::PostUpdate(const UpdateInfo &_info,
140140

141141
if (!_info.paused)
142142
{
143+
// check to see if update is necessary
144+
// we only update if there is at least one sensor that needs data
145+
// and that sensor has subscribers.
146+
// note: ign-sensors does its own throttling. Here the check is mainly
147+
// to avoid doing work in the AirPressurePrivate::UpdatePressures function
148+
bool needsUpdate = false;
149+
for (auto &it : this->dataPtr->entitySensorMap)
150+
{
151+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
152+
it.second->HasConnections())
153+
{
154+
needsUpdate = true;
155+
break;
156+
}
157+
}
158+
if (!needsUpdate)
159+
return;
160+
143161
this->dataPtr->UpdateAirPressures(_ecm);
144162

145163
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/altimeter/Altimeter.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,24 @@ void Altimeter::PostUpdate(const UpdateInfo &_info,
141141
// Only update and publish if not paused.
142142
if (!_info.paused)
143143
{
144+
// check to see if update is necessary
145+
// we only update if there is at least one sensor that needs data
146+
// and that sensor has subscribers.
147+
// note: ign-sensors does its own throttling. Here the check is mainly
148+
// to avoid doing work in the AltimeterPrivate::UpdateAltimeters function
149+
bool needsUpdate = false;
150+
for (auto &it : this->dataPtr->entitySensorMap)
151+
{
152+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
153+
it.second->HasConnections())
154+
{
155+
needsUpdate = true;
156+
break;
157+
}
158+
}
159+
if (!needsUpdate)
160+
return;
161+
144162
this->dataPtr->UpdateAltimeters(_ecm);
145163

146164
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/force_torque/ForceTorque.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,24 @@ void ForceTorque::PostUpdate(const UpdateInfo &_info,
132132
// Only update and publish if not paused.
133133
if (!_info.paused)
134134
{
135+
// check to see if update is necessary
136+
// we only update if there is at least one sensor that needs data
137+
// and that sensor has subscribers.
138+
// note: ign-sensors does its own throttling. Here the check is mainly
139+
// to avoid doing work in the ForceTorquePrivate::Update function
140+
bool needsUpdate = false;
141+
for (auto &it : this->dataPtr->entitySensorMap)
142+
{
143+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
144+
it.second->HasConnections())
145+
{
146+
needsUpdate = true;
147+
break;
148+
}
149+
}
150+
if (!needsUpdate)
151+
return;
152+
135153
this->dataPtr->Update(_ecm);
136154

137155
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/imu/Imu.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,24 @@ void Imu::PostUpdate(const UpdateInfo &_info,
145145
// Only update and publish if not paused.
146146
if (!_info.paused)
147147
{
148+
// check to see if update is necessary
149+
// we only update if there is at least one sensor that needs data
150+
// and that sensor has subscribers.
151+
// note: ign-sensors does its own throttling. Here the check is mainly
152+
// to avoid doing work in the ImuPrivate::Update function
153+
bool needsUpdate = false;
154+
for (auto &it : this->dataPtr->entitySensorMap)
155+
{
156+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
157+
it.second->HasConnections())
158+
{
159+
needsUpdate = true;
160+
break;
161+
}
162+
}
163+
if (!needsUpdate)
164+
return;
165+
148166
this->dataPtr->Update(_ecm);
149167

150168
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/logical_camera/LogicalCamera.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,25 @@ void LogicalCamera::PostUpdate(const UpdateInfo &_info,
143143
// Only update and publish if not paused.
144144
if (!_info.paused)
145145
{
146+
// check to see if update is necessary
147+
// we only update if there is at least one sensor that needs data
148+
// and that sensor has subscribers.
149+
// note: ign-sensors does its own throttling. Here the check is mainly
150+
// to avoid doing work in the LogicalCameraPrivate::UpdateLogicalCameras
151+
// function
152+
bool needsUpdate = false;
153+
for (auto &it : this->dataPtr->entitySensorMap)
154+
{
155+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
156+
it.second->HasConnections())
157+
{
158+
needsUpdate = true;
159+
break;
160+
}
161+
}
162+
if (!needsUpdate)
163+
return;
164+
146165
this->dataPtr->UpdateLogicalCameras(_ecm);
147166

148167
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/magnetometer/Magnetometer.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ void Magnetometer::PostUpdate(const UpdateInfo &_info,
142142
// Only update and publish if not paused.
143143
if (!_info.paused)
144144
{
145+
// check to see if update is necessary
146+
// we only update if there is at least one sensor that needs data
147+
// and that sensor has subscribers.
148+
// note: ign-sensors does its own throttling. Here the check is mainly
149+
// to avoid doing work in the MagnetometerPrivate::Update function
150+
bool needsUpdate = false;
151+
for (auto &it : this->dataPtr->entitySensorMap)
152+
{
153+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
154+
it.second->HasConnections())
155+
{
156+
needsUpdate = true;
157+
break;
158+
}
159+
}
160+
if (!needsUpdate)
161+
return;
162+
145163
this->dataPtr->Update(_ecm);
146164

147165
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/navsat/NavSat.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ void NavSat::PostUpdate(const UpdateInfo &_info,
137137
// Only update and publish if not paused.
138138
if (!_info.paused)
139139
{
140+
// check to see if update is necessary
141+
// we only update if there is at least one sensor that needs data
142+
// and that sensor has subscribers.
143+
// note: ign-sensors does its own throttling. Here the check is mainly
144+
// to avoid doing work in the NavSat::Implementation::Update function
145+
bool needsUpdate = false;
146+
for (auto &it : this->dataPtr->entitySensorMap)
147+
{
148+
if (it.second->NextDataUpdateTime() <= _info.simTime &&
149+
it.second->HasConnections())
150+
{
151+
needsUpdate = true;
152+
break;
153+
}
154+
}
155+
if (!needsUpdate)
156+
return;
157+
140158
this->dataPtr->Update(_ecm);
141159

142160
for (auto &it : this->dataPtr->entitySensorMap)

src/systems/sensors/Sensors.cc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <map>
2121
#include <set>
2222
#include <unordered_map>
23+
#include <unordered_set>
2324
#include <utility>
2425
#include <vector>
2526

@@ -186,6 +187,11 @@ class ignition::gazebo::systems::SensorsPrivate
186187
/// \param[in] _ecm Entity component manager
187188
public: void UpdateBatteryState(const EntityComponentManager &_ecm);
188189

190+
/// \brief Check if sensor has subscribers
191+
/// \param[in] _sensor Sensor to check
192+
/// \return True if the sensor has subscribers, false otherwise
193+
public: bool HasConnections(sensors::RenderingSensor *_sensor) const;
194+
189195
/// \brief Use to optionally set the background color.
190196
public: std::optional<math::Color> backgroundColor;
191197

@@ -316,12 +322,34 @@ void SensorsPrivate::RunOnce()
316322
this->scene->PreRender();
317323
}
318324

325+
// disable sensors that have no subscribers to prevent doing unnecessary
326+
// work
327+
std::unordered_set<sensors::RenderingSensor *> tmpDisabledSensors;
328+
this->sensorMaskMutex.lock();
329+
for (auto id : this->sensorIds)
330+
{
331+
sensors::Sensor *s = this->sensorManager.Sensor(id);
332+
auto rs = dynamic_cast<sensors::RenderingSensor *>(s);
333+
if (rs->IsActive() && !this->HasConnections(rs))
334+
{
335+
rs->SetActive(false);
336+
tmpDisabledSensors.insert(rs);
337+
}
338+
}
339+
this->sensorMaskMutex.unlock();
340+
319341
{
320342
// publish data
321343
IGN_PROFILE("RunOnce");
322344
this->sensorManager.RunOnce(this->updateTime);
323345
}
324346

347+
// re-enble sensors
348+
for (auto &rs : tmpDisabledSensors)
349+
{
350+
rs->SetActive(true);
351+
}
352+
325353
{
326354
IGN_PROFILE("PostRender");
327355
// Update the scene graph manually to improve performance
@@ -805,6 +833,44 @@ std::string Sensors::CreateSensor(const Entity &_entity,
805833
return sensor->Name();
806834
}
807835

836+
//////////////////////////////////////////////////
837+
bool SensorsPrivate::HasConnections(sensors::RenderingSensor *_sensor) const
838+
{
839+
if (!_sensor)
840+
return true;
841+
842+
// \todo(iche033) Remove this function once a virtual
843+
// sensors::RenderingSensor::HasConnections function is available
844+
{
845+
auto s = dynamic_cast<sensors::DepthCameraSensor *>(_sensor);
846+
if (s)
847+
return s->HasConnections();
848+
}
849+
{
850+
auto s = dynamic_cast<sensors::GpuLidarSensor *>(_sensor);
851+
if (s)
852+
return s->HasConnections();
853+
}
854+
{
855+
auto s = dynamic_cast<sensors::SegmentationCameraSensor *>(_sensor);
856+
if (s)
857+
return s->HasConnections();
858+
}
859+
{
860+
auto s = dynamic_cast<sensors::ThermalCameraSensor *>(_sensor);
861+
if (s)
862+
return s->HasConnections();
863+
}
864+
{
865+
auto s = dynamic_cast<sensors::CameraSensor *>(_sensor);
866+
if (s)
867+
return s->HasConnections();
868+
}
869+
ignwarn << "Unable to check connection count for sensor: " << _sensor->Name()
870+
<< ". Unknown sensor type." << std::endl;
871+
return true;
872+
}
873+
808874
IGNITION_ADD_PLUGIN(Sensors, System,
809875
Sensors::ISystemConfigure,
810876
Sensors::ISystemUpdate,

0 commit comments

Comments
 (0)