diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp index dc4b109411a3d8e21c60208a8e4f44ea86fe644d..b6aa80e65dd186fe7ae931e7846ce038b2a47523 100644 --- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp +++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp @@ -29,21 +29,6 @@ namespace armarx { namespace RobotUnitModule { - namespace detail - { - std::function<std::string(const std::string&)> makeDebugObserverNameFixer(const std::string& prefix) - { - return - [prefix](const std::string & name) - { - std::string s = prefix + name; - std::replace(s.begin(), s.end(), '.', '_'); - std::replace(s.begin(), s.end(), ':', '_'); - return s; - }; - } - } - /** * \brief This class allows minimal access to private members of \ref NJointController in a sane fashion for \ref Publisher. * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !! @@ -135,6 +120,185 @@ namespace armarx return ControllerManagementAttorneyForPublisher::GetNJointControllers(this); } + TimedVariantPtr Publisher::publishNJointClassNames(IceUtil::Time timestamp, RobotUnitListenerPrx &listenerPrx) + { + const auto beg = TimeUtil::GetTime(true); + + const auto classNames = NJointControllerRegistry::getKeys(); + if (lastReportedClasses.size() != classNames.size()) + { + for (const auto& name : classNames) + { + if (!lastReportedClasses.count(name)) + { + listenerPrx->nJointControllerClassAdded(name); + lastReportedClasses.emplace(name); + } + } + } + + const auto end = TimeUtil::GetTime(true); + return new TimedVariant{TimestampVariant{end-beg}, timestamp}; + } + + TimedVariantPtr Publisher::publishNJointControllerUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx& listenerPrx, + StringVariantBaseMap& timingMap, + const SensorAndControl& controlThreadOutputBuffer, + DebugObserverInterfacePrx& debugObserverBatchPrx + ) + { + const auto beg = TimeUtil::GetTime(true); + + for (const auto& pair : getNJointControllers()) + { + const auto begInner = TimeUtil::GetTime(true); + const NJointControllerPtr& nJointCtrl = pair.second; + + //run some hook for active (used for visu) + NJointControllerAttorneyForPublisher::Publish(nJointCtrl, controlThreadOutputBuffer, debugDrawerPrx, debugObserverBatchPrx); + if ( + NJointControllerAttorneyForPublisher::GetStatusReportedActive(nJointCtrl) != nJointCtrl->isControllerActive() || + NJointControllerAttorneyForPublisher::GetStatusReportedRequested(nJointCtrl) != nJointCtrl->isControllerRequested() + ) + { + NJointControllerAttorneyForPublisher::UpdateStatusReported(nJointCtrl); + listenerPrx->nJointControllerStatusChanged(nJointCtrl->getControllerStatus()); + } + + const auto endInner = TimeUtil::GetTime(true); + timingMap["NJointControllerUpdates_" + nJointCtrl->getInstanceName()] = new TimedVariant{TimestampVariant{endInner-begInner}, timestamp}; + } + + const auto end = TimeUtil::GetTime(true); + return new TimedVariant{TimestampVariant{end-beg}, timestamp}; + } + + TimedVariantPtr Publisher::publishUnitUpdates( + IceUtil::Time timestamp, + StringVariantBaseMap &timingMap, + const SensorAndControl& controlThreadOutputBuffer, + const JointAndNJointControllers& activatedControllers) + { + const auto beg = TimeUtil::GetTime(true); + + ARMARX_DEBUG << deactivateSpam(spamdelay) << "updating units with new sensor values"; + publishNewSensorDataTime = TimeUtil::GetTime(true); + for (const RobotUnitSubUnitPtr& rsu : UnitsAttorneyForPublisher::GetSubUnits(this)) + { + if (rsu && rsu->getObjectScheduler() && rsu->getProxy()) + { + const auto begInner = TimeUtil::GetTime(true); + rsu->update(controlThreadOutputBuffer, activatedControllers); + const auto endInner = TimeUtil::GetTime(true); + timingMap["UnitUpdate_" + rsu->getName()] = new TimedVariant{TimestampVariant{endInner-begInner}, timestamp}; + } + } + + const auto end = TimeUtil::GetTime(true); + return new TimedVariant{TimestampVariant{end-beg}, timestamp}; + } + + TimedVariantPtr Publisher::publishControlUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx& listenerPrx, + const SensorAndControl& controlThreadOutputBuffer, + bool haveSensorAndControlValsChanged, + bool publishToObserver, + const JointAndNJointControllers& activatedControllers, + const std::vector<JointController*>& requestedJointControllers) + { + const auto beg = TimeUtil::GetTime(true); + + + StringVariantBaseMap ctrlDevMap; + for (std::size_t ctrlidx = 0 ; ctrlidx < _module<Devices>().getNumberOfControlDevices(); ++ctrlidx) + { + const ControlDevice& ctrlDev = *(_module<Devices>().getControlDevices().at(ctrlidx)); + + StringToStringVariantBaseMapMap variants; + ControlDeviceStatus status; + const auto activeJointCtrl = activatedControllers.jointControllers.at(ctrlidx); + status.activeControlMode = activeJointCtrl ? activeJointCtrl->getControlMode() : std::string {"!!JointController is nullptr!!"}; + status.deviceName = ctrlDev.getDeviceName(); + + for (const auto& ctrlVal : controlThreadOutputBuffer.control.at(ctrlidx)) + { + const auto& controlMode = ctrlVal->getControlMode(); + variants[controlMode] = ctrlVal->toVariants(timestamp); + if ( + haveSensorAndControlValsChanged && + !variants[controlMode].empty() && + observerPublishControlTargets && + publishToObserver + ) + { + for(const auto& pair : variants[controlMode]) + { + ctrlDevMap[status.deviceName + "_" + pair.first] = pair.second; + } + } + } + + ARMARX_CHECK_EXPRESSION(requestedJointControllers.at(ctrlidx)); + status.requestedControlMode = requestedJointControllers.at(ctrlidx)->getControlMode(); + status.controlTargetValues = std::move(variants); + status.timestampUSec = MicroNow().count(); + listenerPrx->controlDeviceStatusChanged(status); + } + if (robotUnitObserver->getState() >= eManagedIceObjectStarted) + { + robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->controlDevicesChannel, ctrlDevMap); + robotUnitObserver->updateChannel(robotUnitObserver->controlDevicesChannel); + } + + const auto end = TimeUtil::GetTime(true); + return new TimedVariant{TimestampVariant{end-beg}, timestamp}; + } + + TimedVariantPtr Publisher::publishSensorUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx &listenerPrx, + bool publishToObserver, + const SensorAndControl &controlThreadOutputBuffer) + { + const auto beg = TimeUtil::GetTime(true); + + StringVariantBaseMap sensorDevMap; + for (std::size_t sensidx = 0 ; sensidx < _module<Devices>().getNumberOfSensorDevices(); ++sensidx) + { + const SensorValueBase& sensVal = *(controlThreadOutputBuffer.sensors.at(sensidx)); + auto variants = sensVal.toVariants(timestamp); + + if (!variants.empty()) + { + SensorDeviceStatus status; + status.deviceName = DevicesAttorneyForPublisher::GetSensorDeviceName(this, sensidx); + + if (observerPublishSensorValues && publishToObserver) + { + for(const auto& pair : variants) + { + sensorDevMap[status.deviceName + "_" + pair.first] = pair.second; + } + } + + status.sensorValue = std::move(variants); + status.timestampUSec = MicroNow().count(); + listenerPrx->sensorDeviceStatusChanged(status); + } + } + if (robotUnitObserver->getState() >= eManagedIceObjectStarted) + { + robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->sensorDevicesChannel, sensorDevMap); + robotUnitObserver->updateChannel(robotUnitObserver->sensorDevicesChannel); + } + + const auto end = TimeUtil::GetTime(true); + return new TimedVariant{TimestampVariant{end-beg}, timestamp}; + } + std::string Publisher::getRobotUnitListenerTopicName(const Ice::Current &) const { return robotUnitListenerTopicName; @@ -241,7 +405,7 @@ namespace armarx void Publisher::_postFinishControlThreadInitialization() { //start publisher - publishNewSensorDataTime = TimeUtil::GetTime(); + publishNewSensorDataTime = TimeUtil::GetTime(true); publisherTask = new PublisherTaskT([&] {publish({});}, publishPeriodMs, false, getName() + "_PublisherTask"); ARMARX_INFO << "starting publisher with timestep " << publishPeriodMs; publisherTask->setDelayWarningTolerance(10 * publishPeriodMs); @@ -251,7 +415,6 @@ namespace armarx void Publisher::publish(StringVariantBaseMap additionalMap, StringVariantBaseMap timingMap) { auto begPublish = Now(); - static const int spamdelay = 30; if (getRobotUnitState() != RobotUnitState::Running) { @@ -283,19 +446,13 @@ namespace armarx const bool haveActivatedControllersChanged = _module<ControlThreadDataBuffer>().activatedControllersChanged(); const bool haveSensorAndControlValsChanged = _module<ControlThreadDataBuffer>().sensorAndControlBufferChanged(); //setup datastructures - const auto& controlThreadOutputBuffer = _module<ControlThreadDataBuffer>().getSensorAndControlBuffer(); - const auto& activatedControllers = _module<ControlThreadDataBuffer>().getActivatedControllers(); + const auto& controlThreadOutputBuffer = _module<ControlThreadDataBuffer>().getSensorAndControlBuffer(); ///TODO copy buffer + const auto activatedControllers = _module<ControlThreadDataBuffer>().getActivatedControllers(); const auto requestedJointControllers = _module<ControlThreadDataBuffer>().copyRequestedJointControllers(); const auto timestamp = controlThreadOutputBuffer.sensorValuesTimestamp; - const auto numSensorDevices = _module<Devices>().getNumberOfSensorDevices(); - const auto numControlDevices = _module<Devices>().getNumberOfControlDevices(); - const bool publishToObserver = !(publishIterationCount % debugObserverSkipIterations); - const bool debugObserverPublishControlTargetsThisIteration = observerPublishControlTargets; - const bool debugObserverPublishSensorValuesThisIteration = observerPublishSensorValues; - StringVariantBaseMap ctrlDevMap, sensorDevMap; //publish publishing meta state additionalMap["haveActivatedControllersChanged"] = new TimedVariant {haveActivatedControllersChanged, timestamp}; additionalMap["haveSensorAndControlValsChanged"] = new TimedVariant {haveSensorAndControlValsChanged, timestamp}; @@ -304,56 +461,9 @@ namespace armarx if (haveSensorAndControlValsChanged) { //update units - timingMap["publishTimings_UnitUpdate"] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - ARMARX_DEBUG << deactivateSpam(spamdelay) << "updating units with new sensor values"; - publishNewSensorDataTime = TimeUtil::GetTime(); - for (const RobotUnitSubUnitPtr& rsu : UnitsAttorneyForPublisher::GetSubUnits(this)) - { - if (rsu && rsu->getObjectScheduler() && rsu->getProxy()) - { - timingMap["publishTimings_UnitUpdate_" + rsu->getName()] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant){rsu->update(controlThreadOutputBuffer, activatedControllers);}, - timestamp - }; - } - } - }, - timestamp - }; + timingMap["UnitUpdate"] = publishUnitUpdates(timestamp, timingMap, controlThreadOutputBuffer, activatedControllers); //publish sensor updates - - timingMap["publishTimings_SensorUpdates"] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - for (std::size_t sensidx = 0 ; sensidx < numSensorDevices; ++sensidx) - { - const SensorValueBase& sensVal = *(controlThreadOutputBuffer.sensors.at(sensidx)); - auto variants = sensVal.toVariants(timestamp); - - if (!variants.empty()) - { - SensorDeviceStatus status; - status.deviceName = DevicesAttorneyForPublisher::GetSensorDeviceName(this, sensidx); - status.sensorValue = std::move(variants); - status.timestampUSec = MicroNow().count(); - if (debugObserverPublishSensorValuesThisIteration && publishToObserver) - { - transformMapKeys( - variants, sensorDevMap, - detail::makeDebugObserverNameFixer(status.deviceName + "_" + sensVal.getSensorValueType(true) + "_") - ); - } - listenerBatchPrx->sensorDeviceStatusChanged(status); - } - } - }, - timestamp - }; + timingMap["SensorUpdates"] = publishSensorUpdates(timestamp, listenerBatchPrx, publishToObserver, controlThreadOutputBuffer); } else { @@ -366,126 +476,32 @@ namespace armarx } if (haveSensorAndControlValsChanged || haveActivatedControllersChanged) { - timingMap["publishTimings_ControlUpdates"] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - for (std::size_t ctrlidx = 0 ; ctrlidx < numControlDevices; ++ctrlidx) - { - const ControlDevice& ctrlDev = *(_module<Devices>().getControlDevices().at(ctrlidx)); - - StringToStringVariantBaseMapMap variants; - for (const auto& ctrlVal : controlThreadOutputBuffer.control.at(ctrlidx)) - { - const auto& controlMode = ctrlVal->getControlMode(); - variants[controlMode] = ctrlVal->toVariants(timestamp); - if ( - haveSensorAndControlValsChanged && - !variants[controlMode].empty() && - debugObserverPublishControlTargetsThisIteration && - publishToObserver - ) - { - transformMapKeys( - variants[controlMode], ctrlDevMap, - detail::makeDebugObserverNameFixer(ctrlDev.getDeviceName() + "_" + controlMode + "_") - ); - } - } - ControlDeviceStatus status; - const auto activeJointCtrl = activatedControllers.jointControllers.at(ctrlidx); - status.activeControlMode = activeJointCtrl ? activeJointCtrl->getControlMode() : std::string {"!!JointController is nullptr!!"}; - status.deviceName = ctrlDev.getDeviceName(); - ARMARX_CHECK_EXPRESSION(requestedJointControllers.at(ctrlidx)); - status.requestedControlMode = requestedJointControllers.at(ctrlidx)->getControlMode(); - status.controlTargetValues = std::move(variants); - status.timestampUSec = MicroNow().count(); - listenerBatchPrx->controlDeviceStatusChanged(status); - } - }, - timestamp - }; + timingMap["ControlUpdates"] = publishControlUpdates( + timestamp, listenerBatchPrx, controlThreadOutputBuffer, + haveSensorAndControlValsChanged, publishToObserver, + activatedControllers, requestedJointControllers); } //call publish hook + publish NJointController changes - timingMap["publishTimings_NJointControllerUpdates"] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - for (const auto& pair : getNJointControllers()) - { - const NJointControllerPtr& nJointCtrl = pair.second; - timingMap["publishTimings_NJointControllerUpdates_" + nJointCtrl->getInstanceName()] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - //run some hook for active (used for visu) - NJointControllerAttorneyForPublisher::Publish(nJointCtrl, controlThreadOutputBuffer, debugDrawerPrx, debugObserverBatchPrx); - if ( - NJointControllerAttorneyForPublisher::GetStatusReportedActive(nJointCtrl) != nJointCtrl->isControllerActive() || - NJointControllerAttorneyForPublisher::GetStatusReportedRequested(nJointCtrl) != nJointCtrl->isControllerRequested() - ) - { - NJointControllerAttorneyForPublisher::UpdateStatusReported(nJointCtrl); - listenerBatchPrx->nJointControllerStatusChanged(nJointCtrl->getControllerStatus()); - } - }, - timestamp - }; - } - }, - timestamp - }; + timingMap["NJointControllerUpdates"] = publishNJointControllerUpdates(timestamp, listenerBatchPrx, timingMap, controlThreadOutputBuffer, debugObserverBatchPrx); //report new class names - timingMap["publishTimings_ClassNameUpdates"] = new TimedVariant - { - ARMARX_STOPWATCH(TimestampVariant) - { - const auto classNames = NJointControllerRegistry::getKeys(); - if (lastReportedClasses.size() != classNames.size()) - { - for (const auto& name : classNames) - { - if (!lastReportedClasses.count(name)) - { - listenerBatchPrx->nJointControllerClassAdded(name); - lastReportedClasses.emplace(name); - } - } - } - }, - timestamp - }; - timingMap["publishTimings_RobotUnitListenerFlush"] = new TimedVariant + timingMap["ClassNameUpdates"] = publishNJointClassNames(timestamp, listenerBatchPrx); + timingMap["RobotUnitListenerFlush"] = new TimedVariant { ARMARX_STOPWATCH(TimestampVariant){listenerBatchPrx->ice_flushBatchRequests();}, timestamp }; if (publishToObserver) { - timingMap["publishTimings_LastRobotUnitObserverFlush"] = - new TimedVariant {TimestampVariant{lastRobotUnitObserverFlush.count()}, timestamp}; - timingMap["publishTimings_LastPublishLoop"] = new TimedVariant {TimestampVariant{lastPublishLoop.count()}, timestamp}; - lastRobotUnitObserverFlush = ARMARX_STOPWATCH() + timingMap["LastPublishLoop"] = new TimedVariant {TimestampVariant{lastPublishLoop.count()}, timestamp}; + if (robotUnitObserver->getState() >= eManagedIceObjectStarted) { - if (robotUnitObserver->getState() >= eManagedIceObjectStarted) - { - robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->additionalChannel, additionalMap); - robotUnitObserver->updateChannel(robotUnitObserver->additionalChannel); - robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->timingChannel, timingMap); - robotUnitObserver->updateChannel(robotUnitObserver->timingChannel); - robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->controlDevicesChannel, ctrlDevMap); - robotUnitObserver->updateChannel(robotUnitObserver->controlDevicesChannel); - robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->sensorDevicesChannel, sensorDevMap); - robotUnitObserver->updateChannel(robotUnitObserver->sensorDevicesChannel); - - } - debugObserverBatchPrx->ice_flushBatchRequests(); - }; - } - else - { - lastRobotUnitObserverFlush = std::chrono::microseconds {0}; + robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->additionalChannel, additionalMap); + robotUnitObserver->updateChannel(robotUnitObserver->additionalChannel); + robotUnitObserver->offerOrUpdateDataFieldsFlatCopy(robotUnitObserver->timingChannel, timingMap); + robotUnitObserver->updateChannel(robotUnitObserver->timingChannel); + } + debugObserverBatchPrx->ice_flushBatchRequests(); } //warn if there are unset jointCtrl controllers diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.h b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.h index 21cb1a18a5a794de8139bda0ffb72d4d50de62e6..c59dcd9a5039bb5e8742e96d8146c0c98e5b5757 100644 --- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.h +++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.h @@ -34,6 +34,13 @@ namespace armarx { TYPEDEF_PTRS_HANDLE(RobotUnitObserver); + + namespace detail + { + struct ControlThreadOutputBufferEntry; + } + using SensorAndControl = detail::ControlThreadOutputBufferEntry; + namespace RobotUnitModule { class PublisherPropertyDefinitions: public ModuleBasePropertyDefinitions @@ -163,10 +170,84 @@ namespace armarx ARMARX_CHECK_EXPRESSION(robotUnitObserver); return robotUnitObserver; } + /** + * @brief Publishes updtes about new classes od \ref NJointController "NJointControllers" + * @param timestamp The timestamp of the published \ref ControlThread iteration + * @param listenerPrx The proxy to the \ref RobotUnitListener topic + * @return The time required by this function as a \ref Variant + */ + TimedVariantPtr publishNJointClassNames( + IceUtil::Time timestamp, + RobotUnitListenerPrx& listenerPrx); + /** + * @brief Publishes updates of \ref NJointController "NJointControllers" ([de]activate + publish hooks) + * @param timestamp The timestamp of the published \ref ControlThread iteration + * @param listenerPrx The proxy to the \ref RobotUnitListener topic + * @param timingMap Timings of this publish iteration (out param) + * @param controlThreadOutputBuffer The output of the published \ref ControlThread iteration + * @param debugObserverBatchPrx Proxy to the \ref DebugObserver's topic + * @return The time required by this function as a \ref Variant + * @see NJointController::onPublish + */ + TimedVariantPtr publishNJointControllerUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx& listenerPrx, + StringVariantBaseMap& timingMap, + const SensorAndControl& controlThreadOutputBuffer, + DebugObserverInterfacePrx& debugObserverBatchPrx); + /** + * @brief Updates all sub units and publishes the timings of these updates + * @param timestamp The timestamp of the published \ref ControlThread iteration + * @param timingMap Timings of this publish iteration (out param) + * @param controlThreadOutputBuffer The output of the published \ref ControlThread iteration + * @param activatedControllers The \ref JointController "JointControllers" and \ref NJointController "NJointControllers" + * active in the published \ref ControlThread iteration + * @return The time required by this function as a \ref Variant + */ + TimedVariantPtr publishUnitUpdates( + IceUtil::Time timestamp, + StringVariantBaseMap &timingMap, + const SensorAndControl& controlThreadOutputBuffer, + const JointAndNJointControllers& activatedControllers); + /** + * @brief Publishes data about updates of \ref JointController "JointControllers" and their \ref ControlTargetBase "ControlTargets" + * @param timestamp The timestamp of the published \ref ControlThread iteration + * @param listenerPrx The proxy to the \ref RobotUnitListener topic + * @param controlThreadOutputBuffer The output of the published \ref ControlThread iteration + * @param haveSensorAndControlValsChanged Whether \ref ControlTargetBase "ControlTargets" were updated by the \ref ControlThread + * @param publishToObserver Whether data should be published to observers + * @param activatedControllers The \ref JointController "JointControllers" and \ref NJointController "NJointControllers" + * active in the published \ref ControlThread iteration + * @param requestedJointControllers + * @return The time required by this function as a \ref Variant + */ + TimedVariantPtr publishControlUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx& listenerPrx, + const SensorAndControl& controlThreadOutputBuffer, + bool haveSensorAndControlValsChanged, + bool publishToObserver, + const JointAndNJointControllers& activatedControllers, + const std::vector<JointController*>& requestedJointControllers); + /** + * @brief Publishes Updates about \ref SensorValueBase "SensorValues" (To \ref RobotUnitListener and \ref RobotUnitObserver) + * @param timestamp The timestamp of the published \ref ControlThread iteration + * @param listenerPrx The proxy to the \ref RobotUnitListener topic + * @param publishToObserver Whether data should be published to observers + * @param controlThreadOutputBuffer The output of the published \ref ControlThread iteration + * @return The time required by this function as a \ref Variant + */ + TimedVariantPtr publishSensorUpdates( + IceUtil::Time timestamp, + RobotUnitListenerPrx &listenerPrx, + bool publishToObserver, + const SensorAndControl& controlThreadOutputBuffer); // //////////////////////////////////////////////////////////////////////////////////////// // // ///////////////////////////////////////// Data ///////////////////////////////////////// // // //////////////////////////////////////////////////////////////////////////////////////// // private: + static constexpr int spamdelay = 30; + using PublisherTaskT = SimplePeriodicTask<std::function<void(void)>>; /// @brief The name of the used RobotUnitListenerTopic @@ -198,8 +279,6 @@ namespace armarx /// @brief How many iterations of \ref publish shold not publish data to the debug observer. std::atomic<std::uint64_t> debugObserverSkipIterations; - /// @brief The time required by the last iteration of \ref publish to flush the debug observer - std::chrono::microseconds lastRobotUnitObserverFlush; /// @brief The time required by the last iteration of \ref publish std::chrono::microseconds lastPublishLoop;