3#include <SimoxUtility/math/regression/linear.hpp>
14#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h>
25 Base(memoryToIceAdapter,
27 arondto::Proprioception::ToAronType(),
39 defs->optional(properties.predictionTimeWindow,
40 "prediction.TimeWindow",
41 "Duration of time window into the past to use for predictions"
42 " when requested via the PredictingMemoryInterface (in seconds).");
58 this->robotUnit = robotUnitPrx;
60 std::string providerSegmentName =
"Robot";
62 KinematicUnitInterfacePrx kinematicUnit = robotUnit->getKinematicUnit();
65 providerSegmentName = kinematicUnit->getRobotName();
69 ARMARX_WARNING <<
"Robot unit '" << robotUnit->ice_getIdentity().name
70 <<
"' does not have a kinematic unit."
71 <<
"\n Falling back to provider segment name '" << providerSegmentName
74 this->robotUnitProviderID =
segmentPtr->id().withProviderSegmentName(providerSegmentName);
127 _tFindData,
"tFindData " + std::to_string(i),
ARMARX_DEBUG);
137 _tReadSensorValues,
"tReadSensorValues " + std::to_string(i),
ARMARX_DEBUG)
148 tProcessEntities.toMilliSecondsDouble());
152 tReadSensorValues.toMilliSecondsDouble());
161 return robotUnitProviderID;
169 std::vector<double> values;
171 auto addData = [&](adn::DictPtr dict)
173 for (
const auto& [name, value] : dict->
getElements())
176 static_cast<double>(adn::Float::DynamicCastAndCheck(value)->getValue()));
180 if (adn::DictPtr joints = getDictElement(
data,
"joints"))
182 if (adn::DictPtr jointsPosition = getDictElement(*joints,
"position"))
184 addData(jointsPosition);
186 if (adn::DictPtr jointsVelocity = getDictElement(*joints,
"velocity"))
188 addData(jointsVelocity);
190 if (adn::DictPtr jointsTorque = getDictElement(*joints,
"torque"))
192 addData(jointsTorque);
195 Eigen::VectorXd vec =
196 Eigen::Map<Eigen::VectorXd>(values.data(),
static_cast<Eigen::Index
>(values.size()));
203 Eigen::Index row = 0;
204 for (
auto& [joint, value] : dataTemplate.joints.position)
206 value =
static_cast<float>(jointData(row++));
208 for (
auto& [joint, value] : dataTemplate.joints.velocity)
210 value =
static_cast<float>(jointData(row++));
212 for (
auto& [joint, value] : dataTemplate.joints.torque)
214 value =
static_cast<float>(jointData(row++));
228 " is not supported in Proprioception.";
246 timeOrigin - timeWindow,
255 Eigen::VectorXd prediction(latestJoints.size());
258 prediction = latestJoints;
262 using simox::math::LinearRegression;
263 const bool inputOffset =
false;
264 const LinearRegression model = LinearRegression<Eigen::Dynamic>::Fit(
267 prediction = model.predict((predictionTime - timeOrigin).toSecondsDouble());
270 arondto::Proprioception templateData =
271 arondto::Proprioception::FromAron(info.
latestValue);
292 auto checkJVM = [&sensorValues](
const std::string& name)
299 if (adn::DictPtr joints = getDictElement(
data,
"joints"))
301 if (adn::DictPtr values = getDictElement(*joints,
"position"))
303 for (
const auto& [name, value] : values->getElements())
307 adn::Float::DynamicCastAndCheck(value)->getValue();
310 if (adn::DictPtr values = getDictElement(*joints,
"velocity"))
312 for (
const auto& [name, value] : values->getElements())
316 adn::Float::DynamicCastAndCheck(value)->getValue();
319 if (adn::DictPtr values = getDictElement(*joints,
"torque"))
321 for (
const auto& [name, value] :
values->getElements())
325 adn::Float::DynamicCastAndCheck(value)->getValue();
329 if (adn::DictPtr forceTorqueMap = getDictElement(
data,
"forceTorque"))
331 for (
const auto& [name, value] : forceTorqueMap->getElements())
335 const Eigen::Vector3f torque =
337 adn::NDArray::DynamicCastAndCheck(
338 forceTorqueValues->getElement(
"torque")));
340 const Eigen::Vector3f force =
342 adn::NDArray::DynamicCastAndCheck(
343 forceTorqueValues->getElement(
"force")));
346 ForceTorqueValues{.force = force, .torque = torque};
Brief description of class DebugObserverHelper.
void setDebugObserverDatafield(const std::string &channelName, const std::string &datafieldName, const TimedVariantPtr &value) const
std::string providerSegmentName
EntitySnapshotT * findLatestSnapshot()
Return the snapshot with the most recent timestamp.
const EntitySnapshotT * findLatestSnapshotBeforeOrAt(const Time &time) const
Return the latest snapshot before or at time.
Helps connecting a Memory server to the Ice interface.
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
void onConnect(RobotUnitInterfacePrx robotUnitPrx)
const armem::MemoryID & getRobotUnitProviderID() const
SensorValuesMap getSensorValues(const armem::Time ×tamp, DebugObserverHelper *debugObserver=nullptr) const
SensorValuesMap getSensorValuesLocking(const armem::Time ×tamp, DebugObserverHelper *debugObserver=nullptr) const
Segment(server::MemoryToIceAdapter &iceMemory)
armem::PredictionResult predictLinear(const armem::PredictionRequest &request) const
virtual ~Segment() override
virtual void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="") override
auto doLocked(FunctionT &&function) const
Execute function under shared (read) lock.
virtual void init() override
server::wm::CoreSegment * segmentPtr
std::map< std::string, VariantPtr > getElements() const
bool hasElement(const std::string &) const
VariantPtr getElement(const std::string &) const
static Eigen::Vector3f ConvertToVector3f(const data::NDArrayPtr &)
static PointerType DynamicCastAndCheck(const VariantPtr &n)
Represents a point in time.
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
static Duration SecondsDouble(double seconds)
Constructs a duration in seconds.
double toMilliSecondsDouble() const
Returns the amount of milliseconds.
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define TIMING_START(name)
Helper macro to do timing tests.
#define TIMING_END_COMMENT_STREAM(name, comment, os)
Prints duration with comment in front of it, yet only once per second.
#define TIMING_END_STREAM(name, os)
Prints duration.
std::unordered_map< std::string, SensorValues > SensorValuesMap
void emplaceJointData(const Eigen::VectorXd &jointData, arondto::Proprioception &dataTemplate)
Eigen::VectorXd readJointData(const wm::EntityInstanceData &data)
armem::wm::EntitySnapshot EntitySnapshot
armarx::aron::data::Dict EntityInstanceData
SnapshotRangeInfo< DataType, LatestType > getSnapshotsInRange(const SegmentType *segment, const MemoryID &entityID, const DateTime &startTime, const DateTime &endTime, std::function< DataType(const aron::data::DictPtr &)> dictToData, std::function< LatestType(const aron::data::DictPtr &)> dictToLatest)
Get data points for the snapshots of an entity in a given time range.
armarx::core::time::DateTime Time
armarx::core::time::Duration Duration
A convenience header to include all aron files (full include, not forward declared)
std::shared_ptr< Dict > DictPtr
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface > RobotUnitInterfacePrx
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
armem::MemoryID snapshotID
PredictionSettings predictionSettings
aron::data::DictPtr prediction
armem::MemoryID snapshotID
std::string predictionEngineID
Holds info on snapshot data extracted from a time range.
std::vector< double > timestampsSec
std::vector< DataType > values
JointValuesMap jointValueMap
ForceTorqueValuesMap forceTorqueValuesMap
aron::data::DictPtr findInstanceData(int instanceIndex=0) const