Newer
Older
/*
* This file is part of ArmarX.
*
* Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
*
* ArmarX is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* ArmarX is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package RobotStateComponent::
* @author ( at kit dot edu)
* @date
* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
* GNU General Public License
*/
#include "RobotStateComponent.h"
#include <boost/foreach.hpp>
#include <VirtualRobot/XML/RobotIO.h>
#include <VirtualRobot/Nodes/RobotNode.h>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <ArmarXCore/core/system/ArmarXDataPath.h>
#include <ArmarXCore/core/ArmarXManager.h>
#include <ArmarXCore/core/ArmarXObjectScheduler.h>
#include <ArmarXCore/core/application/Application.h>
using namespace std;
using namespace VirtualRobot;
using namespace Eigen;
using namespace Ice;
using namespace boost;
namespace armarx
{
RobotStateComponent::~RobotStateComponent()
{
if (_synchronizedPrx)
{
_synchronizedPrx->unref();
}
}
void RobotStateComponent::onInitComponent()
{
Mirko Wächter
committed
historyLength = getProperty<int>("HistoryLength").getValue();
history.clear();
Mirko Waechter
committed
relativeRobotFile = getProperty<std::string>("RobotFileName").getValue();
if (!ArmarXDataPath::getAbsolutePath(relativeRobotFile, robotFile))
{
throw UserException("Could not find robot file " + robotFile);
}
this->_synchronized = VirtualRobot::RobotIO::loadRobot(robotFile, VirtualRobot::RobotIO::eStructure);
_synchronized->setName(getProperty<std::string>("AgentName").getValue());
robotModelScaling = getProperty<float>("RobotModelScaling").getValue();
ARMARX_INFO << "scale factor: " << robotModelScaling;
if (robotModelScaling != 1.0f)
{
ARMARX_INFO << "Scaling robot model with scale factor " << robotModelScaling;
_synchronized = _synchronized->clone(_synchronized->getName(), _synchronized->getCollisionChecker(), robotModelScaling);
}
if (this->_synchronized)
{
ARMARX_VERBOSE << "Loaded robot from file " << robotFile << ". Robot name: " << this->_synchronized->getName();
}
else
{
ARMARX_VERBOSE << "Failed loading robot from file " << robotFile;
}
Nikolaus Vahrenkamp
committed
robotNodeSetName = getProperty<std::string>("RobotNodeSetName").getValue();
{
throw UserException("RobotNodeSet not defined");
}
VirtualRobot::RobotNodeSetPtr rns = this->_synchronized->getRobotNodeSet(robotNodeSetName);
throw UserException("RobotNodeSet not defined");
}
vector<RobotNodePtr> nodes = rns->getAllRobotNodes();
ARMARX_VERBOSE << "Using RobotNodeSet " << robotNodeSetName << " with " << nodes.size() << " robot nodes.";
BOOST_FOREACH(RobotNodePtr node, nodes)
{
ARMARX_VERBOSE << "Node: " << node->getName() << endl;
}
usingTopic(robotNodeSetName + "State");
/*VirtualRobot::RobotNodeSetPtr pns = this->_synchronized->getRobotNodeSet("Platform");
if (pns)
{
usingTopic("PlatformState");
vector<RobotNodePtr> nodes = pns->getAllRobotNodes();
ARMARX_VERBOSE << "Using RobotNodeSet Platform with " << nodes.size() << " robot nodes.";
BOOST_FOREACH(RobotNodePtr node, nodes)
{
ARMARX_VERBOSE << "Node: " << node->getName() << endl;
}
_sharedRobotServant = new SharedRobotServant(this->_synchronized);
_sharedRobotServant->ref();
}
void RobotStateComponent::onConnectComponent()
{
this->_synchronizedPrx = SharedRobotInterfacePrx::uncheckedCast(getObjectAdapter()->addWithUUID(_sharedRobotServant));
ARMARX_INFO << "Started RobotStateComponent" << flush;
Mirko Wächter
committed
if (robotStateObs)
{
robotStateObs->setRobot(_synchronized);
}
void RobotStateComponent::onDisconnectComponent()
{
}
SharedRobotInterfacePrx RobotStateComponent::getSynchronizedRobot(const Current& current) const
{
if (!this->_synchronizedPrx)
{
throw NotInitializedException("Shared Robot is NULL", "getSynchronizedRobot");
return this->_synchronizedPrx;
}
SharedRobotInterfacePrx RobotStateComponent::getRobotSnapshot(const string& time, const Current& current)
throw NotInitializedException("Shared Robot is NULL", "getRobotSnapshot");
Mirko Waechter
committed
auto clone = this->_synchronized->clone(_synchronized->getName());
Mirko Wächter
committed
SharedRobotServantPtr p = new SharedRobotServant(clone);
p->setTimestamp(IceUtil::Time::microSeconds(_sharedRobotServant->getTimestamp()->timestamp));
Mirko Waechter
committed
auto result = getObjectAdapter()->addWithUUID(p);
// virtal robot clone is buggy -> set global pose here
p->setGlobalPose(new Pose(_synchronized->getGlobalPose()));
return SharedRobotInterfacePrx::uncheckedCast(result);
Mirko Wächter
committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
SharedRobotInterfacePrx RobotStateComponent::getRobotSnapshotAtTimestamp(Ice::Long time, const Current& current)
{
if (!_synchronized)
{
throw NotInitializedException("Shared Robot is NULL", "getRobotSnapshot");
}
VirtualRobot::RobotPtr clone = this->_synchronized->clone(_synchronized->getName());
RobotStateConfig config;
if (!interpolate(time, config))
{
ARMARX_WARNING << "Could not find or interpolate a robot state for time " << IceUtil::Time::microSeconds(time).toDateTime();
return NULL;
}
clone->setJointValues(config.jointMap);
clone->setGlobalPose(FramedPosePtr::dynamicCast(config.globalPose)->toEigen());
SharedRobotServantPtr p = new SharedRobotServant(clone);
p->setTimestamp(IceUtil::Time::microSeconds(_sharedRobotServant->getTimestamp()->timestamp));
auto result = getObjectAdapter()->addWithUUID(p);
// virtal robot clone is buggy -> set global pose here
p->setGlobalPose(new Pose(_synchronized->getGlobalPose()));
return SharedRobotInterfacePrx::uncheckedCast(result);
}
NameValueMap RobotStateComponent::getJointConfigAtTimestamp(Ice::Long timestamp, const Current&) const
{
RobotStateConfig config;
if (!interpolate(timestamp, config))
{
ARMARX_WARNING << "Could not find or interpolate a robot state for time " << IceUtil::Time::microSeconds(timestamp).toDateTime();
return NameValueMap();
}
return config.jointMap;
}
RobotStateConfig RobotStateComponent::getRobotStateAtTimestamp(Long timestamp, const Current&) const
{
RobotStateConfig config;
if (!interpolate(timestamp, config))
{
ARMARX_WARNING << "Could not find or interpolate a robot state for time " << IceUtil::Time::microSeconds(timestamp).toDateTime();
return RobotStateConfig();
}
return config;
}
bool RobotStateComponent::interpolate(long time, RobotStateConfig& config) const
{
auto it = history.lower_bound(time);
if (time > history.rbegin()->first)
{
config = history.rbegin()->second;
}
else if (it == history.end())
{
return false;
}
else
{
config = it->second;
if (it->first != time)
{
// interpolate
auto prevIt = std::prev(it);
if (prevIt != history.end())
{
long deltaT = it->first - prevIt->first;
float influenceNext = 1.0f - (float)(it->first - time) / deltaT;
float influencePrev = 1.0f - (float)(time - prevIt->first) / deltaT;
auto jointIt = prevIt->second.jointMap.begin();
for (auto& joint : config.jointMap)
Mirko Wächter
committed
{
joint.second = joint.second * influenceNext + jointIt->second * influencePrev;
jointIt++;
}
config.timestamp = time;
ARMARX_CHECK_EXPRESSION(it->second.globalPose);
ARMARX_CHECK_EXPRESSION(prevIt->second.globalPose);
Eigen::Matrix4f globalPoseNext = FramedPosePtr::dynamicCast(it->second.globalPose)->toEigen();
Eigen::Matrix4f globalPosePref = FramedPosePtr::dynamicCast(prevIt->second.globalPose)->toEigen();
Eigen::Quaternionf rotNext(globalPoseNext.block<3, 3>(0, 0));
Eigen::Quaternionf rotPrev(globalPosePref.block<3, 3>(0, 0));
Eigen::Quaternionf rotNew = rotPrev.slerp(influenceNext, rotNext);
Eigen::Matrix4f globalPose;
globalPose.block<3, 3>(0, 0) = rotNew.toRotationMatrix();
globalPose.block<3, 1>(0, 3) = globalPoseNext.block<3, 1>(0, 3) * influenceNext +
globalPosePref.block<3, 1>(0, 3) * influencePrev;
}
}
}
return true;
}
void RobotStateComponent::reportJointAngles(const NameValueMap& jointAngles, Ice::Long timestamp, bool aValueChanged, const Current& c)
if (timestamp <= 0)
{
timestamp = IceUtil::Time::now().toMicroSeconds();
}
WriteLockPtr lock = _synchronized->getWriteLock();
std::vector<float> jv;
std::vector< RobotNodePtr > nodes;
BOOST_FOREACH(NameValueMap::value_type namedAngle, jointAngles)
{
RobotNodePtr node = this->_synchronized->getRobotNode(namedAngle.first);
nodes.push_back(node);
jv.push_back(namedAngle.second);
}
_synchronized->setJointValues(nodes, jv);
robotStateObs->updatePoses();
_sharedRobotServant->setTimestamp(IceUtil::Time::microSeconds(timestamp));
RobotStateConfig config;
config.timestamp = timestamp;
config.globalPose = new FramedPose(_synchronized->getGlobalPose(), GlobalFrame, "");
config.jointMap = jointAngles;
history[timestamp] = config;
Mirko Wächter
committed
if (history.size() > historyLength)
{
history.erase(history.begin());
}
std::string RobotStateComponent::getRobotFilename(const Ice::Current&) const
Mirko Waechter
committed
return relativeRobotFile;
Nikolaus Vahrenkamp
committed
}
float RobotStateComponent::getScaling(const Ice::Current&) const
{
return robotModelScaling;
}
std::vector<string> RobotStateComponent::getArmarXPackages(const Current&) const
Nikolaus Vahrenkamp
committed
{
std::vector<string> result;
auto packages = armarx::Application::GetProjectDependencies();
packages.push_back(Application::GetProjectName());
for (const std::string& projectName : packages)
Nikolaus Vahrenkamp
committed
{
Nikolaus Vahrenkamp
committed
continue;
Nikolaus Vahrenkamp
committed
result.push_back(projectName);
}
return result;
}
void RobotStateComponent::reportControlModeChanged(const NameControlModeMap& jointModes, Ice::Long timestamp, bool aValueChanged, const Current& c) {}
void RobotStateComponent::reportJointVelocities(const NameValueMap& jointVelocities, Ice::Long timestamp, bool aValueChanged, const Current& c)
robotStateObs->updateNodeVelocities(jointVelocities);
void RobotStateComponent::reportJointTorques(const NameValueMap& jointTorques, Ice::Long timestamp, bool aValueChanged, const Current& c) {}
void RobotStateComponent::reportJointAccelerations(const NameValueMap& jointAccelerations, Ice::Long timestamp, bool aValueChanged, const Current& c)
{
}
void RobotStateComponent::reportJointCurrents(const NameValueMap& jointCurrents, Ice::Long timestamp, bool aValueChanged, const Current& c) {}
void RobotStateComponent::reportJointMotorTemperatures(const NameValueMap& jointMotorTemperatures, Ice::Long timestamp, bool aValueChanged, const Current& c) {}
void RobotStateComponent::reportJointStatuses(const NameStatusMap& jointStatuses, Ice::Long timestamp, bool aValueChanged, const Current& c) {}
PropertyDefinitionsPtr RobotStateComponent::createPropertyDefinitions()
{
return PropertyDefinitionsPtr(new RobotStatePropertyDefinitions(
getConfigIdentifier()));
}
void RobotStateComponent::setRobotStateObserver(RobotStateObserverPtr observer)
{
robotStateObs = observer;
string RobotStateComponent::getRobotName(const Current&) const
return _synchronizedPrx->getName();
throw NotInitializedException("Robot Ptr is NULL", "getName");
Nikolaus Vahrenkamp
committed
string RobotStateComponent::getRobotNodeSetName(const Current&) const
{
if (robotNodeSetName.empty())
{
throw NotInitializedException("RobotNodeSetName is empty", "getRobotNodeSetName");
}
return robotNodeSetName;
}