28 const armarx::NJointControllerConfigPtr& config,
32 ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
41 armarx::ControlModes::HolonomicPlatformVelocity)
44 <<
"The actuator " << robotUnit->getRobotPlatformName() <<
" has no control mode "
45 << armarx::ControlModes::HolonomicPlatformVelocity;
50 configBuffer.reinitAllBuffers(configData);
53 const VirtualRobot::RobotNodeSetPtr rnsRight =
54 robot->getRobotNodeSet(configData.
params.nodeSetNameRight);
56 const VirtualRobot::RobotNodeSetPtr rnsLeft =
57 robot->getRobotNodeSet(configData.
params.nodeSetNameLeft);
59 tcpRight = rnsRight->getTCP();
60 tcpLeft = rnsLeft->getTCP();
71 const IceUtil::Time& timeSinceLastIteration)
74 stateBuffer.getWriteBuffer().handPositionRight = tcpRight->getPositionInRootFrame();
75 stateBuffer.getWriteBuffer().handPositionLeft = tcpLeft->getPositionInRootFrame();
77 stateBuffer.getWriteBuffer().currentVel.setZero();
78 stateBuffer.commitWrite();
109 if (not rtReady.load())
119 configBuffer.updateReadBuffer();
120 stateBuffer.updateReadBuffer();
122 const auto state = stateBuffer.getReadBuffer();
123 const auto params = configBuffer.getReadBuffer().params;
125 const double deltaT = (state.time - additionalTaskData.lastTime).toSecondsDouble();
126 additionalTaskData.lastTime = state.time;
131 const Eigen::Vector3f currentVel = state.currentVel;
132 const Eigen::Vector3f currentPositionRight = state.handPositionRight;
133 const Eigen::Vector3f currentPositionLeft = state.handPositionLeft;
134 const Eigen::Vector3f positionDeltaRight =
135 currentPositionRight - initialState.handPositionRight;
136 const Eigen::Vector3f positionDeltaLeft =
137 currentPositionLeft - initialState.handPositionLeft;
139 Eigen::Vector2f positionDelta = ((positionDeltaLeft + positionDeltaRight) / 2).head<2>();
140 Eigen::Vector2f velocity = Eigen::Vector2f::Zero();
141 if (positionDelta.norm() >= params.minPosTolerance)
144 positionDelta - params.minPosTolerance * positionDelta / positionDelta.norm();
145 velocity = positionDelta * params.kPos - currentVel.head<2>() * params.dPos;
147 const float Tstar = 1 / ((params.filterTimeConstant / deltaT) + 1);
148 additionalTaskData.filteredLinearVel =
149 Tstar * (velocity - additionalTaskData.filteredLinearVel) +
150 additionalTaskData.filteredLinearVel;
153 additionalTaskData.filteredLinearVel(0) = 0;
157 additionalTaskData.filteredLinearVel(1) = 0;
159 velocity = additionalTaskData.filteredLinearVel.norm() > params.maxPosVel
160 ? additionalTaskData.filteredLinearVel.normalized() * params.maxPosVel
161 : additionalTaskData.filteredLinearVel;
164 const Eigen::Vector3f currentDirection = state.direction();
165 const float cosAlpha = currentDirection.dot(initialState.direction());
166 const Eigen::Vector3f directionDiff = currentDirection - initialState.direction();
168 if (directionDiff(1) < 0)
170 alpha = -acos(cosAlpha);
174 alpha = acos(cosAlpha);
176 float angularVelocity;
177 if (fabs(alpha) < params.minAngleTolerance)
185 alpha -= params.minAngleTolerance;
189 alpha += params.minAngleTolerance;
191 angularVelocity = params.kAngle * alpha - params.dAngle * currentVel.z();
193 additionalTaskData.filteredAngularVel =
194 Tstar * (angularVelocity - additionalTaskData.filteredAngularVel) +
195 additionalTaskData.filteredAngularVel;
198 additionalTaskData.filteredAngularVel = 0;
200 angularVelocity = std::min(additionalTaskData.filteredAngularVel, params.maxAngleVel);
204 auto& onPublishData = onPublishBuffer.getWriteBuffer();
206 onPublishData.target.platformVelocityTargets.x = velocity.x();
207 onPublishData.target.platformVelocityTargets.y = velocity.y();
208 onPublishData.target.platformVelocityTargets.yaw = angularVelocity;
210 onPublishData.position_error_left = positionDeltaLeft;
211 onPublishData.position_error_right = positionDeltaRight;
212 onPublishBuffer.commitWrite();