TSMP.cpp
Go to the documentation of this file.
1 #include "TSMP.h"
2 
3 #include <SimoxUtility/math/compare/is_equal.h>
4 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
5 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
6 #include <VirtualRobot/MathTools.h>
7 
9 
12 
13 #include "../utils.h"
14 
16 {
17 
18  TSMP::TSMP(const MPConfig& c) : MP{c}
19  {
20 
21  ARMARX_INFO << " -- created TSMP with name: " << VAROUT(cfg.name);
22  // if (cfg.viaPoints.size() > 0)
23  // {
24  // for (const auto& vp : cfg.viaPoints)
25  // {
26  //// std::map<std::string, FramedPose> viapointsMapTemp;
27  //// viapointsMapTemp = userConfig["via_points"].get<decltype(viapointsMapTemp)>();
28  // ARMARX_IMPORTANT << VAROUT(vp.canonicalValue) << " " << VAROUT(common::dVecToString(vp.viaPointValue)) << " " << VAROUT(vmp->getUmin());
29  // ARMARX_CHECK_GREATER_EQUAL(vp.canonicalValue, 0);
30  // ARMARX_CHECK_LESS_EQUAL(vp.canonicalValue, 1);
31  // PosePtr p = new Pose(vp.viaPointValue);
32  // userDefinedViaPoints.push_back({vp.canonicalValue, common::poseToDVec(p)});
33  // }
34  // }
35  }
36 
37  void
39  {
40  setStart(starts);
41  vmp->setInitialState(currentState);
42  vmp->prepareExecution();
43  }
44 
45  void
47  {
48  if (not running.load())
49  {
50  return;
51  }
52  TSMPInputPtr in = std::dynamic_pointer_cast<TSMPInput>(input);
53  TSMPOutputPtr out = std::dynamic_pointer_cast<TSMPOutput>(output);
54  ARMARX_CHECK_NOT_NULL(in) << "\nInput pointer for TSMP has wrong type or empty";
55  ARMARX_CHECK_NOT_NULL(out) << "\nOutput pointer for TSMP has wrong type or empty";
56 
57  out->vel.setZero();
58  if (paused.load())
59  {
60  return;
61  }
62 
63  // ARMARX_INFO << VAROUT(canonicalValue); // << VAROUT(deltaT) << VAROUT(currentPose);
64  double phaseStop = 0.0;
65  double tau = 1.0;
66 
67  if (canonicalValue < 0.01 && cfg.mpStyle == "Periodic")
68  {
69  ARMARX_IMPORTANT << " -- Periodic mode: new iteration.";
70  canonicalValue = 1.0;
71  }
72  if (canonicalValue < 1e-8 && cfg.mpStyle == "Discrete")
73  {
74  ARMARX_INFO << " -- Discrete mode: MP " << cfg.name << " finished.";
75  running.store(false);
76  return;
77  }
78 
79  LockGuardType guard(mpMutex);
80  Eigen::Matrix4f currentPose = in->pose;
81  // Eigen::Vector6f currentVel = in->vel;
82 
83  std::vector<double> currentPoseVec = common::mat4ToDVec(currentPose);
84  for (size_t i = 0; i < currentState.size(); i++)
85  {
86  currentState[i].pos = currentPoseVec[i];
87  }
88  double deltaT = in->deltaT;
89 
90  // /// calculate phase stop based on current pose and target pose
91  // // if (cfg.enablePhaseStop)
92  // // {
93  // double posiError = 0;
94  // double oriError = 0;
95 
96  // Eigen::Vector3d targetPosition {targetPoseVec[0], targetPoseVec[1], targetPoseVec[2]};
97  // Eigen::Quaterniond targetQuaternion {targetPoseVec[3], targetPoseVec[4], targetPoseVec[5], targetPoseVec[6]}; // w,x,y,z convention
98 
99  // getError(currentPose, targetPosition, targetQuaternion, posiError, oriError);
100 
101  // double poseError = posiError + cfg.psMM2Radian * oriError;
102 
103  // double phaseDist;
104  // if (isDisturbance)
105  // {
106  // phaseDist = cfg.backDist;
107  // }
108  // else
109  // {
110  // phaseDist = cfg.goDist;
111  // }
112  // double phaseL = cfg.maxValue;
113  // double phaseK = cfg.slop;
114 
115  // phaseStop = phaseL / (1 + exp(-phaseK * (poseError - phaseDist)));
116  // double mpcFactor = 1 - (phaseStop / phaseL);
117 
118  // if (mpcFactor < 0.1)
119  // {
120  // isDisturbance = true;
121  // }
122 
123  // if (mpcFactor > 0.9)
124  // {
125  // isDisturbance = false;
126  // }
127 
128  double timeDuration = cfg.durationSec;
129  canonicalValue -= tau * deltaT / ((1 + phaseStop) * timeDuration);
130 
131  std::vector<mplib::representation::MPState> targetState =
132  std::dynamic_pointer_cast<mplib::representation::vmp::TaskSpacePrincipalComponentVMP>(
133  vmp)
134  ->calculateDesiredState(canonicalValue, currentState);
135 
136  // scale translation velocity
137  for (size_t i = 0; i < 3; ++i)
138  {
139  currentState[i].vel = tau * targetState[i].vel * cfg.amplitude / timeDuration;
140  currentState[i].pos += deltaT * currentState[i].vel;
141  }
142 
143  // // define the translation velocity
144  // if (cfg.enablePhaseStop)
145  // {
146  // float vel0, vel1;
147 
148  // for (size_t i = 0; i < 3; i++)
149  // {
150  // vel0 = currentState[i].vel;
151  // vel1 = cfg.psKpPos * (targetPoseVec[i] - currentPose(i, 3)) - cfg.psKdPos * currentVel(i);
152  // targetVel(i) = mpcFactor * vel0 + (1 - mpcFactor) * vel1;
153  // }
154  // }
155  // else
156  // {
157  for (size_t i = 0; i < 3; i++)
158  {
159  out->vel(i) = currentState[i].vel;
160  }
161  // }
162 
163  // define the rotation velocity
164  Eigen::Quaterniond dmpQuaternionVel{
165  targetState[3].vel, targetState[4].vel, targetState[5].vel, targetState[6].vel};
166  Eigen::Quaterniond dmpQuaternionPosi{
167  currentState[3].pos, currentState[4].pos, currentState[5].pos, currentState[6].pos};
168  Eigen::Quaterniond angularVel0 = dmpQuaternionVel * dmpQuaternionPosi.inverse();
169  angularVel0.w() *= 2;
170  angularVel0.x() *= 2;
171  angularVel0.y() *= 2;
172  angularVel0.z() *= 2;
173 
174 
175  double angularChange = angularVel0.angularDistance(previousAngularVelocity);
176  if (angularVel0.w() * previousAngularVelocity.w() < 0 &&
177  angularVel0.x() * previousAngularVelocity.x() < 0 &&
178  angularVel0.y() * previousAngularVelocity.y() < 0 &&
179  angularVel0.z() * previousAngularVelocity.z() < 0 && angularChange < 1e-2)
180  {
181  angularVel0.w() = -angularVel0.w();
182  angularVel0.x() = -angularVel0.x();
183  angularVel0.y() = -angularVel0.y();
184  angularVel0.z() = -angularVel0.z();
185  }
186  previousAngularVelocity = angularVel0;
187 
188  // scale orientation velocity
189  angularVel0.w() = 0;
190  angularVel0.x() =
191  tau * angularVel0.x() * /*config.oriAmplitude*/ cfg.amplitude / timeDuration;
192  angularVel0.y() =
193  tau * angularVel0.y() * /*config.oriAmplitude*/ cfg.amplitude / timeDuration;
194  angularVel0.z() =
195  tau * angularVel0.z() * /*config.oriAmplitude*/ cfg.amplitude / timeDuration;
196 
197  // Eigen::Quaterniond scaledQuat = (angularVel0 * dmpQuaternionPosi);
198  // currentState[3].vel = 0.5 * scaledQuat.w();
199  // currentState[4].vel = 0.5 * scaledQuat.x();
200  // currentState[6].vel = 0.5 * scaledQuat.z();
201  // currentState[5].vel = 0.5 * scaledQuat.y();
202 
203  for (size_t i = 3; i < 7; ++i)
204  {
205  currentState[i].vel =
206  tau * targetState[i].vel * /*config.oriAmplitude*/ cfg.amplitude / timeDuration;
207  currentState[i].pos += currentState[i].vel * deltaT;
208  }
209 
210  // if (cfg.enablePhaseStop)
211  // {
212  // Eigen::Quaternionf targetQuaternionf {(float)targetPoseVec[3], (float)targetPoseVec[4], (float)targetPoseVec[5], (float)targetPoseVec[6]};
213 
214  // Eigen::Matrix3f desiredMat(targetQuaternionf);
215  // Eigen::Matrix3f currentMat = currentPose.block<3, 3>(0, 0);
216  // Eigen::Matrix3f diffMat = desiredMat * currentMat.inverse();
217  // Eigen::Vector3f diffRPY = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
218  // Eigen::Vector3f angularVel1 = /*config.phaseStopParas.Kori*/cfg.psKpOri * diffRPY - /*config.phaseStopParas.Dori*/cfg.psKdOri * currentVel.tail(3);
219 
220  // targetVel(3) = mpcFactor * angularVel0.x() / timeDuration + (1 - mpcFactor) * angularVel1(0);
221  // targetVel(4) = mpcFactor * angularVel0.y() / timeDuration + (1 - mpcFactor) * angularVel1(1);
222  // targetVel(5) = mpcFactor * angularVel0.z() / timeDuration + (1 - mpcFactor) * angularVel1(2);
223  // }
224  // else
225  // {
226  out->vel(3) = angularVel0.x();
227  out->vel(4) = angularVel0.y();
228  out->vel(5) = angularVel0.z();
229  // }
230 
231  // // debugData.canonicalValue = canonicalValue;
232  // // debugData.oriError = oriError;
233  // // debugData.posiError = posiError;
234  // // debugData.mpcFactor = mpcFactor;
235  // // debugData.poseError = poseError;
236  // Eigen::VectorXf desiredPosition;
237  // desiredPosition.setZero(currentState.size());
238  // for (size_t i = 0; i < currentState.size(); i++)
239  // {
240  // desiredPosition[i] = currentState[i][0];
241  // }
242  std::vector<double> targetVec;
243  for (const auto& t : targetState)
244  {
245  targetVec.push_back(t.pos);
246  };
247  out->pose = common::dVecToMat4(targetVec);
248  if (firstRun.load())
249  {
250  firstRun.store(false);
251  }
252  }
253 
254 } // namespace armarx::control::common::mp
armarx::control::common::mp::MP
Definition: MP.h:67
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::control::common::mp::TSMP::TSMP
TSMP(const MPConfig &c)
Definition: TSMP.cpp:18
TSMP.h
armarx::control::common::mp::MP::canonicalValue
double canonicalValue
Definition: MP.h:145
ARMARX_CHECK_NOT_NULL
#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...
Definition: ExpressionException.h:206
armarx::control::common::mp::TSMP::validateInitialState
void validateInitialState(const DVec &starts) override
Definition: TSMP.cpp:38
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::control::common::mp
This file is part of ArmarX.
Definition: aron_conversions.cpp:331
armarx::control::common::mp::TSMP::run
void run(MPInputPtr, MPOutputPtr) override
Definition: TSMP.cpp:46
armarx::control::common::mp::MP::setStart
void setStart(const DVec &starts)
Definition: MP.cpp:343
armarx::control::common::mp::TSMP::previousAngularVelocity
Eigen::Quaterniond previousAngularVelocity
Definition: TSMP.h:60
armarx::control::common::mp::MP::firstRun
std::atomic_bool firstRun
Definition: MP.h:146
armarx::control::common::mp::MP::cfg
MPConfig cfg
Definition: MP.h:134
armarx::control::common::mp::LockGuardType
std::lock_guard< std::recursive_mutex > LockGuardType
Definition: MP.h:44
armarx::control::common::mp::TSMPOutputPtr
std::shared_ptr< TSMPOutput > TSMPOutputPtr
Definition: TSMP.h:47
FramedPose.h
armarx::control::common::mp::DVec
Ice::DoubleSeq DVec
Definition: MP.h:46
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
armarx::control::common::mp::MP::paused
std::atomic_bool paused
Definition: MP.h:144
armarx::control::common::mp::MPInputPtr
std::shared_ptr< MPInput > MPInputPtr
Definition: MP.h:63
armarx::control::common::mp::MP::vmp
VMPPtr vmp
Definition: MP.h:139
armarx::control::common::dVecToMat4
Eigen::Matrix4f dVecToMat4(const mplib::core::DVec &dvec)
create Eigen:Matrix4f from 7D double vector.
Definition: utils.cpp:218
armarx::control::common::mp::MP::currentState
std::vector< mplib::representation::MPState > currentState
Definition: MP.h:154
ExpressionException.h
armarx::control::common::mp::MPOutputPtr
std::shared_ptr< MPOutput > MPOutputPtr
Definition: MP.h:64
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::control::common::mat4ToDVec
mplib::core::DVec mat4ToDVec(const Eigen::Matrix4f &mat)
convert Eigen:Matrix4f to 7D double vector.
Definition: utils.cpp:240
Eigen::Quaterniond
Quaternion< double, 0 > Quaterniond
Definition: EigenForwardDeclarations.h:62
armarx::control::common::mp::TSMPInputPtr
std::shared_ptr< TSMPInput > TSMPInputPtr
Definition: TSMP.h:46
armarx::control::common::mp::MP::mpMutex
MutexType mpMutex
Definition: MP.h:138
json_conversions.h
armarx::control::common::mp::MP::running
std::atomic_bool running
Definition: MP.h:142