30 #include <SimoxUtility/math/convert.h>
31 #include <SimoxUtility/xml/rapidxml/RapidXMLWrapper.h>
32 #include <VirtualRobot/MathTools.h>
33 #include <VirtualRobot/Robot.h>
38 #include <MMM/Model/ModelProcessorWinter.h>
39 #include <MMM/Motion/Legacy/LegacyMotion.h>
40 #include <MMM/Motion/Legacy/LegacyMotionReaderXML.h>
41 #include <MMM/Motion/MotionReaderXML.h>
42 #include <MMM/Motion/Plugin/KinematicPlugin/KinematicSensor.h>
43 #include <MMM/Motion/Plugin/ModelPosePlugin/ModelPoseSensor.h>
44 #include <MMM/Motion/XMLTools.h>
51 double butterworthFilterCutOffFreq,
52 const std::string relativeModelRoot)
56 simox::xml::RapidXMLWrapperRootNodePtr root =
57 simox::xml::RapidXMLWrapperRootNode::FromFile(motionFilePath);
58 if (root && root->name() == xml::tag::MMM_ROOT)
60 if (!root->has_attribute(xml::attribute::VERSION))
62 if (!wrapper->loadLegacyMotion(motionFilePath))
69 std::string version = root->attribute_value(xml::attribute::VERSION);
72 if (!wrapper->loadMotion(motionFilePath, relativeModelRoot))
77 else if (version ==
"1.0 ")
79 if (!wrapper->loadLegacyMotion(motionFilePath, relativeModelRoot))
86 ARMARX_ERROR <<
"Could not load mmm motion with version '" << version <<
"'";
99 MotionFileWrapper::MotionFileWrapper(
int butterworthFilterCutOffFreq) :
100 butterworthFilterCutOffFreq(butterworthFilterCutOffFreq)
105 MotionFileWrapper::loadMotion(
const std::string& motionFilePath,
106 const std::string relativeModelRoot)
109 MotionRecordingPtr motions;
112 MotionReaderXMLPtr motionReader(
new MotionReaderXML());
113 motions = motionReader->loadMotionRecording(motionFilePath);
115 catch (Exception::MMMException& e)
117 ARMARX_ERROR <<
"Could not load mmm motion! " << e.what();
122 for (
auto motion : *motions)
124 ModelPtr model = motion->getModel();
127 if (!model->getFilename().empty() &&
128 std::filesystem::path(model->getFilename()).stem() == relativeModelRoot)
130 auto modelPoseSensor = motion->getSensorByType<ModelPoseSensor>();
131 if (modelPoseSensor && modelPoseSensor->getTimesteps().size() > 0)
133 auto modelPoseSensorMeasurement = modelPoseSensor->getDerivedMeasurement(
134 modelPoseSensor->getTimesteps().at(0));
136 Eigen::Vector3f orientation = simox::math::mat4f_to_rpy(rootPose);
137 modelRootTransformation.block<3,3>(0, 0) =
138 simox::math::rpy_to_mat3f(0, 0, -orientation(2));
139 modelRootTransformation.block<3,1>(0, 3) =
140 Eigen::Vector3f(-rootPose(0, 3), -rootPose(1, 3), 0);
146 for (
auto motion : *motions)
150 ModelPtr model = motion->getModel();
153 m->modelPath = model->getFilename();
156 ModelPoseSensorPtr modelPoseSensor = motion->getSensorByType<ModelPoseSensor>();
157 if (!modelPoseSensor)
159 ARMARX_ERROR <<
"Ignoring motion with name '" << motion->getName()
160 <<
"', because it has no model pose sensor!";
164 std::vector<float> t = modelPoseSensor->getTimesteps();
165 m->timestamp = ::Ice::DoubleSeq(t.begin(), t.end());
166 m->numberOfFrames = m->timestamp.size();
167 for (
float timestep : m->timestamp)
169 ModelPoseSensorMeasurementPtr modelPoseSensorMeasurement =
170 modelPoseSensor->getDerivedMeasurement(timestep);
172 modelRootTransformation * modelPoseSensorMeasurement->getRootPose();
173 m->poseTrajData[timestep] = getTrajData(pose);
176 KinematicSensorList kinematicSensors = motion->getSensorsByType<KinematicSensor>();
177 for (KinematicSensorPtr kinematicSensor : kinematicSensors)
179 KinematicSensorPtr kSensor = kinematicSensor;
180 std::vector<std::string> jointNames = kinematicSensor->getJointNames();
181 m->jointNames.insert(m->jointNames.end(), jointNames.begin(), jointNames.end());
182 if (butterworthFilterCutOffFreq > 0.0f)
184 kSensor = KinematicSensorPtr(
new KinematicSensor(jointNames));
185 std::vector<filters::ButterworthFilter> filters;
186 for (
size_t j = 0; j < jointNames.size(); j++)
192 bool initialized =
false;
193 for (
float timestep : m->timestamp)
195 KinematicSensorMeasurementPtr kinematicSensorMeasurement =
196 kinematicSensor->getDerivedMeasurement(timestep);
197 if (!kinematicSensorMeasurement)
199 MMM_ERROR <<
"No kinematic measurement at timestep " << timestep
200 <<
" for motion with name '" << motion->getName() <<
"'";
203 Eigen::VectorXf
jointAngles = kinematicSensorMeasurement->getJointAngles();
204 for (
size_t j = 0; j < jointNames.size(); j++)
212 jointAngles[j] = filters[j].getValue()->getDouble();
214 kSensor->addSensorMeasurement(KinematicSensorMeasurementPtr(
215 new KinematicSensorMeasurement(timestep,
jointAngles)));
219 for (
float timestep : m->timestamp)
221 KinematicSensorMeasurementPtr kinematicSensorMeasurement =
222 kSensor->getDerivedMeasurement(timestep);
223 if (kinematicSensorMeasurement)
225 m->jointTrajData.push_back(
226 getTrajData(kinematicSensorMeasurement->getJointAngles()));
230 MMM_ERROR <<
"No kinematic measurement at timestep " << timestep
231 <<
" for motion with name '" << motion->getName() <<
"'";
240 m->scaling = model->getScaling();
244 auto modelProcessor =
245 std::dynamic_pointer_cast<MMM::ModelProcessorWinter>(motion->getModelProcessor());
248 m->scaling = modelProcessor->getHeight();
256 motionNames.push_back(motion->getName());
257 motionData[motion->getName()] = m;
259 return motionData.size();
263 MotionFileWrapper::loadLegacyMotion(
const std::string& motionFilePath,
264 const std::string relativeModelRoot)
267 LegacyMotionReaderXML reader;
268 LegacyMotionList motions = reader.loadAllMotions(motionFilePath);
271 for (
auto motion : motions)
273 ModelPtr model = motion->getModel();
275 model ? std::filesystem::path(model->getFilename()) : motion->getModelFilePath();
276 if (std::filesystem::path(
filename).stem() == relativeModelRoot)
278 auto motionFrames = motion->getMotionFrames();
279 if (motionFrames.size() > 0)
282 Eigen::Vector3f orientation = simox::math::mat4f_to_rpy(rootPose);
283 modelRootTransformation.block<3,3>(0, 0) =
284 simox::math::rpy_to_mat3f(0, 0, -orientation(2));
285 modelRootTransformation.block<3,1>(0, 3) =
286 Eigen::Vector3f(-rootPose(0, 3), -rootPose(1, 3), 0);
291 for (
auto motion : motions)
294 ModelPtr model = motion->getModel();
295 m->modelPath = model ? model->getFilename() : motion->getModelFilePath().c_str();
296 m->numberOfFrames = motion->getNumFrames();
297 m->jointNames = motion->getJointNames();
299 if (butterworthFilterCutOffFreq > 0.0f)
301 for (
size_t j = 0; j < motion->getJointNames().size(); j++)
304 filter.setInitialValue(motion->getMotionFrame(0)->joint[j]);
305 for (
size_t i = 0; i < motion->getNumFrames(); i++)
307 filter.update(0,
new Variant(motion->getMotionFrame(i)->joint[j]));
308 motion->getMotionFrame(i)->joint[j] = filter.getValue()->getDouble();
314 for (
size_t i = 0; i < motion->getNumFrames(); ++i)
316 MMM::MotionFramePtr frame = motion->getMotionFrame(i);
318 m->poseTrajData[frame->timestep] = getTrajData(pose);
319 m->timestamp.push_back(frame->timestep);
320 m->jointTrajData.push_back(getTrajData(frame->joint));
325 m->scaling = model->getScaling();
329 auto modelProcessor =
330 std::dynamic_pointer_cast<MMM::ModelProcessorWinter>(motion->getModelProcessor());
333 m->scaling = modelProcessor->getHeight();
341 motionNames.push_back(motion->getName());
342 motionData[motion->getName()] = m;
344 return motionData.size();
351 ::Ice::DoubleSeq curData;
352 curData.push_back(rootPose(0, 3));
353 curData.push_back(rootPose(1, 3));
354 curData.push_back(rootPose(2, 3));
355 curData.push_back(
q.w);
356 curData.push_back(
q.x);
357 curData.push_back(
q.y);
358 curData.push_back(
q.z);
363 MotionFileWrapper::getTrajData(
const Eigen::VectorXf&
jointAngles)
365 DoubleSeqSeq curdata;
368 ::Ice::DoubleSeq dimData;
370 curdata.push_back(dimData);
378 if (motionNames.size() == 0)
384 return motionData[motionNames.at(0)];
391 for (
auto m : motionData)
393 if (std::filesystem::path(m.second->modelPath).stem() == modelName)
404 return motionData[motionName];
410 ::Ice::StringSeq modelNames;
411 for (
auto m : motionData)
413 modelNames.push_back(std::filesystem::path(m.second->modelPath).stem());