1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
17*ec779b8eSAndroid Build Coastguard Worker
18*ec779b8eSAndroid Build Coastguard Worker #include "media/Pose.h"
19*ec779b8eSAndroid Build Coastguard Worker #include "media/QuaternionUtil.h"
20*ec779b8eSAndroid Build Coastguard Worker #include "media/Twist.h"
21*ec779b8eSAndroid Build Coastguard Worker
22*ec779b8eSAndroid Build Coastguard Worker namespace android {
23*ec779b8eSAndroid Build Coastguard Worker namespace media {
24*ec779b8eSAndroid Build Coastguard Worker
25*ec779b8eSAndroid Build Coastguard Worker using android::base::StringAppendF;
26*ec779b8eSAndroid Build Coastguard Worker using Eigen::Vector3f;
27*ec779b8eSAndroid Build Coastguard Worker
fromVector(const std::vector<float> & vec)28*ec779b8eSAndroid Build Coastguard Worker std::optional<Pose3f> Pose3f::fromVector(const std::vector<float>& vec) {
29*ec779b8eSAndroid Build Coastguard Worker if (vec.size() != 6) {
30*ec779b8eSAndroid Build Coastguard Worker return std::nullopt;
31*ec779b8eSAndroid Build Coastguard Worker }
32*ec779b8eSAndroid Build Coastguard Worker return Pose3f({vec[0], vec[1], vec[2]}, rotationVectorToQuaternion({vec[3], vec[4], vec[5]}));
33*ec779b8eSAndroid Build Coastguard Worker }
34*ec779b8eSAndroid Build Coastguard Worker
toVector() const35*ec779b8eSAndroid Build Coastguard Worker std::vector<float> Pose3f::toVector() const {
36*ec779b8eSAndroid Build Coastguard Worker Eigen::Vector3f rot = quaternionToRotationVector(mRotation);
37*ec779b8eSAndroid Build Coastguard Worker return {mTranslation[0], mTranslation[1], mTranslation[2], rot[0], rot[1], rot[2]};
38*ec779b8eSAndroid Build Coastguard Worker }
39*ec779b8eSAndroid Build Coastguard Worker
toString() const40*ec779b8eSAndroid Build Coastguard Worker std::string Pose3f::toString() const {
41*ec779b8eSAndroid Build Coastguard Worker const auto& vec = this->toVector();
42*ec779b8eSAndroid Build Coastguard Worker std::string ss = "[";
43*ec779b8eSAndroid Build Coastguard Worker for (auto f = vec.begin(); f != vec.end(); ++f) {
44*ec779b8eSAndroid Build Coastguard Worker if (f != vec.begin()) {
45*ec779b8eSAndroid Build Coastguard Worker ss.append(", ");
46*ec779b8eSAndroid Build Coastguard Worker }
47*ec779b8eSAndroid Build Coastguard Worker StringAppendF(&ss, "%0.2f", *f);
48*ec779b8eSAndroid Build Coastguard Worker }
49*ec779b8eSAndroid Build Coastguard Worker ss.append("]");
50*ec779b8eSAndroid Build Coastguard Worker return ss;
51*ec779b8eSAndroid Build Coastguard Worker }
52*ec779b8eSAndroid Build Coastguard Worker
moveWithRateLimit(const Pose3f & from,const Pose3f & to,float t,float maxTranslationalVelocity,float maxRotationalVelocity)53*ec779b8eSAndroid Build Coastguard Worker std::tuple<Pose3f, bool> moveWithRateLimit(const Pose3f& from, const Pose3f& to, float t,
54*ec779b8eSAndroid Build Coastguard Worker float maxTranslationalVelocity,
55*ec779b8eSAndroid Build Coastguard Worker float maxRotationalVelocity) {
56*ec779b8eSAndroid Build Coastguard Worker // Never rate limit if both limits are set to infinity.
57*ec779b8eSAndroid Build Coastguard Worker if (isinf(maxTranslationalVelocity) && isinf(maxRotationalVelocity)) {
58*ec779b8eSAndroid Build Coastguard Worker return {to, false};
59*ec779b8eSAndroid Build Coastguard Worker }
60*ec779b8eSAndroid Build Coastguard Worker // Always rate limit if t is 0 (required to avoid division by 0).
61*ec779b8eSAndroid Build Coastguard Worker if (t == 0 || maxTranslationalVelocity == 0 || maxRotationalVelocity == 0) {
62*ec779b8eSAndroid Build Coastguard Worker return {from, true};
63*ec779b8eSAndroid Build Coastguard Worker }
64*ec779b8eSAndroid Build Coastguard Worker
65*ec779b8eSAndroid Build Coastguard Worker Pose3f fromToTo = from.inverse() * to;
66*ec779b8eSAndroid Build Coastguard Worker Twist3f twist = differentiate(fromToTo, t);
67*ec779b8eSAndroid Build Coastguard Worker float angularRotationalRatio = twist.scalarRotationalVelocity() / maxRotationalVelocity;
68*ec779b8eSAndroid Build Coastguard Worker float translationalVelocityRatio =
69*ec779b8eSAndroid Build Coastguard Worker twist.scalarTranslationalVelocity() / maxTranslationalVelocity;
70*ec779b8eSAndroid Build Coastguard Worker float maxRatio = std::max(angularRotationalRatio, translationalVelocityRatio);
71*ec779b8eSAndroid Build Coastguard Worker if (maxRatio <= 1) {
72*ec779b8eSAndroid Build Coastguard Worker return {to, false};
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker return {from * integrate(twist, t / maxRatio), true};
75*ec779b8eSAndroid Build Coastguard Worker }
76*ec779b8eSAndroid Build Coastguard Worker
operator <<(std::ostream & os,const Pose3f & pose)77*ec779b8eSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Pose3f& pose) {
78*ec779b8eSAndroid Build Coastguard Worker os << "translation: " << pose.translation().transpose()
79*ec779b8eSAndroid Build Coastguard Worker << " quaternion: " << pose.rotation().coeffs().transpose();
80*ec779b8eSAndroid Build Coastguard Worker return os;
81*ec779b8eSAndroid Build Coastguard Worker }
82*ec779b8eSAndroid Build Coastguard Worker
83*ec779b8eSAndroid Build Coastguard Worker } // namespace media
84*ec779b8eSAndroid Build Coastguard Worker } // namespace android
85