predictions.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects
17 * @author phesch ( ulila at student dot kit dot edu )
18 * @date 2022
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "predictions.h"
24
25#include <SimoxUtility/math/pose/pose.h>
26#include <SimoxUtility/math/regression/linear.h>
27
30
31#include <manif/SE3.h>
32
33namespace armarx::objpose
34{
35
36 objpose::ObjectPosePredictionResult
37 predictObjectPoseLinear(const std::map<DateTime, ObjectPose>& poses,
38 const DateTime& time,
39 const ObjectPose& latestPose)
40 {
41 objpose::ObjectPosePredictionResult result;
42 result.success = false;
43
44 const DateTime timeOrigin = DateTime::Now();
45
46 static const int tangentDims = 6;
48
49 std::vector<double> timestampsSec;
50 std::vector<Vector6d> tangentPoses;
51
52 // ToDo: How to handle attached objects?
53 for (const auto& [timestamp, pose] : poses)
54 {
55 timestampsSec.push_back((timestamp - timeOrigin).toSecondsDouble());
56 manif::SE3f se3(simox::math::position(pose.objectPoseGlobal),
57 Eigen::Quaternionf(simox::math::orientation(pose.objectPoseGlobal)));
58 tangentPoses.emplace_back(se3.cast<double>().log().coeffs());
59 }
60
61 ARMARX_CHECK_EQUAL(timestampsSec.size(), tangentPoses.size());
62
63 Eigen::Matrix4f prediction;
64 // Static objects don't move. Objects that haven't moved for a while probably won't either.
65 if (timestampsSec.size() <= 1 || latestPose.isStatic)
66 {
67 prediction = latestPose.objectPoseGlobal;
68 }
69 else
70 {
71 using simox::math::LinearRegression;
72 const bool inputOffset = false;
73
74 const LinearRegression<tangentDims> model =
75 LinearRegression<tangentDims>::Fit(timestampsSec, tangentPoses, inputOffset);
76 const auto predictionTime = armarx::fromIce<DateTime>(time);
77 Vector6d linearPred = model.predict((predictionTime - timeOrigin).toSecondsDouble());
78 prediction = manif::SE3Tangentd(linearPred).exp().transform().cast<float>();
79 }
80
81 // Used as a template for the returned pose prediction.
82 ObjectPose latestCopy = latestPose;
83
84 latestCopy.setObjectPoseGlobal(prediction);
85
86 result.success = true;
87 result.prediction = latestCopy.toIce();
88
89 return result;
90 }
91} // namespace armarx::objpose
std::string timestamp()
static DateTime Now()
Definition DateTime.cpp:51
Represents a point in time.
Definition DateTime.h:25
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Quaternion< float, 0 > Quaternionf
objpose::ObjectPosePredictionResult predictObjectPoseLinear(const std::map< DateTime, ObjectPose > &poses, const DateTime &time, const ObjectPose &latestPose)
Predict the pose of an object given a history of poses based on a linear regression.
void fromIce(const std::map< IceKeyT, IceValueT > &iceMap, boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
An object pose as stored by the ObjectPoseStorage.
Definition ObjectPose.h:34
data::ObjectPose toIce() const
void setObjectPoseGlobal(const Eigen::Matrix4f &objectPoseGlobal, bool updateObjectPoseRobot=true)
bool isStatic
Whether object is static. Static objects don't decay.
Definition ObjectPose.h:63
Eigen::Matrix4f objectPoseGlobal
The object pose in the global frame.
Definition ObjectPose.h:71