|
From: <is...@us...> - 2009-08-31 02:58:10
|
Revision: 23359
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23359&view=rev
Author: isucan
Date: 2009-08-31 02:58:00 +0000 (Mon, 31 Aug 2009)
Log Message:
-----------
began work on state handling
Modified Paths:
--------------
pkg/trunk/motion_planning/planning_models/CMakeLists.txt
pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_model.h
pkg/trunk/motion_planning/planning_models/src/kinematic_model.cpp
pkg/trunk/motion_planning/planning_models/test/test_kinematic2.cpp
Added Paths:
-----------
pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_state.h
pkg/trunk/motion_planning/planning_models/src/kinematic_state.cpp
Modified: pkg/trunk/motion_planning/planning_models/CMakeLists.txt
===================================================================
--- pkg/trunk/motion_planning/planning_models/CMakeLists.txt 2009-08-31 00:32:46 UTC (rev 23358)
+++ pkg/trunk/motion_planning/planning_models/CMakeLists.txt 2009-08-31 02:58:00 UTC (rev 23359)
@@ -11,7 +11,8 @@
rospack_link_boost(planning_models thread)
-rospack_add_library(planning_models2 src/kinematic_model.cpp)
+rospack_add_library(planning_models2 src/kinematic_model.cpp
+ src/kinematic_state.cpp)
rospack_link_boost(planning_models2 thread)
# Unit tests
Modified: pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_model.h
===================================================================
--- pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_model.h 2009-08-31 00:32:46 UTC (rev 23358)
+++ pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_model.h 2009-08-31 02:58:00 UTC (rev 23359)
@@ -224,7 +224,7 @@
btTransform globalTrans;
/** \brief Recompute globalTrans and globalTransFwd */
- inline void computeTransform(void);
+ void computeTransform(void);
};
@@ -256,7 +256,7 @@
std::vector<std::string> touchLinks;
/** \brief Recompute globalTrans */
- inline void computeTransform(void);
+ void computeTransform(void);
};
@@ -327,6 +327,9 @@
/** \brief Get a group by its name */
const JointGroup* getGroup(const std::string &name) const;
+
+ /** \brief Get a group by its name */
+ JointGroup* getGroup(const std::string &name);
/** \brief Check if a group exists */
bool hasGroup(const std::string &name) const;
@@ -340,6 +343,9 @@
/** \brief Get a link by its name */
const Link* getLink(const std::string &link) const;
+ /** \brief Get a link by its name */
+ Link* getLink(const std::string &link);
+
/** \brief Check if a link exists */
bool hasLink(const std::string &name) const;
@@ -352,6 +358,9 @@
/** \brief Get a joint by its name */
const Joint* getJoint(const std::string &joint) const;
+ /** \brief Get a joint by its name */
+ Joint* getJoint(const std::string &joint);
+
/** \brief Check if a joint exists */
bool hasJoint(const std::string &name) const;
Added: pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_state.h
===================================================================
--- pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_state.h (rev 0)
+++ pkg/trunk/motion_planning/planning_models/include/planning_models/kinematic_state.h 2009-08-31 02:58:00 UTC (rev 23359)
@@ -0,0 +1,221 @@
+/*********************************************************************
+* Software License Agreement (BSD License)
+*
+* Copyright (c) 2008, Willow Garage, Inc.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of the Willow Garage nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*********************************************************************/
+
+/** \author Ioan Sucan */
+
+#ifndef PLANNING_MODELS_KINEMATIC_STATE_
+#define PLANNING_MODELS_KINEMATIC_STATE_
+
+#include "planning_models/kinematic_model.h"
+
+/** \brief Main namespace */
+namespace planning_models
+{
+
+ /** \brief A class that can hold the named parameters of this planning model */
+ class KinematicState
+ {
+ public:
+ KinematicState(const KinematicModel *model);
+ KinematicState(const KinematicState &sp);
+
+ ~KinematicState(void);
+
+ KinematicState &operator=(const KinematicState &rhs);
+
+ bool operator==(const KinematicState &rhs) const;
+
+ /** \brief Construct a default state: each value at 0.0, if
+ within bounds. Otherwise, select middle point. */
+ void defaultState(void);
+
+ /** \brief Construct a random state (within bounds) */
+ void randomState(void);
+
+ /** \brief Construct a random state for a group */
+ void randomStateGroup(const std::string &group);
+
+ /** \brief Construct a random state for a group */
+ void randomStateGroup(const KinematicModel::JointGroup *group);
+
+ /** \brief Perturb state. Each dimension is perturbed by a factor of its range */
+ void perturbState(double factor);
+
+ /** \brief Perturb state of a group. Each dimension is perturbed by a factor of its range */
+ void perturbStateGroup(double factor, const std::string &group);
+
+ /** \brief Perturb state of a group. Each dimension is perturbed by a factor of its range */
+ void perturbStateGroup(double factor, const KinematicModel::JointGroup *group);
+
+ /** \brief Update parameters so that they are within the specified bounds */
+ void enforceBounds(void);
+
+ /** \brief Update parameters so that they are within the specified bounds (for a specific group) */
+ void enforceBoundsGroup(const std::string &group);
+
+ /** \brief Update parameters so that they are within the specified bounds (for a specific group) */
+ void enforceBoundsGroup(const KinematicModel::JointGroup *group);
+
+ /** \brief Mark all values as unseen */
+ void reset(void);
+
+ /** \brief Mark all values in a group as unseen */
+ void resetGroup(const KinematicModel::JointGroup *group);
+
+ /** \brief Mark all values in a group as unseen */
+ void resetGroup(const std::string &group);
+
+ /** \brief Set all the parameters to a given value */
+ void setAll(const double value);
+
+ /** \brief Set all the parameters from a group to a given value */
+ void setAllInGroup(const double value, const std::string &group);
+
+ /** \brief Set all the parameters from a group to a given value */
+ void setAllInGroup(const double value, const KinematicModel::JointGroup *group);
+
+ /** \brief Set the parameters for the complete robot. */
+ bool setParams(const std::vector<double> ¶ms);
+
+ /** \brief Set the parameters for the complete robot. */
+ bool setParams(const double *params);
+
+ /** \brief Set the parameters for a given group. Return true if
+ any change was observed in either of the set
+ values. */
+ bool setParamsGroup(const std::vector<double> ¶ms, const std::string &group);
+
+ /** \brief Set the parameters for a given group. Return true if
+ any change was observed in either of the set
+ values. */
+ bool setParamsGroup(const std::vector<double> ¶ms, const KinematicModel::JointGroup *group);
+
+ /** \brief Set the parameters for a given group. Return true if
+ any change was observed in either of the set
+ values. */
+ bool setParamsGroup(const double *params, const std::string &group);
+
+ /** \brief Set the parameters for a given group. Return true if
+ any change was observed in either of the set
+ values. */
+ bool setParamsGroup(const double *params, const KinematicModel::JointGroup *group);
+
+ /** \brief Given the name of a joint, set the values of the
+ parameters describing the joint. Return true if any
+ change was observed in the set value */
+ bool setParamsJoint(const double *params, const std::string &name);
+
+ /** \brief Given the name of a joint, set the values of the
+ parameters describing the joint. Return true if any
+ change was observed in the set value */
+ bool setParamsJoint(const std::vector<double> ¶ms, const std::string &name);
+
+ /** \brief Given the names of some joints, set the values of the
+ parameters describing the joints. Return true if any
+ change was observed in the set values */
+ bool setParamsJoints(const double *params, const std::vector<std::string> &names);
+
+ /** \brief Given the names of some joints, set the values of the
+ parameters describing the joints. Return true if any
+ change was observed in the set values */
+ bool setParamsJoints(const std::vector<double> ¶ms, const std::vector<std::string> &names);
+
+ /** \brief Given the name of a joint, get the values of the
+ parameters describing the joint. */
+ const double* getParamsJoint(const std::string &name) const;
+
+ /** \brief Return the current value of the params */
+ const double* getParams(void) const;
+
+ /** \brief Copy the parameters for a given group to a destination address */
+ void copyParamsGroup(std::vector<double> ¶ms, const std::string &group) const;
+
+ /** \brief Copy the parameters for a given group to a destination address */
+ void copyParamsGroup(std::vector<double> ¶ms, const KinematicModel::JointGroup *group) const;
+
+ /** \brief Copy the parameters for a given group to a destination address */
+ void copyParamsGroup(double *params, const std::string &group) const;
+
+ /** \brief Copy the parameters for a given group to a destination address */
+ void copyParamsGroup(double *params, const KinematicModel::JointGroup *group) const;
+
+ /** \brief Copy all parameters to a destination address */
+ void copyParams(double *params) const;
+
+ /** \brief Copy all parameters to a destination address */
+ void copyParams(std::vector<double> ¶ms) const;
+
+ /** \brief Copy the parameters describing a given joint */
+ void copyParamsJoint(double *params, const std::string &name) const;
+
+ /** \brief Copy the parameters describing a given joint */
+ void copyParamsJoint(std::vector<double> ¶ms, const std::string &name) const;
+
+ /** \brief Copy the parameters describing a given set of joints */
+ void copyParamsJoints(double *params, const std::vector<std::string> &names) const;
+
+ /** \brief Copy the parameters describing a given set of joints */
+ void copyParamsJoints(std::vector<double> ¶ms, const std::vector<std::string> &names) const;
+
+ /** \brief Check if all params for a joint were seen */
+ bool seenJoint(const std::string &name) const;
+
+ /** \brief Check if all params in a group were seen */
+ bool seenAllGroup(const std::string &group) const;
+
+ /** \brief Check if all params in a group were seen */
+ bool seenAllGroup(const KinematicModel::JointGroup *group) const;
+
+ /** \brief Check if all params were seen */
+ bool seenAll(void) const;
+
+ /** \brief Print the data from the state to screen */
+ void print(std::ostream &out = std::cout) const;
+
+ /** \brief Print the missing joint index values */
+ void missing(std::ostream &out = std::cout);
+
+ protected:
+
+ /** \brief Copy data from another instance of this class */
+ void copyFrom(const KinematicState &sp);
+
+ const KinematicModel *owner_;
+ double *params_;
+ std::vector<bool> seen_;
+ };
+
+}
+
+#endif
Modified: pkg/trunk/motion_planning/planning_models/src/kinematic_model.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/src/kinematic_model.cpp 2009-08-31 00:32:46 UTC (rev 23358)
+++ pkg/trunk/motion_planning/planning_models/src/kinematic_model.cpp 2009-08-31 02:58:00 UTC (rev 23359)
@@ -91,7 +91,7 @@
return modelName_;
}
-unsigned int planning_models::KinematicModel::getDimension(void) const
+inline unsigned int planning_models::KinematicModel::getDimension(void) const
{
return dimension_;
}
@@ -101,12 +101,12 @@
return stateBounds_;
}
-const btTransform& planning_models::KinematicModel::getRootTransform(void) const
+inline const btTransform& planning_models::KinematicModel::getRootTransform(void) const
{
return rootTransform_;
}
-void planning_models::KinematicModel::setRootTransform(const btTransform &transform)
+inline void planning_models::KinematicModel::setRootTransform(const btTransform &transform)
{
rootTransform_ = transform;
}
@@ -121,12 +121,12 @@
return planarJoints_;
}
-void planning_models::KinematicModel::lock(void)
+inline void planning_models::KinematicModel::lock(void)
{
lock_.lock();
}
-void planning_models::KinematicModel::unlock(void)
+inline void planning_models::KinematicModel::unlock(void)
{
lock_.unlock();
}
@@ -176,8 +176,6 @@
planning_models::KinematicModel::Joint* planning_models::KinematicModel::buildRecursive(Link *parent, const urdf::Link *link)
{
- ROS_INFO("%s", link->name.c_str());
-
Joint *joint = constructJoint(link->parent_joint.get(), stateBounds_);
joint->stateIndex = dimension_;
jointMap_[joint->name] = joint;
@@ -196,7 +194,7 @@
if (dynamic_cast<PlanarJoint*>(joint))
planarJoints_.push_back(joint->name);
- for (unsigned int i = 0 ; link->child_links.size() ; ++i)
+ for (unsigned int i = 0 ; i < link->child_links.size() ; ++i)
joint->after->after.push_back(buildRecursive(joint->after, link->child_links[i].get()));
return joint;
@@ -420,6 +418,18 @@
return it->second;
}
+planning_models::KinematicModel::Joint* planning_models::KinematicModel::getJoint(const std::string &name)
+{
+ std::map<std::string, Joint*>::iterator it = jointMap_.find(name);
+ if (it == jointMap_.end())
+ {
+ ROS_ERROR("Joint '%s' not found", name.c_str());
+ return NULL;
+ }
+ else
+ return it->second;
+}
+
const planning_models::KinematicModel::Link* planning_models::KinematicModel::getLink(const std::string &name) const
{
std::map<std::string, Link*>::const_iterator it = linkMap_.find(name);
@@ -432,6 +442,18 @@
return it->second;
}
+planning_models::KinematicModel::Link* planning_models::KinematicModel::getLink(const std::string &name)
+{
+ std::map<std::string, Link*>::iterator it = linkMap_.find(name);
+ if (it == linkMap_.end())
+ {
+ ROS_ERROR("Link '%s' not found", name.c_str());
+ return NULL;
+ }
+ else
+ return it->second;
+}
+
const planning_models::KinematicModel::JointGroup* planning_models::KinematicModel::getGroup(const std::string &name) const
{
std::map<std::string, JointGroup*>::const_iterator it = groupMap_.find(name);
@@ -444,6 +466,18 @@
return it->second;
}
+planning_models::KinematicModel::JointGroup* planning_models::KinematicModel::getGroup(const std::string &name)
+{
+ std::map<std::string, JointGroup*>::iterator it = groupMap_.find(name);
+ if (it == groupMap_.end())
+ {
+ ROS_ERROR("Joint group '%s' not found", name.c_str());
+ return NULL;
+ }
+ else
+ return it->second;
+}
+
void planning_models::KinematicModel::getGroups(std::vector<const JointGroup*> &groups) const
{
groups.clear();
@@ -554,7 +588,7 @@
getJoints(joints);
for (unsigned int i = 0 ; i < joints.size() ; ++i)
{
- printTransform(joints[i]->name, joints[i]->varTrans);
+ printTransform(joints[i]->name, joints[i]->varTrans, out);
out << std::endl;
}
out << "Link poses:" << std::endl;
@@ -562,7 +596,7 @@
getLinks(links);
for (unsigned int i = 0 ; i < links.size() ; ++i)
{
- printTransform(links[i]->name, links[i]->globalTrans);
+ printTransform(links[i]->name, links[i]->globalTrans, out);
out << std::endl;
}
}
@@ -629,7 +663,7 @@
}
-void planning_models::KinematicModel::Link::computeTransform(void)
+inline void planning_models::KinematicModel::Link::computeTransform(void)
{
globalTransFwd.mult(before->before ? before->before->globalTransFwd : owner->getRootTransform(), constTrans);
globalTransFwd *= before->varTrans;
@@ -652,7 +686,7 @@
delete shape;
}
-void planning_models::KinematicModel::AttachedBody::computeTransform(void)
+inline void planning_models::KinematicModel::AttachedBody::computeTransform(void)
{
globalTrans = owner->globalTrans * attachTrans;
}
Added: pkg/trunk/motion_planning/planning_models/src/kinematic_state.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/src/kinematic_state.cpp (rev 0)
+++ pkg/trunk/motion_planning/planning_models/src/kinematic_state.cpp 2009-08-31 02:58:00 UTC (rev 23359)
@@ -0,0 +1,468 @@
+/*********************************************************************
+* Software License Agreement (BSD License)
+*
+* Copyright (c) 2008, Willow Garage, Inc.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following
+* disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of the Willow Garage nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*********************************************************************/
+
+/** \author Ioan Sucan */
+
+#include <planning_models/kinematic_state.h>
+#include <ros/console.h>
+#include <algorithm>
+#include <sstream>
+#include <cmath>
+#include <cstdlib>
+
+planning_models::KinematicState::KinematicState(const KinematicModel *model) : owner_(model)
+{
+ params_ = model->getDimension() > 0 ? new double[model->getDimension()] : NULL;
+ seen_.resize(model->getDimension(), false);
+ defaultState();
+ reset();
+}
+
+planning_models::KinematicState::KinematicState(const KinematicState &sp) : owner_(sp.owner_), params_(NULL)
+{
+ copyFrom(sp);
+}
+
+planning_models::KinematicState::~KinematicState(void)
+{
+ if (params_)
+ delete[] params_;
+}
+
+planning_models::KinematicState& planning_models::KinematicState::operator=(const KinematicState &rhs)
+{
+ if (this != &rhs)
+ copyFrom(rhs);
+ return *this;
+}
+
+bool planning_models::KinematicState::operator==(const KinematicState &rhs) const
+{
+ const unsigned int dim = owner_->getDimension();
+ if (dim != rhs.owner_->getDimension())
+ return false;
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ if (fabs(params_[i] - rhs.params_[i]) > DBL_MIN)
+ return false;
+ return true;
+}
+
+void planning_models::KinematicState::copyFrom(const KinematicState &sp)
+{
+ owner_ = sp.owner_;
+ if (params_)
+ delete[] params_;
+ const unsigned int dim = owner_->getDimension();
+ params_ = dim > 0 ? new double[dim] : NULL;
+ if (params_)
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ params_[i] = sp.params_[i];
+ seen_ = sp.seen_;
+}
+
+void planning_models::KinematicState::defaultState(void)
+{
+ const unsigned int dim = owner_->getDimension();
+ const std::vector<double> &bounds = owner_->getStateBounds();
+
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ {
+ const unsigned int i2 = i << 1;
+ if (bounds[i2] <= 0.0 && bounds[i2 + 1] >= 0.0)
+ params_[i] = 0.0;
+ else
+ params_[i] = (bounds[i2] + bounds[i2 + 1]) / 2.0;
+ seen_[i] = true;
+ }
+}
+
+void planning_models::KinematicState::randomStateGroup(const std::string &group)
+{
+ randomStateGroup(owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::randomStateGroup(const KinematicModel::JointGroup *group)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ {
+ const unsigned int j = group->stateIndex[i];
+ const unsigned int j2 = j << 1;
+ params_[j] = (bounds[j2 + 1] - bounds[j2]) * ((double)rand() / (RAND_MAX + 1.0)) + bounds[j2];
+ seen_[j] = true;
+ }
+}
+
+void planning_models::KinematicState::randomState(void)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ {
+ const unsigned int i2 = i << 1;
+ params_[i] = (bounds[i2 + 1] - bounds[i2]) * ((double)rand() / (RAND_MAX + 1.0)) + bounds[i2];
+ seen_[i] = true;
+ }
+}
+
+void planning_models::KinematicState::perturbStateGroup(double factor, const std::string &group)
+{
+ perturbStateGroup(factor, owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::perturbStateGroup(double factor, const KinematicModel::JointGroup *group)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ {
+ const unsigned int j = group->stateIndex[i];
+ const unsigned int j2 = j << 1;
+ params_[j] += factor * (bounds[j2 + 1] - bounds[j2]) * (2.0 * ((double)rand() / (RAND_MAX + 1.0)) - 1.0);
+ }
+ enforceBoundsGroup(group);
+}
+
+void planning_models::KinematicState::perturbState(double factor)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ {
+ const unsigned int i2 = i << 1;
+ params_[i] += factor * (bounds[i2 + 1] - bounds[i2]) * (2.0 * ((double)rand() / (RAND_MAX + 1.0)) - 1.0);
+ }
+ enforceBounds();
+}
+
+void planning_models::KinematicState::enforceBoundsGroup(const std::string &group)
+{
+ enforceBoundsGroup(owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::enforceBoundsGroup(const KinematicModel::JointGroup *group)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ {
+ const unsigned int j = group->stateIndex[i];
+ const unsigned int j2 = j << 1;
+ if (params_[j] > bounds[j2 + 1])
+ params_[j] = bounds[j2 + 1];
+ else
+ if (params_[j] < bounds[j2])
+ params_[j] = bounds[j2];
+ }
+}
+
+void planning_models::KinematicState::enforceBounds(void)
+{
+ const std::vector<double> &bounds = owner_->getStateBounds();
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ {
+ const unsigned int i2 = i << 1;
+ if (params_[i] > bounds[i2 + 1])
+ params_[i] = bounds[i2 + 1];
+ else
+ if (params_[i] < bounds[i2])
+ params_[i] = bounds[i2];
+ }
+}
+
+void planning_models::KinematicState::reset(void)
+{
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ seen_[i] = false;
+}
+
+void planning_models::KinematicState::resetGroup(const std::string &group)
+{
+ resetGroup(owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::resetGroup(const KinematicModel::JointGroup *group)
+{
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ seen_[group->stateIndex[i]] = false;
+}
+
+bool planning_models::KinematicState::seenAll(void) const
+{
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ if (!seen_[i])
+ return false;
+ return true;
+}
+
+bool planning_models::KinematicState::seenAllGroup(const std::string &group) const
+{
+ return seenAllGroup(owner_->getGroup(group));
+}
+
+bool planning_models::KinematicState::seenAllGroup(const KinematicModel::JointGroup *group) const
+{
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ if (!seen_[group->stateIndex[i]])
+ return false;
+ return true;
+}
+
+bool planning_models::KinematicState::seenJoint(const std::string &name) const
+{
+ const KinematicModel::Joint *joint = owner_->getJoint(name);
+ for (unsigned int i = 0 ; i < joint->usedParams ; ++i)
+ if (!seen_[joint->stateIndex + i])
+ return false;
+ return true;
+}
+
+void planning_models::KinematicState::missing(std::ostream &out)
+{
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ if (!seen_[i])
+ out << i << " ";
+}
+
+const double* planning_models::KinematicState::getParamsJoint(const std::string &name) const
+{
+ const KinematicModel::Joint *joint = owner_->getJoint(name);
+ return params_ + joint->stateIndex;
+}
+
+bool planning_models::KinematicState::setParamsJoints(const double *params, const std::vector<std::string> &names)
+{
+ bool change = false;
+ int u = 0;
+ for (unsigned int i = 0 ; i < names.size() ; ++i)
+ {
+ const KinematicModel::Joint *joint = owner_->getJoint(names[i]);
+ bool ch = setParamsJoint(params + u, names[i]);
+ u += joint->usedParams;
+ change = change || ch;
+ }
+
+ return change;
+}
+
+bool planning_models::KinematicState::setParamsJoints(const std::vector<double> ¶ms, const std::vector<std::string> &names)
+{
+ return setParamsJoints(¶ms[0], names);
+}
+
+bool planning_models::KinematicState::setParamsJoint(const std::vector<double> ¶ms, const std::string &name)
+{
+ return setParamsJoint(¶ms[0], name);
+}
+
+bool planning_models::KinematicState::setParamsJoint(const double *params, const std::string &name)
+{
+ bool result = false;
+ const KinematicModel::Joint *joint = owner_->getJoint(name);
+
+ for (unsigned int i = 0 ; i < joint->usedParams ; ++i)
+ {
+ unsigned int pos_i = joint->stateIndex + i;
+ if (params_[pos_i] != params[i] || !seen_[pos_i])
+ {
+ params_[pos_i] = params[i];
+ seen_[pos_i] = true;
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool planning_models::KinematicState::setParams(const std::vector<double> ¶ms)
+{
+ return setParams(¶ms[0]);
+}
+
+bool planning_models::KinematicState::setParams(const double *params)
+{
+ const unsigned int dim = owner_->getDimension();
+ bool result = false;
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ if (params_[i] != params[i] || !seen_[i])
+ {
+ params_[i] = params[i];
+ seen_[i] = true;
+ result = true;
+ }
+ return result;
+}
+
+bool planning_models::KinematicState::setParamsGroup(const std::vector<double> ¶ms, const std::string &group)
+{
+ return setParamsGroup(¶ms[0], owner_->getGroup(group));
+}
+
+bool planning_models::KinematicState::setParamsGroup(const std::vector<double> ¶ms, const KinematicModel::JointGroup *group)
+{
+ return setParamsGroup(¶ms[0], group);
+}
+
+bool planning_models::KinematicState::setParamsGroup(const double *params, const std::string &group)
+{
+ return setParamsGroup(params, owner_->getGroup(group));
+}
+
+bool planning_models::KinematicState::setParamsGroup(const double *params, const KinematicModel::JointGroup *group)
+{
+ bool result = false;
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ {
+ unsigned int j = group->stateIndex[i];
+ if (params_[j] != params[i] || !seen_[j])
+ {
+ params_[j] = params[i];
+ seen_[j] = true;
+ result = true;
+ }
+ }
+ return result;
+}
+
+void planning_models::KinematicState::setAllInGroup(const double value, const std::string &group)
+{
+ setAllInGroup(value, owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::setAllInGroup(const double value, const KinematicModel::JointGroup *group)
+{
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ {
+ unsigned int j = group->stateIndex[i];
+ params_[j] = value;
+ seen_[j] = true;
+ }
+}
+
+void planning_models::KinematicState::setAll(const double value)
+{
+ const unsigned int dim = owner_->getDimension();
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ {
+ params_[i] = value;
+ seen_[i] = true;
+ }
+}
+
+const double* planning_models::KinematicState::getParams(void) const
+{
+ return params_;
+}
+
+void planning_models::KinematicState::copyParamsJoint(double *params, const std::string &name) const
+{
+ const KinematicModel::Joint *joint = owner_->getJoint(name);
+ std::copy(params_ + joint->stateIndex, params_ + joint->stateIndex + joint->usedParams, params);
+}
+
+void planning_models::KinematicState::copyParamsJoint(std::vector<double> ¶ms, const std::string &name) const
+{
+ const KinematicModel::Joint *joint = owner_->getJoint(name);
+ params.resize(joint->usedParams);
+ std::copy(params_ + joint->stateIndex, params_ + joint->stateIndex + joint->usedParams, params.begin());
+}
+
+void planning_models::KinematicState::copyParams(double *params) const
+{
+ std::copy(params_, params_ + owner_->getDimension(), params);
+}
+
+void planning_models::KinematicState::copyParams(std::vector<double> ¶ms) const
+{
+ params.resize(owner_->getDimension());
+ std::copy(params_, params_ + owner_->getDimension(), params.begin());
+}
+
+void planning_models::KinematicState::copyParamsJoints(std::vector<double> ¶ms, const std::vector<std::string> &names) const
+{
+ params.clear();
+ for (unsigned int j = 0 ; j < names.size() ; ++j)
+ {
+ std::vector<double> p;
+ copyParamsJoint(p, names[j]);
+ params.insert(params.end(), p.begin(), p.end());
+ }
+}
+
+void planning_models::KinematicState::copyParamsGroup(double *params, const std::string &group) const
+{
+ copyParamsGroup(params, owner_->getGroup(group));
+}
+
+void planning_models::KinematicState::copyParamsGroup(std::vector<double> ¶ms, const std::string &group) const
+{
+ const KinematicModel::JointGroup *g = owner_->getGroup(group);
+ params.resize(g->dimension);
+ copyParamsGroup(¶ms[0], g);
+}
+
+void planning_models::KinematicState::copyParamsGroup(std::vector<double> ¶ms, const KinematicModel::JointGroup *group) const
+{
+ params.resize(group->dimension);
+ copyParamsGroup(¶ms[0], group);
+}
+
+void planning_models::KinematicState::copyParamsGroup(double *params, const KinematicModel::JointGroup *group) const
+{
+ for (unsigned int i = 0 ; i < group->dimension ; ++i)
+ params[i] = params_[group->stateIndex[i]];
+}
+
+void planning_models::KinematicState::print(std::ostream &out) const
+{
+ out << std::endl;
+ std::vector<const KinematicModel::Joint*> joints;
+ owner_->getJoints(joints);
+
+ for (unsigned int i = 0 ; i < joints.size() ; ++i)
+ {
+ out << joints[i]->name;
+ if (!seenJoint(joints[i]->name))
+ out << "[ *** UNSEEN *** ]";
+ out << ": ";
+ for (unsigned int j = 0 ; j < joints[i]->usedParams ; ++j)
+ out << params_[joints[i]->stateIndex + j] << std::endl;
+ }
+ out << std::endl;
+ for (unsigned int i = 0; i < owner_->getDimension() ; ++i)
+ out << params_[i] << " ";
+ out << std::endl;
+}
Modified: pkg/trunk/motion_planning/planning_models/test/test_kinematic2.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/test/test_kinematic2.cpp 2009-08-31 00:32:46 UTC (rev 23358)
+++ pkg/trunk/motion_planning/planning_models/test/test_kinematic2.cpp 2009-08-31 02:58:00 UTC (rev 23359)
@@ -182,6 +182,232 @@
delete model;
}
+
+TEST(FK, OneRobot)
+{
+ static const std::string MODEL2 =
+ "<?xml version=\"1.0\" ?>"
+ "<robot name=\"one_robot\">"
+ "<joint name=\"base_joint\" type=\"planar\">"
+ " <parent link=\"world\"/>"
+ " <child link=\"base_link\"/>"
+ " <origin rpy=\" 0.0 -0.2 0 \" xyz=\"1 0 0 \"/>"
+ "</joint>"
+ "<link name=\"base_link\">"
+ " <inertial>"
+ " <mass value=\"2.81\"/>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
+ " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
+ " </inertial>"
+ " <collision name=\"my_collision\">"
+ " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </collision>"
+ " <visual>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </visual>"
+ "</link>"
+ "<joint name=\"joint_a\" type=\"continuous\">"
+ " <axis xyz=\"0 0 1\"/>"
+ " <parent link=\"base_link\"/>"
+ " <child link=\"link_a\"/>"
+ " <origin rpy=\" 0.0 0 0 \" xyz=\"0.0 0 0 \"/>"
+ "</joint>"
+ "<link name=\"link_a\">"
+ " <inertial>"
+ " <mass value=\"1.0\"/>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
+ " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
+ " </inertial>"
+ " <collision>"
+ " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </collision>"
+ " <visual>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </visual>"
+ "</link>"
+ "<joint name=\"joint_b\" type=\"fixed\">"
+ " <parent link=\"link_a\"/>"
+ " <child link=\"link_b\"/>"
+ " <origin rpy=\" 0.0 -0.42 0 \" xyz=\"0.0 0.5 0 \"/>"
+ "</joint>"
+ "<link name=\"link_b\">"
+ " <inertial>"
+ " <mass value=\"1.0\"/>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0.0 .0\"/>"
+ " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
+ " </inertial>"
+ " <collision>"
+ " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </collision>"
+ " <visual>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </visual>"
+ "</link>"
+ " <joint name=\"joint_c\" type=\"prismatic\">"
+ " <axis xyz=\"1 0 0\"/>"
+ " <limit effort=\"100.0\" lower=\"0.0\" upper=\"0.09\" velocity=\"0.2\"/>"
+ " <safety_controller k_position=\"20.0\" k_velocity=\"500.0\" soft_lower_limit=\"0.0\" soft_upper_limit=\"0.089\"/>"
+ " <parent link=\"link_b\"/>"
+ " <child link=\"link_c\"/>"
+ " <origin rpy=\" 0.0 0.42 0.0 \" xyz=\"0.0 -0.1 0 \"/>"
+ " </joint>"
+ "<link name=\"link_c\">"
+ " <inertial>"
+ " <mass value=\"1.0\"/>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0 .0\"/>"
+ " <inertia ixx=\"0.1\" ixy=\"-0.2\" ixz=\"0.5\" iyy=\"-.09\" iyz=\"1\" izz=\"0.101\"/>"
+ " </inertial>"
+ " <collision>"
+ " <origin rpy=\"0 0 0\" xyz=\"0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </collision>"
+ " <visual>"
+ " <origin rpy=\"0 0 0\" xyz=\"0.0 0 0\"/>"
+ " <geometry>"
+ " <box size=\"1 2 1\" />"
+ " </geometry>"
+ " </visual>"
+ "</link>"
+ "</robot>";
+
+ static const std::string MODEL2_INFO =
+ "Number of robots = 1\n"
+ "Complete model state dimension = 5\n"
+ "State bounds: [0.00000, 0.00000] [0.00000, 0.00000] [-3.14159, 3.14159] [-3.14159, 3.14159] [0.01000, 0.38600] \n"
+ "Parameter index:\n"
+ "base_link_joint = 0\n"
+ "link_a_joint = 3\n"
+ "link_c_joint = 4\n"
+ "Parameter name:\n"
+ "0 = base_link_joint\n"
+ "1 = base_link_joint\n"
+ "2 = base_link_joint\n"
+ "3 = link_a_joint\n"
+ "4 = link_c_joint\n"
+ "Floating joints at: \n"
+ "Planar joints at: 0 base_link_joint \n"
+ "Available groups: base \n"
+ "Group base with ID 0 has 1 roots: base_link_joint \n"
+ "The state components for this group are: 0 1 2 3 4 base_link_joint base_link_joint base_link_joint link_a_joint link_c_joint \n";
+
+ urdf::Model urdfModel;
+ urdfModel.initString(MODEL2);
+
+ std::map < std::string, std::vector<std::string> > groups;
+ groups["base"].push_back("base_joint");
+ groups["base"].push_back("joint_a");
+ groups["base"].push_back("joint_b");
+ groups["base"].push_back("joint_c");
+
+ planning_models::KinematicModel *model = new planning_models::KinematicModel(urdfModel, groups);
+
+
+ EXPECT_EQ((unsigned int)5, model->getDimension());
+
+ double param[5] = { 1, 1, 0.5, -0.5, 0.1 };
+ model->getGroup("base")->computeTransforms(param);
+
+ std::stringstream ss1;
+ model->printModelInfo(ss1);
+ // EXPECT_TRUE(sameStringIgnoringWS(MODEL2_INFO, ss1.str()));
+ ROS_INFO("'%s'", ss1.str().c_str());
+
+ // make sure applying the state works for the entire robot
+ model->printTransforms(ss1);
+
+ model->computeTransforms(param);
+
+ std::stringstream ss2;
+ model->printModelInfo(ss2);
+ model->printTransforms(ss2);
+
+ // EXPECT_EQ(ss1.str(), ss2.str());
+
+ EXPECT_NEAR(1.0, model->getLink("base_link")->globalTrans.getOrigin().x(), 1e-5);
+ EXPECT_NEAR(1.0, model->getLink("base_link")->globalTrans.getOrigin().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("base_link")->globalTrans.getOrigin().z(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("base_link")->globalTrans.getRotation().x(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("base_link")->globalTrans.getRotation().y(), 1e-5);
+ EXPECT_NEAR(0.247404, model->getLink("base_link")->globalTrans.getRotation().z(), 1e-5);
+ EXPECT_NEAR(0.968912, model->getLink("base_link")->globalTrans.getRotation().w(), 1e-5);
+
+ EXPECT_NEAR(1.0, model->getLink("link_a")->globalTrans.getOrigin().x(), 1e-5);
+ EXPECT_NEAR(1.0, model->getLink("link_a")->globalTrans.getOrigin().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_a")->globalTrans.getOrigin().z(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_a")->globalTrans.getRotation().x(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_a")->globalTrans.getRotation().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_a")->globalTrans.getRotation().z(), 1e-5);
+ EXPECT_NEAR(1.0, model->getLink("link_a")->globalTrans.getRotation().w(), 1e-5);
+
+ EXPECT_NEAR(1.0, model->getLink("link_b")->globalTrans.getOrigin().x(), 1e-5);
+ EXPECT_NEAR(1.5, model->getLink("link_b")->globalTrans.getOrigin().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_b")->globalTrans.getOrigin().z(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_b")->globalTrans.getRotation().x(), 1e-5);
+ EXPECT_NEAR(-0.20846, model->getLink("link_b")->globalTrans.getRotation().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_b")->globalTrans.getRotation().z(), 1e-5);
+ EXPECT_NEAR(0.978031, model->getLink("link_b")->globalTrans.getRotation().w(), 1e-5);
+
+ EXPECT_NEAR(1.1, model->getLink("link_c")->globalTrans.getOrigin().x(), 1e-5);
+ EXPECT_NEAR(1.4, model->getLink("link_c")->globalTrans.getOrigin().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_c")->globalTrans.getOrigin().z(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_c")->globalTrans.getRotation().x(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_c")->globalTrans.getRotation().y(), 1e-5);
+ EXPECT_NEAR(0.0, model->getLink("link_c")->globalTrans.getRotation().z(), 1e-5);
+ EXPECT_NEAR(1.0, model->getLink("link_c")->globalTrans.getRotation().w(), 1e-5);
+
+ /*
+ planning_models::StateParams *sp = model->newStateParams();
+ EXPECT_FALSE(sp->seenAll());
+
+ double tmpParam[3];
+ tmpParam[0] = 0.1;
+ sp->setParamsJoint(tmpParam, "link_a_joint");
+ EXPECT_FALSE(sp->seenAll());
+ EXPECT_TRUE(sp->seenJoint("link_a_joint"));
+
+ tmpParam[0] = -1.0;
+ sp->setParamsJoint(tmpParam, "link_c_joint");
+ EXPECT_FALSE(sp->seenAll());
+
+ tmpParam[0] = 0.5; tmpParam[1] = 0.4; tmpParam[2] = 1.1;
+ sp->setParamsJoint(tmpParam, "base_link_joint");
+ EXPECT_TRUE(sp->seenAll());
+
+ EXPECT_EQ(0.5, sp->getParams()[0]);
+ EXPECT_EQ(0.4, sp->getParams()[1]);
+ EXPECT_EQ(1.1, sp->getParams()[2]);
+ EXPECT_EQ(0.1, sp->getParams()[3]);
+ EXPECT_EQ(-1.0, sp->getParams()[4]);
+
+ planning_models::StateParams sp_copy = *sp;
+ EXPECT_TRUE(sp_copy == *sp);
+
+ delete sp;
+ */
+ delete model;
+}
+
+
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|