MixedImpedanceVelocityController.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  * @author Jianfeng Gao ( jianfeng dot gao at kit dot edu )
17  * @date 2024
18  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19  * GNU General Public License
20  */
21 
23 
25 
27 {
28  NJointControllerRegistration<NJointTSMixedImpedanceVelocityMPController>
30  "NJointTSMixedImpedanceVelocityMPController");
31 
33  const RobotUnitPtr& robotUnit,
34  const NJointControllerConfigPtr& config,
35  const VirtualRobot::RobotPtr& robot) :
37  {
38  mpConfig = MPListConfig();
39  ARMARX_IMPORTANT << getClassName() + " construction done";
40  }
41 
42  std::string
44  {
45  return "NJointTSMixedImpedanceVelocityMPController";
46  }
47 
48  void
51  const Ice::Current& iceCurrent)
52  {
53  if (isFinished("all"))
54  {
55  auto configData = MPListConfig::FromAron(dto);
56  isMPReady.store(false);
57  while (additionalTaskRunning.load())
58  {
59  usleep(1000);
60  }
61  for (const auto& _mp : configData.mpList)
62  {
63  if (limb.find(_mp.nodeSetName) == limb.end())
64  {
65  ARMARX_WARNING << "You have to make sure the RobotNodeSet " << _mp.nodeSetName
66  << " in your MP config "
67  << "corresponds to one of the RobotNodeSet in the controllers";
68  return;
69  }
70  }
71  mpConfig = configData;
73  // isMPReady.store(true);
74 
76  ARMARX_INFO << "-- successfully updated MP config.";
77  }
78  else
79  {
80  ARMARX_WARNING << "MP is not finished yet, cannot reset MP\n"
81  "If you want to force reset, please call \n\n"
82  " ctrl->stop('all') \n\n"
83  "before you continue";
84  }
85  }
86 
89  {
90  return mpConfig.toAronDTO();
91  }
92 
93  void
95  {
96  robotUnit->updateVirtualRobot(nonRtRobot);
97 
98  /// parse arguments and run mp
99  if (isMPReady.load())
100  {
101  additionalTaskRunning.store(true);
102  bool rtSafe = true;
103  for (auto& _mp : mps)
104  {
105  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
106  arm->nonRtConfig = arm->bufferConfigUserToNonRt.getUpToDateReadBuffer();
107  arm->rtStatusInNonRT = arm->bufferRtStatusToNonRt.getUpToDateReadBuffer();
108  rtSafe = rtSafe and arm->rtStatusInNonRT.rtSafe;
109 
110  if (_mp.second.mp->getClassName() == "TSMP")
111  {
112  mp::TSMPInputPtr in =
113  std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
114  in->pose = arm->rtStatusInNonRT.currentPose;
115  in->vel = arm->rtStatusInNonRT.currentTwist;
116  in->deltaT = arm->rtStatusInNonRT.deltaT;
117  }
118  else if (_mp.second.mp->getClassName() == "JSMP")
119  {
120  mp::JSMPInputPtr in =
121  std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
122  ARMARX_CHECK_EQUAL(arm->rtStatusInNonRT.numJoints,
123  arm->rtStatusInNonRT.qpos.size());
124  in->angleRadian = arm->rtStatusInNonRT.qpos;
125  in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
126  in->deltaT = arm->rtStatusInNonRT.deltaT;
127  }
128  }
129  if (rtSafe)
130  {
131  runMPs();
132  }
133  else
134  {
135  for (auto& _mp : mps)
136  for (auto& pair : limb)
137  {
138  if (not pair.second->rtReady)
139  continue;
140  const auto& desiredPose =
141  pair.second->rtStatusInNonRT.desiredPose.topRightCorner<3, 1>();
142  const auto& currentPose =
143  pair.second->rtStatusInNonRT.currentPose.topRightCorner<3, 1>();
144 
145  if ((desiredPose - currentPose).norm() >
146  pair.second->nonRtConfig.safeDistanceToGoal)
147  {
149  "new target \n\n [%.2f, %.2f, %.2f]\n\nis too far away from the "
150  "current pose\n\n [%.2f, %.2f, %.2f]",
151  pair.second->rtStatusInNonRT.desiredPose(0, 3),
152  pair.second->rtStatusInNonRT.desiredPose(1, 3),
153  pair.second->rtStatusInNonRT.desiredPose(2, 3),
154  pair.second->rtStatusInNonRT.currentPose(0, 3),
155  pair.second->rtStatusInNonRT.currentPose(1, 3),
156  pair.second->rtStatusInNonRT.currentPose(2, 3))
157  .deactivateSpam(1.0);
158  }
159  }
160  }
161  /// set mp target to rt buffer
162  for (auto& _mp : mps)
163  {
164  auto& arm = limb.at(_mp.second.mp->getNodeSetName());
165  if (_mp.second.mp->getClassName() == "TSMP")
166  {
167  mp::TSMPOutputPtr out =
168  std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
169  arm->nonRtConfig.desiredPose = out->pose;
170  arm->nonRtConfig.desiredTwist = out->vel;
171  }
172  else if (_mp.second.mp->getClassName() == "JSMP")
173  {
174  mp::JSMPOutputPtr out =
175  std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
176  ARMARX_CHECK_EQUAL(arm->rtStatusInNonRT.numJoints, out->angleRadian.size());
177  arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
178  }
179  }
180  for (auto& pair : limb)
181  {
182  limbNonRT(pair.second);
183  }
184  }
185  else
186  {
187  additionalTaskRunning.store(false);
188  }
189  }
190 
191  void
193  {
194  arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
195  arm->bufferConfigNonRtToRt.commitWrite();
196  }
197 
198  void
200  {
201  ARMARX_INFO << "-- reconfigure MP: reinitialize the mp input output, as well as the rt "
202  "related buffer values";
203  int index = 0;
204  for (auto& _mp : mps)
205  {
206  const auto& nodeSetName = _mp.second.mp->getNodeSetName();
207  ARMARX_CHECK_EQUAL(nodeSetName, limb.at(nodeSetName)->kinematicChainName);
208  VirtualRobot::RobotNodeSetPtr rns = rtGetRobot()->getRobotNodeSet(nodeSetName);
209  Eigen::Matrix4f currentPose = rns->getTCP()->getPoseInRootFrame();
210 
211  if (_mp.second.mp->getClassName() == "TSMP")
212  {
213  ARMARX_INFO << "---- (" << index << ") init input output data for "
214  << _mp.second.mp->getMPName();
215  std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input)->pose = currentPose;
216  std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input)->vel.setZero();
217  std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output)->pose = currentPose;
218  std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output)->vel.setZero();
219  }
220  else if (_mp.second.mp->getClassName() == "JSMP")
221  {
222  ARMARX_INFO << "---- (" << index << ") init input output data for "
223  << _mp.second.mp->getMPName() << " with "
224  << rns->getJointValues().size() << " joints";
225  std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input)->angleRadian =
226  rns->getJointValuesEigen();
227  std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input)->angularVel =
228  Eigen::VectorXf::Zero(rns->getJointValues().size());
229  std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output)->angleRadian =
230  rns->getJointValuesEigen();
231  std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output)->angularVel =
232  Eigen::VectorXf::Zero(rns->getJointValues().size());
233  }
234  index++;
235  }
236  }
237 } // namespace armarx::control::njoint_mp_controller::task_space
armarx::control::common::mp::MPPool::isMPReady
std::atomic< bool > isMPReady
Definition: MPPool.h:112
armarx::control::common::mp::MPPool::reconfigureMPs
void reconfigureMPs(const MPListConfig &mpListConfig)
Definition: MPPool.cpp:76
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::control::njoint_controller::task_space::NJointTaskspaceMixedImpedanceVelocityController::limb
std::map< std::string, ArmPtr > limb
Definition: MixedImpedanceVelocityController.h:150
armarx::control::njoint_mp_controller::task_space::registrationControllerNJointTSMixedImpedanceVelocityMPController
NJointControllerRegistration< NJointTSMixedImpedanceVelocityMPController > registrationControllerNJointTSMixedImpedanceVelocityMPController("NJointTSMixedImpedanceVelocityMPController")
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::control::common::mp::JSMPInputPtr
std::shared_ptr< JSMPInput > JSMPInputPtr
Definition: JSMP.h:47
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::limbNonRT
void limbNonRT(ArmPtr &arm)
Definition: MixedImpedanceVelocityController.cpp:192
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::additionalTask
void additionalTask() override
Definition: MixedImpedanceVelocityController.cpp:94
armarx::control::common::mp::MPPool::runMPs
void runMPs()
Definition: MPPool.cpp:83
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::getClassName
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override
Definition: MixedImpedanceVelocityController.cpp:43
armarx::control::common::mp::JSMPOutputPtr
std::shared_ptr< JSMPOutput > JSMPOutputPtr
Definition: JSMP.h:48
MixedImpedanceVelocityController.h
armarx::control::NJointTSMixedImpedanceVelocityMPControllerInterface::getMPConfig
armarx::aron::data::dto::Dict getMPConfig()
armarx::NJointControllerBase::rtGetRobot
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
Definition: NJointControllerBase.h:845
armarx::control::common::mp::TSMPOutputPtr
std::shared_ptr< TSMPOutput > TSMPOutputPtr
Definition: TSMP.h:47
armarx::control::njoint_controller::task_space::NJointTaskspaceMixedImpedanceVelocityController
Brief description of class NJointTaskspaceMixedImpedanceVelocityController.
Definition: MixedImpedanceVelocityController.h:50
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::mpConfig
MPListConfig mpConfig
this variable is only needed when constructing the MP instances, therefore you don't need to use trip...
Definition: MixedImpedanceVelocityController.h:71
armarx::control::njoint_controller::task_space::NJointTaskspaceMixedImpedanceVelocityController::nonRtRobot
VirtualRobot::RobotPtr nonRtRobot
Definition: MixedImpedanceVelocityController.h:152
utils.h
armarx::control::njoint_mp_controller::task_space
This file is part of ArmarX.
Definition: AdmittanceController.cpp:26
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::NJointTSMixedImpedanceVelocityMPController
NJointTSMixedImpedanceVelocityMPController(const RobotUnitPtr &robotUnit, const NJointControllerConfigPtr &config, const VirtualRobot::RobotPtr &)
Definition: MixedImpedanceVelocityController.cpp:32
armarx::control::common::mp::MPPool
Definition: MPPool.h:46
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::reInitMPInputOutputData
void reInitMPInputOutputData()
Definition: MixedImpedanceVelocityController.cpp:199
armarx::control::common::mp::MPPool::mps
std::map< std::string, MPInputOutput > mps
Definition: MPPool.h:111
armarx::control::njoint_controller::task_space::NJointTaskspaceMixedImpedanceVelocityController::ArmPtr
std::unique_ptr< ArmData > ArmPtr
Definition: MixedImpedanceVelocityController.h:100
armarx::control::common::mp::TSMPInputPtr
std::shared_ptr< TSMPInput > TSMPInputPtr
Definition: TSMP.h:46
ARMARX_CHECK_EQUAL
#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...
Definition: ExpressionException.h:130
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
ARMARX_RT_LOGF_WARN
#define ARMARX_RT_LOGF_WARN(...)
Definition: ControlThreadOutputBuffer.h:345
armarx::control::njoint_controller::task_space::NJointTaskspaceMixedImpedanceVelocityController::robotUnit
RobotUnitPtr robotUnit
Definition: MixedImpedanceVelocityController.h:153
armarx::control::njoint_mp_controller::task_space::NJointTSMixedImpedanceVelocityMPController::updateMPConfig
void updateMPConfig(const ::armarx::aron::data::dto::DictPtr &dto, const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition: MixedImpedanceVelocityController.cpp:49
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::control::common::mp::MPPool::isFinished
bool isFinished(const std::string &mpName="all", const Ice::Current &iceCurrent=Ice::emptyCurrent) override
Definition: MPPool.cpp:278