28 #include <MMM/Motion/MotionReaderXML.h>
29 #include <MMM/Motion/Legacy/LegacyMotionReaderXML.h>
30 #include <MMM/Motion/Legacy/LegacyMotion.h>
31 #include <MMM/Motion/Plugin/KinematicPlugin/KinematicSensor.h>
32 #include <MMM/Motion/Plugin/ModelPosePlugin/ModelPoseSensor.h>
33 #include <MMM/Model/ModelProcessorWinter.h>
38 #include <VirtualRobot/MathTools.h>
39 #include <VirtualRobot/Robot.h>
40 #include <SimoxUtility/math/convert.h>
41 #include <SimoxUtility/xml/rapidxml/RapidXMLWrapper.h>
42 #include <MMM/Motion/XMLTools.h>
53 simox::xml::RapidXMLWrapperRootNodePtr root = simox::xml::RapidXMLWrapperRootNode::FromFile(motionFilePath);
54 if (root && root->name() == xml::tag::MMM_ROOT)
56 if (!root->has_attribute(xml::attribute::VERSION))
58 if (!wrapper->loadLegacyMotion(motionFilePath))
65 std::string version = root->attribute_value(xml::attribute::VERSION);
68 if (!wrapper->loadMotion(motionFilePath, relativeModelRoot))
73 else if (version ==
"1.0 ")
75 if (!wrapper->loadLegacyMotion(motionFilePath, relativeModelRoot))
82 ARMARX_ERROR <<
"Could not load mmm motion with version '" << version <<
"'";
95 MotionFileWrapper::MotionFileWrapper(
int butterworthFilterCutOffFreq) : butterworthFilterCutOffFreq(butterworthFilterCutOffFreq)
99 bool MotionFileWrapper::loadMotion(
const std::string& motionFilePath,
const std::string relativeModelRoot)
102 MotionRecordingPtr motions;
105 MotionReaderXMLPtr motionReader(
new MotionReaderXML());
106 motions = motionReader->loadMotionRecording(motionFilePath);
108 catch (Exception::MMMException& e)
110 ARMARX_ERROR <<
"Could not load mmm motion! " << e.what();
115 for (
auto motion : *motions)
117 ModelPtr model = motion->getModel();
120 if (!model->getFilename().empty() && std::filesystem::path(model->getFilename()).stem() == relativeModelRoot)
122 auto modelPoseSensor = motion->getSensorByType<ModelPoseSensor>();
123 if (modelPoseSensor && modelPoseSensor->getTimesteps().size() > 0)
125 auto modelPoseSensorMeasurement = modelPoseSensor->getDerivedMeasurement(modelPoseSensor->getTimesteps().at(0));
127 Eigen::Vector3f orientation = simox::math::mat4f_to_rpy(rootPose);
128 modelRootTransformation.block(0, 0, 3, 3) = simox::math::rpy_to_mat3f(0, 0, -orientation(2));
129 modelRootTransformation.block(0, 3, 3, 1) = Eigen::Vector3f(-rootPose(0, 3), -rootPose(1, 3), 0);
135 for (
auto motion : *motions)
139 ModelPtr model = motion->getModel();
142 m->modelPath = model->getFilename();
145 ModelPoseSensorPtr modelPoseSensor = motion->getSensorByType<ModelPoseSensor>();
146 if (!modelPoseSensor)
148 ARMARX_ERROR <<
"Ignoring motion with name '" << motion->getName() <<
"', because it has no model pose sensor!";
152 std::vector<float> t = modelPoseSensor->getTimesteps();
153 m->timestamp = ::Ice::DoubleSeq(t.begin(), t.end());
154 m->numberOfFrames = m->timestamp.size();
155 for (
float timestep : m->timestamp)
157 ModelPoseSensorMeasurementPtr modelPoseSensorMeasurement = modelPoseSensor->getDerivedMeasurement(timestep);
158 Eigen::Matrix4f pose = modelRootTransformation * modelPoseSensorMeasurement->getRootPose();
159 m->poseTrajData[timestep] = getTrajData(pose);
162 KinematicSensorList kinematicSensors = motion->getSensorsByType<KinematicSensor>();
163 for (KinematicSensorPtr kinematicSensor : kinematicSensors)
165 KinematicSensorPtr kSensor = kinematicSensor;
166 std::vector<std::string> jointNames = kinematicSensor->getJointNames();
167 m->jointNames.insert(m->jointNames.end(), jointNames.begin(), jointNames.end());
168 if (butterworthFilterCutOffFreq > 0.0f)
170 kSensor = KinematicSensorPtr(
new KinematicSensor(jointNames));
171 std::vector<filters::ButterworthFilter> filters;
172 for (
size_t j = 0; j < jointNames.size(); j++)
177 bool initialized =
false;
178 for (
float timestep : m->timestamp)
180 KinematicSensorMeasurementPtr kinematicSensorMeasurement = kinematicSensor->getDerivedMeasurement(timestep);
181 if (!kinematicSensorMeasurement)
183 MMM_ERROR <<
"No kinematic measurement at timestep " << timestep <<
" for motion with name '" << motion->getName() <<
"'";
186 Eigen::VectorXf
jointAngles = kinematicSensorMeasurement->getJointAngles();
187 for (
size_t j = 0; j < jointNames.size(); j++)
195 jointAngles[j] = filters[j].getValue()->getDouble();
197 kSensor->addSensorMeasurement(KinematicSensorMeasurementPtr(
new KinematicSensorMeasurement(timestep,
jointAngles)));
201 for (
float timestep : m->timestamp)
203 KinematicSensorMeasurementPtr kinematicSensorMeasurement = kSensor->getDerivedMeasurement(timestep);
204 if (kinematicSensorMeasurement)
206 m->jointTrajData.push_back(getTrajData(kinematicSensorMeasurement->getJointAngles()));
210 MMM_ERROR <<
"No kinematic measurement at timestep " << timestep <<
" for motion with name '" << motion->getName() <<
"'";
219 m->scaling = model->getScaling();
223 auto modelProcessor = std::dynamic_pointer_cast<MMM::ModelProcessorWinter>(motion->getModelProcessor());
226 m->scaling = modelProcessor->getHeight();
234 motionNames.push_back(motion->getName());
235 motionData[motion->getName()] = m;
237 return motionData.size();
240 bool MotionFileWrapper::loadLegacyMotion(
const std::string& motionFilePath,
const std::string relativeModelRoot)
243 LegacyMotionReaderXML reader;
244 LegacyMotionList motions = reader.loadAllMotions(motionFilePath);
247 for (
auto motion : motions)
249 ModelPtr model = motion->getModel();
250 std::filesystem::path
filename = model ? std::filesystem::path(model->getFilename()) : motion->getModelFilePath();
251 if (std::filesystem::path(
filename).stem() == relativeModelRoot)
253 auto motionFrames = motion->getMotionFrames();
254 if (motionFrames.size() > 0)
257 Eigen::Vector3f orientation = simox::math::mat4f_to_rpy(rootPose);
258 modelRootTransformation.block(0, 0, 3, 3) = simox::math::rpy_to_mat3f(0, 0, -orientation(2));
259 modelRootTransformation.block(0, 3, 3, 1) = Eigen::Vector3f(-rootPose(0, 3), -rootPose(1, 3), 0);
264 for (
auto motion : motions)
267 ModelPtr model = motion->getModel();
268 m->modelPath = model ? model->getFilename() : motion->getModelFilePath().c_str();
269 m->numberOfFrames = motion->getNumFrames();
270 m->jointNames = motion->getJointNames();
272 if (butterworthFilterCutOffFreq > 0.0f)
274 for (
size_t j = 0; j < motion->getJointNames().size(); j++)
277 filter.setInitialValue(motion->getMotionFrame(0)->joint[j]);
278 for (
size_t i = 0; i < motion->getNumFrames(); i++)
280 filter.update(0,
new Variant(motion->getMotionFrame(i)->joint[j]));
281 motion->getMotionFrame(i)->joint[j] = filter.getValue()->getDouble();
287 for (
size_t i = 0; i < motion->getNumFrames(); ++i)
289 MMM::MotionFramePtr frame = motion->getMotionFrame(i);
291 m->poseTrajData[frame->timestep] = getTrajData(pose);
292 m->timestamp.push_back(frame->timestep);
293 m->jointTrajData.push_back(getTrajData(frame->joint));
298 m->scaling = model->getScaling();
302 auto modelProcessor = std::dynamic_pointer_cast<MMM::ModelProcessorWinter>(motion->getModelProcessor());
305 m->scaling = modelProcessor->getHeight();
313 motionNames.push_back(motion->getName());
314 motionData[motion->getName()] = m;
316 return motionData.size();
319 ::Ice::DoubleSeq MotionFileWrapper::getTrajData(
const Eigen::Matrix4f& rootPose)
322 ::Ice::DoubleSeq curData;
323 curData.push_back(rootPose(0, 3));
324 curData.push_back(rootPose(1, 3));
325 curData.push_back(rootPose(2, 3));
326 curData.push_back(
q.w);
327 curData.push_back(
q.x);
328 curData.push_back(
q.y);
329 curData.push_back(
q.z);
333 DoubleSeqSeq MotionFileWrapper::getTrajData(
const Eigen::VectorXf&
jointAngles)
335 DoubleSeqSeq curdata;
338 ::Ice::DoubleSeq dimData;
340 curdata.push_back(dimData);
347 if (motionNames.size() == 0)
353 return motionData[motionNames.at(0)];
360 for (
auto m : motionData)
362 if (std::filesystem::path(m.second->modelPath).stem() == modelName)
372 return motionData[motionName];
377 ::Ice::StringSeq modelNames;
378 for (
auto m : motionData)
380 modelNames.push_back(std::filesystem::path(m.second->modelPath).stem());