|
From: <jfa...@us...> - 2009-02-27 22:34:50
|
Revision: 11904
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11904&view=rev
Author: jfaustwg
Date: 2009-02-27 22:34:45 +0000 (Fri, 27 Feb 2009)
Log Message:
-----------
Add LINE_LIST option for visualization markers.
Modified Paths:
--------------
pkg/trunk/prcore/robot_msgs/msg/VisualizationMarker.msg
pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.cpp
pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.h
pkg/trunk/visualization/rviz/src/rviz/displays/marker_display.cpp
pkg/trunk/visualization/rviz/src/test/marker_test.cpp
Modified: pkg/trunk/prcore/robot_msgs/msg/VisualizationMarker.msg
===================================================================
--- pkg/trunk/prcore/robot_msgs/msg/VisualizationMarker.msg 2009-02-27 22:34:20 UTC (rev 11903)
+++ pkg/trunk/prcore/robot_msgs/msg/VisualizationMarker.msg 2009-02-27 22:34:45 UTC (rev 11904)
@@ -7,8 +7,9 @@
byte CUBE=1
byte SPHERE=2
byte ROBOT=3
-byte LINE_STRIP=4
-byte CYLINDER=5
+byte CYLINDER=4
+byte LINE_STRIP=5
+byte LINE_LIST=6
byte ADD=0
byte MODIFY=0
@@ -31,5 +32,5 @@
int32 r # red color value (0-255) (if available)
int32 g # green color value
int32 b # blue color value
-#These are only used if the object type is LINE_STRIP
+#These are only used if the object type is LINE_STRIP or LINE_LIST
Point[] points
Modified: pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.cpp
===================================================================
--- pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.cpp 2009-02-27 22:34:20 UTC (rev 11903)
+++ pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.cpp 2009-02-27 22:34:45 UTC (rev 11904)
@@ -38,12 +38,15 @@
#include <sstream>
+#include <ros/assert.h>
+
namespace ogre_tools
{
BillboardLine::BillboardLine( Ogre::SceneManager* scene_manager, Ogre::SceneNode* parent_node )
: Object( scene_manager )
, width_( 0.1f )
+, current_line_(0)
{
if ( !parent_node )
{
@@ -56,8 +59,8 @@
static int count = 0;
ss << "BillboardLine chain" << count++;
chain_ = scene_manager_->createBillboardChain(ss.str());
- chain_->setNumberOfChains(1);
- chain_->setMaxChainElements(1000);
+ setNumLines(1);
+ setMaxPointsPerLine(100);
scene_node_->attachObject( chain_ );
@@ -77,24 +80,43 @@
void BillboardLine::clear()
{
- points_.clear();
- chain_->clearChain(0);
+ chain_->clearAllChains();
+ current_line_ = 0;
+
+ for (V_uint32::iterator it = num_elements_.begin(); it != num_elements_.end(); ++it)
+ {
+ *it = 0;
+ }
}
+void BillboardLine::setMaxPointsPerLine(uint32_t max)
+{
+ chain_->setMaxChainElements(max);
+}
+
+void BillboardLine::setNumLines(uint32_t num)
+{
+ chain_->setNumberOfChains(num);
+ num_elements_.resize(num);
+}
+
+void BillboardLine::newLine()
+{
+ ++current_line_;
+
+ ROS_ASSERT(current_line_ < chain_->getNumberOfChains());
+}
+
void BillboardLine::addPoint( const Ogre::Vector3& point )
{
- points_.push_back( point );
+ ++num_elements_[current_line_];
+ ROS_ASSERT(num_elements_[current_line_] <= (chain_->getMaxChainElements() * (current_line_+1)));
- if ( points_.size() > chain_->getMaxChainElements() )
- {
- chain_->setMaxChainElements( chain_->getMaxChainElements() * 2 );
- }
-
Ogre::BillboardChain::Element e;
e.position = point;
e.width = width_;
e.colour = color_;
- chain_->addChainElement(0, e);
+ chain_->addChainElement(current_line_, e);
}
void BillboardLine::setPoints( const V_Vector3& points )
@@ -112,10 +134,20 @@
void BillboardLine::setLineWidth( float width )
{
width_ = width;
- V_Vector3 points;
- points.swap( points_ );
- setPoints( points );
+ uint32_t num_chains = chain_->getNumberOfChains();
+ for (uint32_t chain = 0; chain < num_chains; ++chain)
+ {
+ uint32_t element_count = num_elements_[chain];
+
+ for ( uint32_t i = 0; i < element_count; ++i )
+ {
+ Ogre::BillboardChain::Element e = chain_->getChainElement(chain, i);
+
+ e.width = width_;
+ chain_->updateChainElement(chain, i, e);
+ }
+ }
}
void BillboardLine::setPosition( const Ogre::Vector3& position )
@@ -148,13 +180,18 @@
color_ = Ogre::ColourValue( r, g, b, a );
- uint32_t element_count = points_.size();
- for ( uint32_t i = 0; i < element_count; ++i )
+ uint32_t num_chains = chain_->getNumberOfChains();
+ for (uint32_t chain = 0; chain < num_chains; ++chain)
{
- Ogre::BillboardChain::Element e = chain_->getChainElement(0, i);
+ uint32_t element_count = num_elements_[chain];
- e.colour = color_;
- chain_->updateChainElement(0, i, e);
+ for ( uint32_t i = 0; i < element_count; ++i )
+ {
+ Ogre::BillboardChain::Element e = chain_->getChainElement(chain, i);
+
+ e.colour = color_;
+ chain_->updateChainElement(chain, i, e);
+ }
}
}
Modified: pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.h
===================================================================
--- pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.h 2009-02-27 22:34:20 UTC (rev 11903)
+++ pkg/trunk/visualization/ogre_tools/src/ogre_tools/billboard_line.h 2009-02-27 22:34:45 UTC (rev 11904)
@@ -67,6 +67,7 @@
virtual ~BillboardLine();
void clear();
+ void newLine();
void addPoint(const Ogre::Vector3& point);
typedef std::vector<Ogre::Vector3> V_Vector3;
@@ -74,6 +75,9 @@
void setLineWidth( float width );
+ void setMaxPointsPerLine(uint32_t max);
+ void setNumLines(uint32_t num);
+
// overrides from Object
virtual void setOrientation( const Ogre::Quaternion& orientation );
virtual void setPosition( const Ogre::Vector3& position );
@@ -98,9 +102,14 @@
Ogre::BillboardChain* chain_;
Ogre::MaterialPtr material_;
- V_Vector3 points_;
Ogre::ColourValue color_;
float width_;
+
+ int current_line_;
+
+ // Ogre 1.4 doesn't have getNumChainElements()
+ typedef std::vector<uint32_t> V_uint32;
+ V_uint32 num_elements_;
};
} // namespace ogre_tools
Modified: pkg/trunk/visualization/rviz/src/rviz/displays/marker_display.cpp
===================================================================
--- pkg/trunk/visualization/rviz/src/rviz/displays/marker_display.cpp 2009-02-27 22:34:20 UTC (rev 11903)
+++ pkg/trunk/visualization/rviz/src/rviz/displays/marker_display.cpp 2009-02-27 22:34:45 UTC (rev 11904)
@@ -61,7 +61,7 @@
kinematic_model_ = new planning_models::KinematicModel();
kinematic_model_->setVerbose( false );
- notifier_ = new tf::MessageNotifier<robot_msgs::VisualizationMarker>(tf_, ros_node_, boost::bind(&MarkerDisplay::incomingMarker, this, _1), "", "", 100);
+ notifier_ = new tf::MessageNotifier<robot_msgs::VisualizationMarker>(tf_, ros_node_, boost::bind(&MarkerDisplay::incomingMarker, this, _1), "", "", 1000);
}
MarkerDisplay::~MarkerDisplay()
@@ -236,6 +236,12 @@
object = line;
}
break;
+ case robot_msgs::VisualizationMarker::LINE_LIST:
+ {
+ ogre_tools::BillboardLine* line = new ogre_tools::BillboardLine( scene_manager_, scene_node_ );
+ object = line;
+ }
+ break;
default:
ROS_ERROR( "Unknown marker type: %d\n", message->type );
}
@@ -311,6 +317,7 @@
line->clear();
line->setLineWidth( message->xScale );
+ line->setMaxPointsPerLine(message->points.size());
std::vector<robot_msgs::Point>::iterator it = message->points.begin();
std::vector<robot_msgs::Point>::iterator end = message->points.end();
@@ -324,6 +331,45 @@
line->addPoint( v );
}
}
+ else if ( message->type == robot_msgs::VisualizationMarker::LINE_LIST )
+ {
+ if (message->points.size() % 2 == 0)
+ {
+ ogre_tools::BillboardLine* line = dynamic_cast<ogre_tools::BillboardLine*>(object);
+ ROS_ASSERT( line );
+
+ line->clear();
+ line->setLineWidth( message->xScale );
+ line->setMaxPointsPerLine(2);
+ line->setNumLines(message->points.size() / 2);
+
+ std::vector<robot_msgs::Point>::iterator it = message->points.begin();
+ std::vector<robot_msgs::Point>::iterator end = message->points.end();
+ for ( ; it != end; ++it )
+ {
+ if (it != message->points.begin())
+ {
+ line->newLine();
+ }
+
+ robot_msgs::Point& p = *it;
+ ++it;
+ robot_msgs::Point& p2 = *it;
+
+ Ogre::Vector3 v( p.x, p.y, p.z );
+ robotToOgre( v );
+ line->addPoint( v );
+
+ v = Ogre::Vector3( p2.x, p2.y, p2.z );
+ robotToOgre( v );
+ line->addPoint( v );
+ }
+ }
+ else
+ {
+ ROS_ERROR("Marker [%d] with type LINE_LIST has an odd number of points", message->id);
+ }
+ }
}
void MarkerDisplay::update( float dt )
Modified: pkg/trunk/visualization/rviz/src/test/marker_test.cpp
===================================================================
--- pkg/trunk/visualization/rviz/src/test/marker_test.cpp 2009-02-27 22:34:20 UTC (rev 11903)
+++ pkg/trunk/visualization/rviz/src/test/marker_test.cpp 2009-02-27 22:34:45 UTC (rev 11904)
@@ -17,6 +17,7 @@
usleep( 1000000 );
+#if 0
for ( int i = -50; i < 50; ++i )
{
robot_msgs::VisualizationMarker marker;
@@ -41,10 +42,44 @@
node->publish( "visualizationMarker", marker );
}
+#endif
+
+ int count = 10000;
+ robot_msgs::VisualizationMarker marker;
+ marker.header.frame_id = "map";
+ marker.header.stamp = ros::Time();
+ marker.id = 0;
+ marker.type = robot_msgs::VisualizationMarker::LINE_LIST;
+ marker.action = robot_msgs::VisualizationMarker::ADD;
+ marker.x = 0;
+ marker.y = 0;
+ marker.z = 0;
+ marker.yaw = 0.0;
+ marker.pitch = 0.0;
+ marker.roll = 0.0;
+ marker.xScale = 0.1;
+ marker.alpha = 255;
+ marker.r = 255;
+ marker.g = 0;
+ marker.b = 0;
+ for ( int i = 0; i < count; ++i )
+ {
+ robot_msgs::Point p1, p2;
+ p1.x = -1;
+ p1.y = (i - count/2);
+ p1.z = 1;
+ p2.x = -1;
+ p2.y = (i - count/2);
+ p2.z = 2;
+ marker.points.push_back(p1);
+ marker.points.push_back(p2);
+ }
+ node->publish( "visualizationMarker", marker );
+
robot_msgs::VisualizationMarker line_marker;
line_marker.header.frame_id = "map";
line_marker.header.stamp = ros::Time();
- line_marker.id = 1000;
+ line_marker.id = count + 1;
line_marker.type = robot_msgs::VisualizationMarker::LINE_STRIP;
line_marker.action = 0;
line_marker.x = 0;
@@ -74,5 +109,5 @@
node->shutdown();
delete node;
-
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <is...@us...> - 2009-02-28 02:32:03
|
Revision: 11934
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11934&view=rev
Author: isucan
Date: 2009-02-28 02:03:10 +0000 (Sat, 28 Feb 2009)
Log Message:
-----------
testing state validity
Modified Paths:
--------------
pkg/trunk/motion_planning/kinematic_planning/src/motion_validator.cpp
pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicPath.srv
Added Paths:
-----------
pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicState.srv
Modified: pkg/trunk/motion_planning/kinematic_planning/src/motion_validator.cpp
===================================================================
--- pkg/trunk/motion_planning/kinematic_planning/src/motion_validator.cpp 2009-02-28 02:02:07 UTC (rev 11933)
+++ pkg/trunk/motion_planning/kinematic_planning/src/motion_validator.cpp 2009-02-28 02:03:10 UTC (rev 11934)
@@ -74,9 +74,9 @@
- None
Provides (name/type):
-- @b "validate_path"/ValidateKinematicPath : given a robot model, starting and goal states, this service computes whether the straight path is valid
+- @b "validate_direct_path"/ValidateKinematicPath : given a robot model, starting and goal states, this service computes whether the straight path is valid
+- @b "validate_state"/ValidateKinematicState : given a robot model and a state, this service computes whether the state is valid
-
<hr>
@section parameters ROS parameters
@@ -88,6 +88,7 @@
#include <ompl/extension/samplingbased/kinematic/SpaceInformationKinematic.h>
#include <robot_srvs/ValidateKinematicPath.h>
+#include <robot_srvs/ValidateKinematicState.h>
#include "kinematic_planning/ompl_extensions/RKPStateValidator.h"
#include "kinematic_planning/ompl_extensions/RKPSpaceInformation.h"
@@ -98,8 +99,7 @@
#include <map>
using namespace kinematic_planning;
-class MotionValidator : public ros::Node,
- public CollisionSpaceMonitor
+class MotionValidator : public CollisionSpaceMonitor
{
public:
@@ -124,10 +124,11 @@
ompl::SpaceInformation::StateValidityChecker_t svc;
};
- MotionValidator(void) : ros::Node("motion_validator"),
- CollisionSpaceMonitor(dynamic_cast<ros::Node*>(this))
+ MotionValidator(ros::Node *node) : CollisionSpaceMonitor(node)
{
- advertiseService("validate_path", &MotionValidator::validatePath);
+ m_node = node;
+ m_node->advertiseService("validate_direct_path", &MotionValidator::validatePath, this);
+ m_node->advertiseService("validate_state", &MotionValidator::validateState, this);
}
/** Free the memory */
@@ -137,6 +138,61 @@
delete i->second;
}
+ bool validateState(robot_srvs::ValidateKinematicState::Request &req, robot_srvs::ValidateKinematicState::Response &res)
+ {
+ myModel *model = m_models[req.model_id];
+ if (model)
+ {
+ if (model->kmodel->getModelInfo().stateDimension != req.state.get_vals_size() &&
+ model->si->getStateDimension() != req.state.get_vals_size())
+ {
+ ROS_ERROR("Dimension of state expected to be %d or %d but was received as %d",
+ model->kmodel->getModelInfo().stateDimension, model->si->getStateDimension(),
+ req.state.get_vals_size());
+ return false;
+ }
+
+ const unsigned int dim = model->si->getStateDimension();
+ ompl::SpaceInformationKinematic::StateKinematic_t state = new ompl::SpaceInformationKinematic::StateKinematic(dim);
+
+ if (model->groupID >= 0)
+ {
+ /* set the pose of the whole robot to the current state */
+ model->kmodel->computeTransforms(m_robotState->getParams());
+ model->collisionSpace->updateRobotModel(model->collisionSpaceID);
+
+ /* extract the components needed for the start state of the desired group */
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ state->values[i] = req.state.vals[model->kmodel->getModelInfo().groupStateIndexList[model->groupID][i]];
+ }
+ else
+ {
+ /* the start state is the complete state */
+ for (unsigned int i = 0 ; i < dim ; ++i)
+ state->values[i] = req.state.vals[i];
+ }
+
+ std::vector<robot_msgs::PoseConstraint> cstrs;
+ req.constraints.get_pose_vec(cstrs);
+ static_cast<StateValidityPredicate*>(model->svc)->setPoseConstraints(cstrs);
+
+ ROS_INFO("Validating state for '%s'...", req.model_id.c_str());
+
+ res.valid = model->si->isValid(state) ? 1 : 0;
+
+ ROS_INFO("Result: %d", (int)res.valid);
+
+ delete state;
+
+ return true;
+ }
+ else
+ {
+ ROS_ERROR("Model '%s' not known", req.model_id.c_str());
+ return false;
+ }
+ }
+
bool validatePath(robot_srvs::ValidateKinematicPath::Request &req, robot_srvs::ValidateKinematicPath::Response &res)
{
myModel *model = m_models[req.model_id];
@@ -184,7 +240,7 @@
req.constraints.get_pose_vec(cstrs);
static_cast<StateValidityPredicate*>(model->svc)->setPoseConstraints(cstrs);
- res.valid = model->si->checkMotionIncremental(start, goal);
+ res.valid = model->si->checkMotionIncremental(start, goal) ? 1 : 0;
ROS_INFO("Result: %d", (int)res.valid);
@@ -254,7 +310,7 @@
}
std::map<std::string, myModel*> m_models;
-
+ ros::Node *m_node;
};
@@ -262,7 +318,8 @@
{
ros::init(argc, argv);
- MotionValidator *validator = new MotionValidator();
+ ros::Node *node = new ros::Node("motion_validator");
+ MotionValidator *validator = new MotionValidator(node);
validator->loadRobotDescription();
std::vector<std::string> mlist;
@@ -271,13 +328,14 @@
for (unsigned int i = 0 ; i < mlist.size() ; ++i)
ROS_INFO(" * %s", mlist[i].c_str());
if (mlist.size() > 0)
- validator->spin();
+ node->spin();
else
ROS_ERROR("No models defined. Path validation node cannot start.");
- validator->shutdown();
+ node->shutdown();
delete validator;
-
+ delete node;
+
return 0;
}
Modified: pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicPath.srv
===================================================================
--- pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicPath.srv 2009-02-28 02:02:07 UTC (rev 11933)
+++ pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicPath.srv 2009-02-28 02:03:10 UTC (rev 11934)
@@ -4,7 +4,7 @@
# The model to validate for
string model_id
-# The starting state for the robot. This is eth complete state of the
+# The starting state for the robot. This is the complete state of the
# robot, all joint values, everything that needs to be specified to
# completely define where each part of the robot is in space. The
# meaning for each element in the state vector can be extracted from
Added: pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicState.srv
===================================================================
--- pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicState.srv (rev 0)
+++ pkg/trunk/prcore/robot_srvs/srv/ValidateKinematicState.srv 2009-02-28 02:03:10 UTC (rev 11934)
@@ -0,0 +1,26 @@
+# This message contains the definition for a request to the state
+# validator
+
+# The model to validate for
+string model_id
+
+# The starting state for the robot. This is either the complete state
+# of the robot, all joint values, everything that needs to be
+# specified to completely define where each part of the robot is in
+# space, or the state of the model. If only the state for the model is
+# specified, the rest of the values are taken from the robot's current
+# state.
+# The meaning for each element in the state vector can be
+# extracted from viewing the output of the robot model construction
+# (the kinematic model constructed from the parsed URDF model) in
+# verbose mode
+robot_msgs/KinematicState state
+
+
+# No state in the produced motion plan will violate these constraints
+robot_msgs/KinematicConstraints constraints
+
+---
+
+# Return true or false, to say if state is valid or not.
+byte valid
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-02-28 02:32:04
|
Revision: 11937
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11937&view=rev
Author: tfoote
Date: 2009-02-28 02:29:24 +0000 (Sat, 28 Feb 2009)
Log Message:
-----------
pulling transformations inside of tf in preperation for working on pytf
Modified Paths:
--------------
pkg/trunk/demos/test_2dnav_gazebo/manifest.xml
pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/manifest.xml
pkg/trunk/prcore/tf/manifest.xml
pkg/trunk/vision/visual_odometry/manifest.xml
pkg/trunk/vision/vslam/manifest.xml
Added Paths:
-----------
pkg/trunk/prcore/tf/src/transformations.py
Removed Paths:
-------------
pkg/trunk/3rdparty/transformations/
Modified: pkg/trunk/demos/test_2dnav_gazebo/manifest.xml
===================================================================
--- pkg/trunk/demos/test_2dnav_gazebo/manifest.xml 2009-02-28 02:19:27 UTC (rev 11936)
+++ pkg/trunk/demos/test_2dnav_gazebo/manifest.xml 2009-02-28 02:29:24 UTC (rev 11937)
@@ -19,7 +19,7 @@
<depend package="robot_pose_ekf"/>
<depend package="pr2_gazebo"/>
<depend package="pr2_prototype1_gazebo"/>
- <depend package="transformations"/>
+ <depend package="tf"/>
<depend package="point_cloud_assembler"/>
<depend package="std_msgs"/>
<depend package="robot_msgs"/>
Modified: pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/manifest.xml
===================================================================
--- pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/manifest.xml 2009-02-28 02:19:27 UTC (rev 11936)
+++ pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/manifest.xml 2009-02-28 02:29:24 UTC (rev 11937)
@@ -14,5 +14,5 @@
<depend package="deprecated_msgs" />
<depend package="robot_msgs" />
<depend package="std_msgs" />
- <depend package="transformations" />
+ <depend package="tf" />
</package>
Modified: pkg/trunk/prcore/tf/manifest.xml
===================================================================
--- pkg/trunk/prcore/tf/manifest.xml 2009-02-28 02:19:27 UTC (rev 11936)
+++ pkg/trunk/prcore/tf/manifest.xml 2009-02-28 02:29:24 UTC (rev 11937)
@@ -13,6 +13,7 @@
<depend package="rosconsole"/>
<depend package="bullet"/>
<depend package="rospy"/>
+<depend package="numpy"/>
<export>
<cpp cflags="-I${prefix}/include -I${prefix}/msg/cpp -I${prefix}/srv/cpp `rosboost-cfg --cflags`" lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -ltf `rosboost-cfg --lflags thread`"/>
</export>
Copied: pkg/trunk/prcore/tf/src/transformations.py (from rev 6928, pkg/trunk/3rdparty/transformations/src/transformations.py)
===================================================================
--- pkg/trunk/prcore/tf/src/transformations.py (rev 0)
+++ pkg/trunk/prcore/tf/src/transformations.py 2009-02-28 02:29:24 UTC (rev 11937)
@@ -0,0 +1,647 @@
+# -*- coding: utf-8 -*-
+# transformations.py
+
+# Copyright (c) 2006-2007, Christoph Gohlke
+# Copyright (c) 2006-2007, The Regents of the University of California
+# 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 copyright holders nor the names of any
+# 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.
+
+# Source: http://lfd.uci.edu/~gohlke/code/transformations.py.html
+
+"""Homogeneous Transformation Matrices and Quaternions.
+
+Functions for calculating 4x4 matrices for translating, rotating, mirroring,
+scaling, projecting, orthogonalization, and superimposition of arrays of
+homogenous coordinates as well as for converting between rotation matrices,
+Euler angles, and quaternions.
+
+Matrices can be inverted using numpy.linalg.inv(M), concatenated using
+numpy.dot(M0,M1), or used to transform homogeneous points using
+numpy.dot(v, M) for shape (4,*) "point of arrays", respectively
+numpy.dot(v, M.T) for shape (*,4) "array of points".
+
+Quaternions ix+jy+kz+w are represented as [x, y, z, w].
+
+Angles are in radians unless specified otherwise.
+
+The 24 ways of specifying rotations for a given triple of Euler angles,
+can be represented by a 4 character string or encoded 4-tuple:
+
+ Axes 4-string:
+ first character -- rotations are applied to 's'tatic or 'r'otating frame
+ remaining characters -- successive rotation axis 'x', 'y', or 'z'
+ Axes 4-tuple:
+ inner axis -- code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix.
+ parity -- even (0) if inner axis 'x' is followed by 'y', 'y' is followed
+ by 'z', or 'z' is followed by 'x'. Otherwise odd (1).
+ repetition -- first and last axis are same (1) or different (0).
+ frame -- rotations are applied to static (0) or rotating (1) frame.
+ Examples of tuple codes:
+ 'sxyz' <-> (0, 0, 0, 0)
+ 'ryxy' <-> (1, 1, 1, 1)
+
+Author:
+ Christoph Gohlke, http://www.lfd.uci.edu/~gohlke/
+ Laboratory for Fluorescence Dynamics, University of California, Irvine
+
+Requirements:
+ Python 2.5 (http://www.python.org)
+ Numpy 1.0 (http://numpy.scipy.org)
+
+References:
+(1) Matrices and Transformations. Ronald Goldman.
+ In "Graphics Gems I", pp 472-475. Morgan Kaufmann, 1990.
+(2) Euler Angle Conversion. Ken Shoemake.
+ In "Graphics Gems IV", pp 222-229. Morgan Kaufmann, 1994.
+(3) Arcball Rotation Control. Ken Shoemake.
+ In "Graphics Gems IV", pp 175-192. Morgan Kaufmann, 1994.
+
+"""
+
+from __future__ import division
+
+import math
+import numpy
+
+_EPS = numpy.finfo(float).eps * 4.0
+
+def concatenate_transforms(*args):
+ """Merge multiple transformation matrices into one."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ for i in args:
+ M = numpy.dot(M, i)
+ return M
+
+def translation_matrix(direction):
+ """Return matrix to translate by direction vector."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,3] = direction[0:3]
+ return M
+
+def mirror_matrix(point, normal):
+ """Return matrix to mirror at plane defined by point and normal vector."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ n = numpy.array(normal[0:3], dtype=numpy.float64, copy=True)
+ n /= math.sqrt(numpy.dot(n,n))
+ M[0:3,0:3] -= 2.0 * numpy.outer(n, n)
+ M[0:3,3] = 2.0 * numpy.dot(point[0:3], n) * n
+ return M
+
+def rotation_matrix(angle, direction, point=None):
+ """Return matrix to rotate about axis defined by point and direction."""
+ sa, ca = math.sin(angle), math.cos(angle)
+ # unit vector of direction
+ u = numpy.array(direction[0:3], dtype=numpy.float64, copy=True)
+ u /= math.sqrt(numpy.dot(u, u))
+ # rotation matrix around unit vector
+ R = numpy.identity(3, dtype=numpy.float64)
+ R *= ca
+ R += numpy.outer(u, u) * (1.0 - ca)
+ R += sa * numpy.array((( 0.0,-u[2], u[1]),
+ ( u[2], 0.0,-u[0]),
+ (-u[1], u[0], 0.0)), dtype=numpy.float64)
+ M = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,0:3] = R
+ if point is not None:
+ # rotation not around origin
+ M[0:3,3] = point[0:3] - numpy.dot(R, point[0:3])
+ return M
+
+def scaling_matrix(factor, origin=None, direction=None):
+ """Return matrix to scale by factor around origin in direction.
+
+ Point Symmetry: factor = -1.0
+
+ """
+ if origin is None: origin = [0,0,0]
+ o = numpy.array(origin[0:3], dtype=numpy.float64, copy=False)
+ if direction is None:
+ # uniform scaling
+ M = factor*numpy.identity(4, dtype=numpy.float64)
+ M[0:3,3] = (1.0-factor) * o
+ M[3,3] = 1.0
+ else:
+ # nonuniform scaling
+ M = numpy.identity(4, dtype=numpy.float64)
+ u = numpy.array(direction[0:3], dtype=numpy.float64, copy=True)
+ u /= math.sqrt(numpy.dot(u, u)) # unit vector of direction
+ M[0:3,0:3] -= (1.0-factor) * numpy.outer(u, u)
+ M[0:3,3] = ((1.0-factor) * numpy.dot(o, u)) * u
+ return M
+
+def projection_matrix(point, normal, direction=None, perspective=None):
+ """Return matrix to project onto plane defined by point and normal.
+
+ Using either perspective point, projection direction, or none of both.
+
+ """
+ M = numpy.identity(4, dtype=numpy.float64)
+ n = numpy.array(normal[0:3], dtype=numpy.float64, copy=True)
+ n /= math.sqrt(numpy.dot(n,n)) # unit vector of normal
+ if perspective is not None:
+ # perspective projection
+ r = numpy.array(perspective[0:3], dtype=numpy.float64)
+ M[0:3,0:3] *= numpy.dot((r-point), n)
+ M[0:3,0:3] -= numpy.outer(n, r)
+ M[0:3,3] = numpy.dot(point, n) * r
+ M[3,0:3] = -n
+ M[3,3] = numpy.dot(perspective, n)
+ elif direction is not None:
+ # parallel projection
+ w = numpy.array(direction[0:3], dtype=numpy.float64)
+ s = 1.0 / numpy.dot(w, n)
+ M[0:3,0:3] -= numpy.outer(n, w) * s
+ M[0:3,3] = w * (numpy.dot(point[0:3], n) * s)
+ else:
+ # orthogonal projection
+ M[0:3,0:3] -= numpy.outer(n, n)
+ M[0:3,3] = numpy.dot(point[0:3], n) * n
+ return M
+
+def orthogonalization_matrix(a=10.0, b=10.0, c=10.0,
+ alpha=90.0, beta=90.0, gamma=90.0):
+ """Return orthogonalization matrix for crystallographic cell coordinates.
+
+ Angles are in degrees.
+
+ """
+ al = math.radians(alpha)
+ be = math.radians(beta)
+ ga = math.radians(gamma)
+ sia = math.sin(al)
+ sib = math.sin(be)
+ coa = math.cos(al)
+ cob = math.cos(be)
+ co = (coa * cob - math.cos(ga)) / (sia * sib)
+ return numpy.array((
+ (a*sib*math.sqrt(1.0-co*co), 0.0, 0.0, 0.0),
+ (-a*sib*co, b*sia, 0.0, 0.0),
+ (a*cob, b*coa, c, 0.0),
+ (0.0, 0.0, 0.0, 1.0)),
+ dtype=numpy.float64)
+
+def superimpose_matrix(v0, v1, compute_rmsd=False):
+ """Return matrix to transform given vector set into second vector set.
+
+ Minimize weighted sum of squared deviations according to W. Kabsch.
+ v0 and v1 are shape (*,3) or (*,4) arrays of at least 3 vectors.
+
+ """
+ v0 = numpy.array(v0, dtype=numpy.float64)
+ v1 = numpy.array(v1, dtype=numpy.float64)
+
+ assert v0.ndim==2 and v0.ndim==v1.ndim and \
+ v0.shape[0]>2 and v0.shape[1] in (3,4)
+
+ # vectors might be homogeneous coordinates
+ if v0.shape[1] == 4:
+ v0 = v0[:,0:3]
+ v1 = v1[:,0:3]
+
+ # move centroids to origin
+ t0 = numpy.mean(v0, axis=0)
+ t1 = numpy.mean(v1, axis=0)
+ v0 = v0 - t0
+ v1 = v1 - t1
+
+ # Singular Value Decomposition of covariance matrix
+ u, s, vh = numpy.linalg.svd(numpy.dot(v1.T, v0))
+
+ # rotation matrix from SVD orthonormal bases
+ R = numpy.dot(u, vh)
+ if numpy.linalg.det(R) < 0.0:
+ # R does not constitute right handed system
+ rc = vh[2,:] * 2.0
+ R -= numpy.vstack((u[0,2]*rc, u[1,2]*rc, u[2,2]*rc))
+ s[-1] *= -1.0
+
+ # homogeneous transformation matrix
+ M = numpy.identity(4, dtype=numpy.float64)
+ T = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,0:3] = R
+ T[0:3,3] = t1
+ M = numpy.dot(T, M)
+ T[0:3,3] = -t0
+ M = numpy.dot(M, T)
+
+ # compute root mean square error from SVD sigma
+ if compute_rmsd:
+ r = numpy.cumsum(v0*v0) + numpy.cumsum(v1*v1)
+ rmsd = numpy.sqrt(abs(r - (2.0 * sum(s)) / len(v0)))
+ return M, rmsd
+ else:
+ return M
+
+def rotation_matrix_from_euler(ai, aj, ak, axes):
+ """Return homogeneous rotation matrix from Euler angles and axis sequence.
+
+ ai, aj, ak -- Euler's roll, pitch and yaw angles
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ if frame: ai, ak = ak, ai
+ if parity: ai, aj, ak = -ai, -aj, -ak
+
+ si, sj, sh = math.sin(ai), math.sin(aj), math.sin(ak)
+ ci, cj, ch = math.cos(ai), math.cos(aj), math.cos(ak)
+ cc, cs = ci*ch, ci*sh
+ sc, ss = si*ch, si*sh
+
+ M = numpy.identity(4, dtype=numpy.float64)
+ if repetition:
+ M[i,i] = cj; M[i,j] = sj*si; M[i,k] = sj*ci
+ M[j,i] = sj*sh; M[j,j] = -cj*ss+cc; M[j,k] = -cj*cs-sc
+ M[k,i] = -sj*ch; M[k,j] = cj*sc+cs; M[k,k] = cj*cc-ss
+ else:
+ M[i,i] = cj*ch; M[i,j] = sj*sc-cs; M[i,k] = sj*cc+ss
+ M[j,i] = cj*sh; M[j,j] = sj*ss+cc; M[j,k] = sj*cs-sc
+ M[k,i] = -sj; M[k,j] = cj*si; M[k,k] = cj*ci
+ return M
+
+def euler_from_rotation_matrix(matrix, axes='sxyz'):
+ """Return Euler angles from rotation matrix for specified axis sequence.
+
+ matrix -- 3x3 or 4x4 rotation matrix
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ Note that many Euler angle triplets can describe one matrix.
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ M = numpy.array(matrix, dtype=numpy.float64)[0:3, 0:3]
+ if repetition:
+ sy = math.sqrt(M[i,j]*M[i,j] + M[i,k]*M[i,k])
+ if sy > _EPS:
+ ax = math.atan2( M[i,j], M[i,k])
+ ay = math.atan2( sy, M[i,i])
+ az = math.atan2( M[j,i], -M[k,i])
+ else:
+ ax = math.atan2(-M[j,k], M[j,j])
+ ay = math.atan2( sy, M[i,i])
+ az = 0.0
+ else:
+ cy = math.sqrt(M[i,i]*M[i,i] + M[j,i]*M[j,i])
+ if cy > _EPS:
+ ax = math.atan2( M[k,j], M[k,k])
+ ay = math.atan2(-M[k,i], cy)
+ az = math.atan2( M[j,i], M[i,i])
+ else:
+ ax = math.atan2(-M[j,k], M[j,j])
+ ay = math.atan2(-M[k,i], cy)
+ az = 0.0
+
+ if parity: ax, ay, az = -ax, -ay, -az
+ if frame: ax, az = az, ax
+ return ax, ay, az
+
+def quaternion_from_euler(ai, aj, ak, axes):
+ """Return quaternion from Euler angles and axis sequence.
+
+ ai, aj, ak -- Euler's roll, pitch and yaw angles
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ if frame: ai, ak = ak, ai
+ if parity: aj = -aj
+
+ ti = ai*0.5
+ tj = aj*0.5
+ tk = ak*0.5
+ ci = math.cos(ti)
+ si = math.sin(ti)
+ cj = math.cos(tj)
+ sj = math.sin(tj)
+ ck = math.cos(tk)
+ sk = math.sin(tk)
+ cc = ci*ck
+ cs = ci*sk
+ sc = si*ck
+ ss = si*sk
+
+ q = numpy.empty((4,), dtype=numpy.float64)
+ if repetition:
+ q[i] = cj*(cs + sc)
+ q[j] = sj*(cc + ss)
+ q[k] = sj*(cs - sc)
+ q[3] = cj*(cc - ss)
+ else:
+ q[i] = cj*sc - sj*cs
+ q[j] = cj*ss + sj*cc
+ q[k] = cj*cs - sj*sc
+ q[3] = cj*cc + sj*ss
+
+ if parity: q[j] *= -1
+ return q
+
+def euler_from_quaternion(quaternion, axes='sxyz'):
+ """Return Euler angles from quaternion for specified axis sequence.
+
+ quaternion -- Sequence of x, y, z, w
+ axes -- One of 24 valid axis sequences as string or encoded tuple
+
+ """
+ return euler_from_rotation_matrix(
+ rotation_matrix_from_quaternion(quaternion), axes)
+
+def quaternion_about_axis(angle, axis):
+ """Return quaternion for rotation about axis."""
+ u = numpy.zeros((4,), dtype=numpy.float64)
+ u[0:3] = axis[0:3]
+ u *= math.sin(angle/2) / math.sqrt(numpy.dot(u, u))
+ u[3] = math.cos(angle/2)
+ return u
+
+def rotation_matrix_from_quaternion(quaternion):
+ """Return homogeneous rotation matrix from quaternion."""
+ q = numpy.array(quaternion, dtype=numpy.float64)[0:4]
+ nq = numpy.dot(q, q)
+ if nq == 0.0:
+ return numpy.identity(4, dtype=numpy.float64)
+ q *= math.sqrt(2.0 / nq)
+ q = numpy.outer(q, q)
+ return numpy.array((
+ (1.0-q[1,1]-q[2,2], q[0,1]-q[2,3], q[0,2]+q[1,3], 0.0),
+ ( q[0,1]+q[2,3], 1.0-q[0,0]-q[2,2], q[1,2]-q[0,3], 0.0),
+ ( q[0,2]-q[1,3], q[1,2]+q[0,3], 1.0-q[0,0]-q[1,1], 0.0),
+ ( 0.0, 0.0, 0.0, 1.0)
+ ), dtype=numpy.float64)
+
+def quaternion_from_rotation_matrix(matrix):
+ """Return quaternion from rotation matrix."""
+ q = numpy.empty((4,), dtype=numpy.float64)
+ M = numpy.array(matrix, dtype=numpy.float64)[0:4,0:4]
+ t = numpy.trace(M)
+ if t > M[3,3]:
+ q[3] = t
+ q[2] = M[1,0] - M[0,1]
+ q[1] = M[0,2] - M[2,0]
+ q[0] = M[2,1] - M[1,2]
+ else:
+ i,j,k = 0,1,2
+ if M[1,1] > M[0,0]:
+ i,j,k = 1,2,0
+ if M[2,2] > M[i,i]:
+ i,j,k = 2,0,1
+ t = M[i,i] - (M[j,j] + M[k,k]) + M[3,3]
+ q[i] = t
+ q[j] = M[i,j] + M[j,i]
+ q[k] = M[k,i] + M[i,k]
+ q[3] = M[k,j] - M[j,k]
+ q *= 0.5 / math.sqrt(t * M[3,3])
+ return q
+
+def quaternion_multiply(q1, q0):
+ """Multiply two quaternions."""
+ x0, y0, z0, w0 = q0
+ x1, y1, z1, w1 = q1
+ return numpy.array((
+ x1*w0 + y1*z0 - z1*y0 + w1*x0,
+ -x1*z0 + y1*w0 + z1*x0 + w1*y0,
+ x1*y0 - y1*x0 + z1*w0 + w1*z0,
+ -x1*x0 - y1*y0 - z1*z0 + w1*w0))
+
+def quaternion_from_sphere_points(v0, v1):
+ """Return quaternion from two points on unit sphere.
+
+ v0 -- E.g. sphere coordinates of cursor at mouse down
+ v1 -- E.g. current sphere coordinates of cursor
+
+ """
+ x, y, z = numpy.cross(v0, v1)
+ return x, y, z, numpy.dot(v0, v1)
+
+def quaternion_to_sphere_points(q):
+ """Return two points on unit sphere from quaternion."""
+ l = math.sqrt(q[0]*q[0] + q[1]*q[1])
+ v0 = numpy.array((0.0, 1.0, 0.0) if l==0.0 else \
+ (-q[1]/l, q[0]/l, 0.0), dtype=numpy.float64)
+ v1 = numpy.array((q[3]*v0[0] - q[3]*v0[1],
+ q[3]*v0[1] + q[3]*v0[0],
+ q[0]*v0[1] - q[1]*v0[0]), dtype=numpy.float64)
+ if q[3] < 0.0:
+ v0 *= -1.0
+ return v0, v1
+
+
+class Arcball(object):
+ """Virtual Trackball Control."""
+
+ def __init__(self, center=None, radius=1.0, initial=None):
+ """Initializes virtual trackball control.
+
+ center -- Window coordinates of trackball center
+ radius -- Radius of trackball in window coordinates
+ initial -- Initial quaternion or rotation matrix
+
+ """
+ self.axis = None
+ self.center = numpy.zeros((3,), dtype=numpy.float64)
+ self.place(center, radius)
+ self.v0 = numpy.array([0., 0., 1.], dtype=numpy.float64)
+ if initial is None:
+ self.q0 = numpy.array([0., 0., 0., 1.], dtype=numpy.float64)
+ else:
+ try:
+ self.q0 = quaternion_from_rotation_matrix(initial)
+ except:
+ self.q0 = initial
+ self.qnow = self.q0
+
+ def place(self, center=[0., 0.], radius=1.0):
+ """Place Arcball, e.g. when window size changes."""
+ self.radius = float(radius)
+ self.center[0:2] = center[0:2]
+
+ def click(self, position, axis=None):
+ """Set axis constraint and initial window coordinates of cursor."""
+ self.axis = axis
+ self.q0 = self.qnow
+ self.v0 = self._map_to_sphere(position, self.center, self.radius)
+
+ def drag(self, position):
+ """Return rotation matrix from updated window coordinates of cursor."""
+ v0 = self.v0
+ v1 = self._map_to_sphere(position, self.center, self.radius)
+
+ if self.axis is not None:
+ v0 = self._constrain_to_axis(v0, self.axis)
+ v1 = self._constrain_to_axis(v1, self.axis)
+
+ t = numpy.cross(v0, v1)
+ if numpy.dot(t, t) < _EPS:
+ # v0 and v1 coincide. no additional rotation
+ self.qnow = self.q0
+ else:
+ q1 = [t[0], t[1], t[2], numpy.dot(v0, v1)]
+ self.qnow = quaternion_multiply(q1, self.q0)
+
+ return rotation_matrix_from_quaternion(self.qnow)
+
+ def _map_to_sphere(self, position, center, radius):
+ """Map window coordinates to unit sphere coordinates."""
+ v = numpy.array([position[0], position[1], 0.0], dtype=numpy.float64)
+ v -= center
+ v /= radius
+ v[1] *= -1
+ l = numpy.dot(v, v)
+ if l > 1.0:
+ v /= math.sqrt(l) # position outside of sphere
+ else:
+ v[2] = math.sqrt(1.0 - l)
+ return v
+
+ def _constrain_to_axis(self, point, axis):
+ """Return sphere point perpendicular to axis."""
+ v = numpy.array(point, dtype=numpy.float64)
+ a = numpy.array(axis, dtype=numpy.float64, copy=True)
+ a /= numpy.dot(a, v)
+ v -= a # on plane
+ n = numpy.dot(v, v)
+ if n > 0.0:
+ v /= math.sqrt(n)
+ return v
+ if a[2] == 1.0:
+ return numpy.array([1.0, 0.0, 0.0], dtype=numpy.float64)
+ v[:] = -a[1], a[0], 0.0
+ v /= math.sqrt(numpy.dot(v, v))
+ return v
+
+ def _nearest_axis(self, point, *axes):
+ """Return axis, which arc is nearest to point."""
+ nearest = None
+ max = -1.0
+ for axis in axes:
+ t = numpy.dot(self._constrain_to_axis(point, axis), point)
+ if t > max:
+ nearest = axis
+ max = d
+ return nearest
+
+# axis sequences for Euler angles
+_NEXT_AXIS = [1, 2, 0, 1]
+_AXES2TUPLE = { # axes string -> (inner axis, parity, repetition, frame)
+ "sxyz": (0, 0, 0, 0), "sxyx": (0, 0, 1, 0), "sxzy": (0, 1, 0, 0),
+ "sxzx": (0, 1, 1, 0), "syzx": (1, 0, 0, 0), "syzy": (1, 0, 1, 0),
+ "syxz": (1, 1, 0, 0), "syxy": (1, 1, 1, 0), "szxy": (2, 0, 0, 0),
+ "szxz": (2, 0, 1, 0), "szyx": (2, 1, 0, 0), "szyz": (2, 1, 1, 0),
+ "rzyx": (0, 0, 0, 1), "rxyx": (0, 0, 1, 1), "ryzx": (0, 1, 0, 1),
+ "rxzx": (0, 1, 1, 1), "rxzy": (1, 0, 0, 1), "ryzy": (1, 0, 1, 1),
+ "rzxy": (1, 1, 0, 1), "ryxy": (1, 1, 1, 1), "ryxz": (2, 0, 0, 1),
+ "rzxz": (2, 0, 1, 1), "rxyz": (2, 1, 0, 1), "rzyz": (2, 1, 1, 1)}
+_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items())
+
+try:
+ # import faster functions from C extension module
+ import _vlfdlib
+ rotation_matrix_from_quaternion = _vlfdlib.quaternion_to_matrix
+ quaternion_from_rotation_matrix = _vlfdlib.quaternion_from_matrix
+ quaternion_multiply = _vlfdlib.quaternion_multiply
+except ImportError:
+ pass
+
+def test_transformations_module(*args, **kwargs):
+ """Test transformation module."""
+ v = numpy.array([6.67,3.69,4.82], dtype=numpy.float64)
+ I = numpy.identity(4, dtype=numpy.float64)
+ T = translation_matrix(-v)
+ M = mirror_matrix([0,0,0], v)
+ R = rotation_matrix(math.pi, [1,0,0], point=v)
+ P = projection_matrix(-v, v, perspective=10*v)
+ P = projection_matrix(-v, v, direction=v)
+ P = projection_matrix(-v, v)
+ S = scaling_matrix(0.25, v, direction=None) # reduce size
+ S = scaling_matrix(-1.0) # point symmetry
+ S = scaling_matrix(10.0)
+ O = orthogonalization_matrix(10.0, 10.0, 10.0, 90.0, 90.0, 90.0)
+ assert numpy.allclose(S, O)
+
+ angles = (1, -2, 3)
+ for axes in sorted(_AXES2TUPLE.keys()):
+ assert axes == _TUPLE2AXES[_AXES2TUPLE[axes]]
+ Me = rotation_matrix_from_euler(axes=axes, *angles)
+ em = euler_from_rotation_matrix(Me, axes)
+ Mf = rotation_matrix_from_euler(axes=axes, *em)
+ assert numpy.allclose(Me, Mf)
+
+ axes = 'sxyz'
+ euler = (0.0, 0.2, 0.0)
+ qe = quaternion_from_euler(axes=axes, *euler)
+ Mr = rotation_matrix(0.2, [0,1,0])
+ Me = rotation_matrix_from_euler(axes=axes, *euler)
+ Mq = rotation_matrix_from_quaternion(qe)
+ assert numpy.allclose(Mr, Me)
+ assert numpy.allclose(Mr, Mq)
+ em = euler_from_rotation_matrix(Mr, axes)
+ eq = euler_from_quaternion(qe, axes)
+ assert numpy.allclose(em, eq)
+ qm = quaternion_from_rotation_matrix(Mq)
+ assert numpy.allclose(qe, qm)
+
+ assert numpy.allclose(
+ rotation_matrix_from_quaternion(
+ quaternion_about_axis(1.0, [1,-0.5,1])),
+ rotation_matrix(1.0, [1,-0.5,1]))
+
+ ball = Arcball([320,320], 320)
+ ball.click([500,250])
+ R = ball.drag([475, 275])
+ assert numpy.allclose(R, [[ 0.9787566, 0.03798976, -0.20147528, 0.],
+ [-0.06854143, 0.98677273, -0.14690692, 0.],
+ [ 0.19322935, 0.15759552, 0.9684142, 0.],
+ [ 0., 0., 0., 1.]])
+
+if __name__ == "__main__":
+ test_transformations_module()
+
Modified: pkg/trunk/vision/visual_odometry/manifest.xml
===================================================================
--- pkg/trunk/vision/visual_odometry/manifest.xml 2009-02-28 02:19:27 UTC (rev 11936)
+++ pkg/trunk/vision/visual_odometry/manifest.xml 2009-02-28 02:29:24 UTC (rev 11937)
@@ -20,7 +20,7 @@
<depend package="vop"/>
<depend package="rosrecord"/>
<depend package="calonder_descriptor"/>
- <depend package="transformations"/>
+ <depend package="tf"/>
<depend package="toro"/>
<export>
<cpp cflags="-I${prefix}/include -I${prefix}/msg/cpp" lflags="-L${prefix}/lib -lvisual_odometry -Wl,-rpath,${prefix}/lib" />
Modified: pkg/trunk/vision/vslam/manifest.xml
===================================================================
--- pkg/trunk/vision/vslam/manifest.xml 2009-02-28 02:19:27 UTC (rev 11936)
+++ pkg/trunk/vision/vslam/manifest.xml 2009-02-28 02:29:24 UTC (rev 11937)
@@ -8,7 +8,7 @@
<depend package="visual_odometry"/>
<depend package="std_msgs"/>
<depend package="rospy"/>
- <depend package="transformations"/>
+ <depend package="tf"/>
<depend package="toro"/>
<depend package="image_synthesizer"/>
<depend package="place_recognition"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rdi...@us...> - 2009-02-28 12:59:43
|
Revision: 11954
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11954&view=rev
Author: rdiankov
Date: 2009-02-28 12:59:38 +0000 (Sat, 28 Feb 2009)
Log Message:
-----------
fixed bullet x86-64 compilation problem
Modified Paths:
--------------
pkg/trunk/3rdparty/openrave/Makefile
pkg/trunk/3rdparty/openrave/manifest.xml
pkg/trunk/prcore/bullet/Makefile
Modified: pkg/trunk/3rdparty/openrave/Makefile
===================================================================
--- pkg/trunk/3rdparty/openrave/Makefile 2009-02-28 10:24:44 UTC (rev 11953)
+++ pkg/trunk/3rdparty/openrave/Makefile 2009-02-28 12:59:38 UTC (rev 11954)
@@ -9,13 +9,11 @@
.PHONY: openrave
-#export CPATH="$(shell rospack find bullet)/include:$(CPATH)"
-#export LD_LIBRARY_PATH=$(shell rospack find bullet)/lib:$(LD_LIBRARY_PATH) &&
BOOST_INCLUDE_DIRS=$(shell rosboost-cfg --include_dirs)
BOOST_LIBRARY_DIRS=$(shell rosboost-cfg --lib_dirs)
installed: $(SVN_DIR) patched
- cd $(SVN_DIR) && export PATH="$(shell rospack find soqt)/bin:$(shell rospack find opende)/opende/bin:$(PATH)" && mkdir -p build && cd build && BOOST_INCLUDEDIR=$(BOOST_INCLUDE_DIRS) BOOST_LIBRARYDIR=$(BOOST_LIBRARY_DIRS) cmake -DCMAKE_INSTALL_PREFIX=$(PWD) -DCMAKE_BUILD_TYPE=Release -DBoost_INCLUDE_DIR=$(BOOST_INCLUDE_DIRS) -DBoost_LIBRARY_DIR=$(BOOST_LIBRARY_DIRS) .. && export PARALLEL_JOBS=ROS_PARALLEL_JOBS && make $(ROS_PARALLEL_JOBS) install
+ cd $(SVN_DIR) && export PATH="$(shell rospack find soqt)/bin:$(shell rospack find opende)/opende/bin:$(PATH)" && mkdir -p build && cd build && export CPATH="$(shell rospack find bullet)/include:$(CPATH)" && export LD_LIBRARY_PATH=$(shell rospack find bullet)/lib:$(LD_LIBRARY_PATH) && BOOST_INCLUDEDIR=$(BOOST_INCLUDE_DIRS) BOOST_LIBRARYDIR=$(BOOST_LIBRARY_DIRS) cmake -DCMAKE_INSTALL_PREFIX=$(PWD) -DCMAKE_BUILD_TYPE=Release -DBoost_INCLUDE_DIR=$(BOOST_INCLUDE_DIRS) -DBoost_LIBRARY_DIR=$(BOOST_LIBRARY_DIRS) .. && export PARALLEL_JOBS=ROS_PARALLEL_JOBS && make $(ROS_PARALLEL_JOBS) install
touch installed
clean:
Modified: pkg/trunk/3rdparty/openrave/manifest.xml
===================================================================
--- pkg/trunk/3rdparty/openrave/manifest.xml 2009-02-28 10:24:44 UTC (rev 11953)
+++ pkg/trunk/3rdparty/openrave/manifest.xml 2009-02-28 12:59:38 UTC (rev 11954)
@@ -11,7 +11,7 @@
<cpp lflags="-Wl,-rpath,${prefix}/lib `${prefix}/bin/openrave-config --libs`" cflags="`${prefix}/bin/openrave-config --cflags`"/>
</export>
<depend package="soqt"/>
-<!-- <depend package="bullet"/> -->
+ <depend package="bullet"/>
<depend package="opende"/>
<depend package="std_msgs"/>
<!-- <depend package="laser_scan"/> -->
Modified: pkg/trunk/prcore/bullet/Makefile
===================================================================
--- pkg/trunk/prcore/bullet/Makefile 2009-02-28 10:24:44 UTC (rev 11953)
+++ pkg/trunk/prcore/bullet/Makefile 2009-02-28 12:59:38 UTC (rev 11954)
@@ -31,7 +31,7 @@
BulletSoftBody
installed: $(SVN_DIR) patched
- cd $(SVN_DIR) && cmake -DCMAKE_INSTALL_PREFIX=$(PWD) .
+ cd $(SVN_DIR) && cmake -DCMAKE_INSTALL_PREFIX=$(PWD) -DCMAKE_CXX_FLAGS=-fPIC .
# Bullet appears not be parallel-make safe
#cd $(SVN_DIR) && make $(PARALLEL_JOBS)
cd $(SVN_DIR) && make $(BULLET_TARGETS)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-02 18:15:56
|
Revision: 11987
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11987&view=rev
Author: tfoote
Date: 2009-03-02 18:15:46 +0000 (Mon, 02 Mar 2009)
Log Message:
-----------
moving transformations into correct namespace
Modified Paths:
--------------
pkg/trunk/demos/test_2dnav_gazebo/set_goal.py
pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/test_arm.py
pkg/trunk/vision/visual_odometry/scripts/mkgeo.py
pkg/trunk/vision/visual_odometry/scripts/mkrun.py
pkg/trunk/vision/visual_odometry/src/visualodometer.py
pkg/trunk/vision/visual_odometry/test/pe.py
pkg/trunk/vision/vslam/scripts/mkplot.py
pkg/trunk/vision/vslam/scripts/plot3d.py
pkg/trunk/vision/vslam/scripts/transf_fit.py
Added Paths:
-----------
pkg/trunk/prcore/tf/src/tf/
pkg/trunk/prcore/tf/src/tf/transformations.py
Removed Paths:
-------------
pkg/trunk/prcore/tf/src/transformations.py
Modified: pkg/trunk/demos/test_2dnav_gazebo/set_goal.py
===================================================================
--- pkg/trunk/demos/test_2dnav_gazebo/set_goal.py 2009-03-02 17:56:22 UTC (rev 11986)
+++ pkg/trunk/demos/test_2dnav_gazebo/set_goal.py 2009-03-02 18:15:46 UTC (rev 11987)
@@ -50,7 +50,7 @@
from std_msgs.msg import *
from robot_msgs.msg import *
from deprecated_msgs.msg import *
-from transformations import *
+from tf.transformations import *
from numpy import *
FLOAT_TOL = 0.0001
Modified: pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/test_arm.py
===================================================================
--- pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/test_arm.py 2009-03-02 17:56:22 UTC (rev 11986)
+++ pkg/trunk/drivers/simulator/test_pr2_mechanism_controllers_gazebo/test_arm.py 2009-03-02 18:15:46 UTC (rev 11987)
@@ -52,7 +52,7 @@
from std_msgs.msg import *
from robot_msgs.msg import *
from pr2_mechanism_controllers.msg import *
-from transformations import *
+from tf.transformations import *
from numpy import *
Copied: pkg/trunk/prcore/tf/src/tf/transformations.py (from rev 11937, pkg/trunk/prcore/tf/src/transformations.py)
===================================================================
--- pkg/trunk/prcore/tf/src/tf/transformations.py (rev 0)
+++ pkg/trunk/prcore/tf/src/tf/transformations.py 2009-03-02 18:15:46 UTC (rev 11987)
@@ -0,0 +1,647 @@
+# -*- coding: utf-8 -*-
+# transformations.py
+
+# Copyright (c) 2006-2007, Christoph Gohlke
+# Copyright (c) 2006-2007, The Regents of the University of California
+# 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 copyright holders nor the names of any
+# 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.
+
+# Source: http://lfd.uci.edu/~gohlke/code/transformations.py.html
+
+"""Homogeneous Transformation Matrices and Quaternions.
+
+Functions for calculating 4x4 matrices for translating, rotating, mirroring,
+scaling, projecting, orthogonalization, and superimposition of arrays of
+homogenous coordinates as well as for converting between rotation matrices,
+Euler angles, and quaternions.
+
+Matrices can be inverted using numpy.linalg.inv(M), concatenated using
+numpy.dot(M0,M1), or used to transform homogeneous points using
+numpy.dot(v, M) for shape (4,*) "point of arrays", respectively
+numpy.dot(v, M.T) for shape (*,4) "array of points".
+
+Quaternions ix+jy+kz+w are represented as [x, y, z, w].
+
+Angles are in radians unless specified otherwise.
+
+The 24 ways of specifying rotations for a given triple of Euler angles,
+can be represented by a 4 character string or encoded 4-tuple:
+
+ Axes 4-string:
+ first character -- rotations are applied to 's'tatic or 'r'otating frame
+ remaining characters -- successive rotation axis 'x', 'y', or 'z'
+ Axes 4-tuple:
+ inner axis -- code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix.
+ parity -- even (0) if inner axis 'x' is followed by 'y', 'y' is followed
+ by 'z', or 'z' is followed by 'x'. Otherwise odd (1).
+ repetition -- first and last axis are same (1) or different (0).
+ frame -- rotations are applied to static (0) or rotating (1) frame.
+ Examples of tuple codes:
+ 'sxyz' <-> (0, 0, 0, 0)
+ 'ryxy' <-> (1, 1, 1, 1)
+
+Author:
+ Christoph Gohlke, http://www.lfd.uci.edu/~gohlke/
+ Laboratory for Fluorescence Dynamics, University of California, Irvine
+
+Requirements:
+ Python 2.5 (http://www.python.org)
+ Numpy 1.0 (http://numpy.scipy.org)
+
+References:
+(1) Matrices and Transformations. Ronald Goldman.
+ In "Graphics Gems I", pp 472-475. Morgan Kaufmann, 1990.
+(2) Euler Angle Conversion. Ken Shoemake.
+ In "Graphics Gems IV", pp 222-229. Morgan Kaufmann, 1994.
+(3) Arcball Rotation Control. Ken Shoemake.
+ In "Graphics Gems IV", pp 175-192. Morgan Kaufmann, 1994.
+
+"""
+
+from __future__ import division
+
+import math
+import numpy
+
+_EPS = numpy.finfo(float).eps * 4.0
+
+def concatenate_transforms(*args):
+ """Merge multiple transformation matrices into one."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ for i in args:
+ M = numpy.dot(M, i)
+ return M
+
+def translation_matrix(direction):
+ """Return matrix to translate by direction vector."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,3] = direction[0:3]
+ return M
+
+def mirror_matrix(point, normal):
+ """Return matrix to mirror at plane defined by point and normal vector."""
+ M = numpy.identity(4, dtype=numpy.float64)
+ n = numpy.array(normal[0:3], dtype=numpy.float64, copy=True)
+ n /= math.sqrt(numpy.dot(n,n))
+ M[0:3,0:3] -= 2.0 * numpy.outer(n, n)
+ M[0:3,3] = 2.0 * numpy.dot(point[0:3], n) * n
+ return M
+
+def rotation_matrix(angle, direction, point=None):
+ """Return matrix to rotate about axis defined by point and direction."""
+ sa, ca = math.sin(angle), math.cos(angle)
+ # unit vector of direction
+ u = numpy.array(direction[0:3], dtype=numpy.float64, copy=True)
+ u /= math.sqrt(numpy.dot(u, u))
+ # rotation matrix around unit vector
+ R = numpy.identity(3, dtype=numpy.float64)
+ R *= ca
+ R += numpy.outer(u, u) * (1.0 - ca)
+ R += sa * numpy.array((( 0.0,-u[2], u[1]),
+ ( u[2], 0.0,-u[0]),
+ (-u[1], u[0], 0.0)), dtype=numpy.float64)
+ M = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,0:3] = R
+ if point is not None:
+ # rotation not around origin
+ M[0:3,3] = point[0:3] - numpy.dot(R, point[0:3])
+ return M
+
+def scaling_matrix(factor, origin=None, direction=None):
+ """Return matrix to scale by factor around origin in direction.
+
+ Point Symmetry: factor = -1.0
+
+ """
+ if origin is None: origin = [0,0,0]
+ o = numpy.array(origin[0:3], dtype=numpy.float64, copy=False)
+ if direction is None:
+ # uniform scaling
+ M = factor*numpy.identity(4, dtype=numpy.float64)
+ M[0:3,3] = (1.0-factor) * o
+ M[3,3] = 1.0
+ else:
+ # nonuniform scaling
+ M = numpy.identity(4, dtype=numpy.float64)
+ u = numpy.array(direction[0:3], dtype=numpy.float64, copy=True)
+ u /= math.sqrt(numpy.dot(u, u)) # unit vector of direction
+ M[0:3,0:3] -= (1.0-factor) * numpy.outer(u, u)
+ M[0:3,3] = ((1.0-factor) * numpy.dot(o, u)) * u
+ return M
+
+def projection_matrix(point, normal, direction=None, perspective=None):
+ """Return matrix to project onto plane defined by point and normal.
+
+ Using either perspective point, projection direction, or none of both.
+
+ """
+ M = numpy.identity(4, dtype=numpy.float64)
+ n = numpy.array(normal[0:3], dtype=numpy.float64, copy=True)
+ n /= math.sqrt(numpy.dot(n,n)) # unit vector of normal
+ if perspective is not None:
+ # perspective projection
+ r = numpy.array(perspective[0:3], dtype=numpy.float64)
+ M[0:3,0:3] *= numpy.dot((r-point), n)
+ M[0:3,0:3] -= numpy.outer(n, r)
+ M[0:3,3] = numpy.dot(point, n) * r
+ M[3,0:3] = -n
+ M[3,3] = numpy.dot(perspective, n)
+ elif direction is not None:
+ # parallel projection
+ w = numpy.array(direction[0:3], dtype=numpy.float64)
+ s = 1.0 / numpy.dot(w, n)
+ M[0:3,0:3] -= numpy.outer(n, w) * s
+ M[0:3,3] = w * (numpy.dot(point[0:3], n) * s)
+ else:
+ # orthogonal projection
+ M[0:3,0:3] -= numpy.outer(n, n)
+ M[0:3,3] = numpy.dot(point[0:3], n) * n
+ return M
+
+def orthogonalization_matrix(a=10.0, b=10.0, c=10.0,
+ alpha=90.0, beta=90.0, gamma=90.0):
+ """Return orthogonalization matrix for crystallographic cell coordinates.
+
+ Angles are in degrees.
+
+ """
+ al = math.radians(alpha)
+ be = math.radians(beta)
+ ga = math.radians(gamma)
+ sia = math.sin(al)
+ sib = math.sin(be)
+ coa = math.cos(al)
+ cob = math.cos(be)
+ co = (coa * cob - math.cos(ga)) / (sia * sib)
+ return numpy.array((
+ (a*sib*math.sqrt(1.0-co*co), 0.0, 0.0, 0.0),
+ (-a*sib*co, b*sia, 0.0, 0.0),
+ (a*cob, b*coa, c, 0.0),
+ (0.0, 0.0, 0.0, 1.0)),
+ dtype=numpy.float64)
+
+def superimpose_matrix(v0, v1, compute_rmsd=False):
+ """Return matrix to transform given vector set into second vector set.
+
+ Minimize weighted sum of squared deviations according to W. Kabsch.
+ v0 and v1 are shape (*,3) or (*,4) arrays of at least 3 vectors.
+
+ """
+ v0 = numpy.array(v0, dtype=numpy.float64)
+ v1 = numpy.array(v1, dtype=numpy.float64)
+
+ assert v0.ndim==2 and v0.ndim==v1.ndim and \
+ v0.shape[0]>2 and v0.shape[1] in (3,4)
+
+ # vectors might be homogeneous coordinates
+ if v0.shape[1] == 4:
+ v0 = v0[:,0:3]
+ v1 = v1[:,0:3]
+
+ # move centroids to origin
+ t0 = numpy.mean(v0, axis=0)
+ t1 = numpy.mean(v1, axis=0)
+ v0 = v0 - t0
+ v1 = v1 - t1
+
+ # Singular Value Decomposition of covariance matrix
+ u, s, vh = numpy.linalg.svd(numpy.dot(v1.T, v0))
+
+ # rotation matrix from SVD orthonormal bases
+ R = numpy.dot(u, vh)
+ if numpy.linalg.det(R) < 0.0:
+ # R does not constitute right handed system
+ rc = vh[2,:] * 2.0
+ R -= numpy.vstack((u[0,2]*rc, u[1,2]*rc, u[2,2]*rc))
+ s[-1] *= -1.0
+
+ # homogeneous transformation matrix
+ M = numpy.identity(4, dtype=numpy.float64)
+ T = numpy.identity(4, dtype=numpy.float64)
+ M[0:3,0:3] = R
+ T[0:3,3] = t1
+ M = numpy.dot(T, M)
+ T[0:3,3] = -t0
+ M = numpy.dot(M, T)
+
+ # compute root mean square error from SVD sigma
+ if compute_rmsd:
+ r = numpy.cumsum(v0*v0) + numpy.cumsum(v1*v1)
+ rmsd = numpy.sqrt(abs(r - (2.0 * sum(s)) / len(v0)))
+ return M, rmsd
+ else:
+ return M
+
+def rotation_matrix_from_euler(ai, aj, ak, axes):
+ """Return homogeneous rotation matrix from Euler angles and axis sequence.
+
+ ai, aj, ak -- Euler's roll, pitch and yaw angles
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ if frame: ai, ak = ak, ai
+ if parity: ai, aj, ak = -ai, -aj, -ak
+
+ si, sj, sh = math.sin(ai), math.sin(aj), math.sin(ak)
+ ci, cj, ch = math.cos(ai), math.cos(aj), math.cos(ak)
+ cc, cs = ci*ch, ci*sh
+ sc, ss = si*ch, si*sh
+
+ M = numpy.identity(4, dtype=numpy.float64)
+ if repetition:
+ M[i,i] = cj; M[i,j] = sj*si; M[i,k] = sj*ci
+ M[j,i] = sj*sh; M[j,j] = -cj*ss+cc; M[j,k] = -cj*cs-sc
+ M[k,i] = -sj*ch; M[k,j] = cj*sc+cs; M[k,k] = cj*cc-ss
+ else:
+ M[i,i] = cj*ch; M[i,j] = sj*sc-cs; M[i,k] = sj*cc+ss
+ M[j,i] = cj*sh; M[j,j] = sj*ss+cc; M[j,k] = sj*cs-sc
+ M[k,i] = -sj; M[k,j] = cj*si; M[k,k] = cj*ci
+ return M
+
+def euler_from_rotation_matrix(matrix, axes='sxyz'):
+ """Return Euler angles from rotation matrix for specified axis sequence.
+
+ matrix -- 3x3 or 4x4 rotation matrix
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ Note that many Euler angle triplets can describe one matrix.
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ M = numpy.array(matrix, dtype=numpy.float64)[0:3, 0:3]
+ if repetition:
+ sy = math.sqrt(M[i,j]*M[i,j] + M[i,k]*M[i,k])
+ if sy > _EPS:
+ ax = math.atan2( M[i,j], M[i,k])
+ ay = math.atan2( sy, M[i,i])
+ az = math.atan2( M[j,i], -M[k,i])
+ else:
+ ax = math.atan2(-M[j,k], M[j,j])
+ ay = math.atan2( sy, M[i,i])
+ az = 0.0
+ else:
+ cy = math.sqrt(M[i,i]*M[i,i] + M[j,i]*M[j,i])
+ if cy > _EPS:
+ ax = math.atan2( M[k,j], M[k,k])
+ ay = math.atan2(-M[k,i], cy)
+ az = math.atan2( M[j,i], M[i,i])
+ else:
+ ax = math.atan2(-M[j,k], M[j,j])
+ ay = math.atan2(-M[k,i], cy)
+ az = 0.0
+
+ if parity: ax, ay, az = -ax, -ay, -az
+ if frame: ax, az = az, ax
+ return ax, ay, az
+
+def quaternion_from_euler(ai, aj, ak, axes):
+ """Return quaternion from Euler angles and axis sequence.
+
+ ai, aj, ak -- Euler's roll, pitch and yaw angles
+ axes -- One of 24 axis sequences as string or encoded tuple
+
+ """
+ try:
+ firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
+ except (AttributeError, KeyError):
+ _TUPLE2AXES[axes]
+ firstaxis, parity, repetition, frame = axes
+
+ i = firstaxis
+ j = _NEXT_AXIS[i+parity]
+ k = _NEXT_AXIS[i-parity+1]
+
+ if frame: ai, ak = ak, ai
+ if parity: aj = -aj
+
+ ti = ai*0.5
+ tj = aj*0.5
+ tk = ak*0.5
+ ci = math.cos(ti)
+ si = math.sin(ti)
+ cj = math.cos(tj)
+ sj = math.sin(tj)
+ ck = math.cos(tk)
+ sk = math.sin(tk)
+ cc = ci*ck
+ cs = ci*sk
+ sc = si*ck
+ ss = si*sk
+
+ q = numpy.empty((4,), dtype=numpy.float64)
+ if repetition:
+ q[i] = cj*(cs + sc)
+ q[j] = sj*(cc + ss)
+ q[k] = sj*(cs - sc)
+ q[3] = cj*(cc - ss)
+ else:
+ q[i] = cj*sc - sj*cs
+ q[j] = cj*ss + sj*cc
+ q[k] = cj*cs - sj*sc
+ q[3] = cj*cc + sj*ss
+
+ if parity: q[j] *= -1
+ return q
+
+def euler_from_quaternion(quaternion, axes='sxyz'):
+ """Return Euler angles from quaternion for specified axis sequence.
+
+ quaternion -- Sequence of x, y, z, w
+ axes -- One of 24 valid axis sequences as string or encoded tuple
+
+ """
+ return euler_from_rotation_matrix(
+ rotation_matrix_from_quaternion(quaternion), axes)
+
+def quaternion_about_axis(angle, axis):
+ """Return quaternion for rotation about axis."""
+ u = numpy.zeros((4,), dtype=numpy.float64)
+ u[0:3] = axis[0:3]
+ u *= math.sin(angle/2) / math.sqrt(numpy.dot(u, u))
+ u[3] = math.cos(angle/2)
+ return u
+
+def rotation_matrix_from_quaternion(quaternion):
+ """Return homogeneous rotation matrix from quaternion."""
+ q = numpy.array(quaternion, dtype=numpy.float64)[0:4]
+ nq = numpy.dot(q, q)
+ if nq == 0.0:
+ return numpy.identity(4, dtype=numpy.float64)
+ q *= math.sqrt(2.0 / nq)
+ q = numpy.outer(q, q)
+ return numpy.array((
+ (1.0-q[1,1]-q[2,2], q[0,1]-q[2,3], q[0,2]+q[1,3], 0.0),
+ ( q[0,1]+q[2,3], 1.0-q[0,0]-q[2,2], q[1,2]-q[0,3], 0.0),
+ ( q[0,2]-q[1,3], q[1,2]+q[0,3], 1.0-q[0,0]-q[1,1], 0.0),
+ ( 0.0, 0.0, 0.0, 1.0)
+ ), dtype=numpy.float64)
+
+def quaternion_from_rotation_matrix(matrix):
+ """Return quaternion from rotation matrix."""
+ q = numpy.empty((4,), dtype=numpy.float64)
+ M = numpy.array(matrix, dtype=numpy.float64)[0:4,0:4]
+ t = numpy.trace(M)
+ if t > M[3,3]:
+ q[3] = t
+ q[2] = M[1,0] - M[0,1]
+ q[1] = M[0,2] - M[2,0]
+ q[0] = M[2,1] - M[1,2]
+ else:
+ i,j,k = 0,1,2
+ if M[1,1] > M[0,0]:
+ i,j,k = 1,2,0
+ if M[2,2] > M[i,i]:
+ i,j,k = 2,0,1
+ t = M[i,i] - (M[j,j] + M[k,k]) + M[3,3]
+ q[i] = t
+ q[j] = M[i,j] + M[j,i]
+ q[k] = M[k,i] + M[i,k]
+ q[3] = M[k,j] - M[j,k]
+ q *= 0.5 / math.sqrt(t * M[3,3])
+ return q
+
+def quaternion_multiply(q1, q0):
+ """Multiply two quaternions."""
+ x0, y0, z0, w0 = q0
+ x1, y1, z1, w1 = q1
+ return numpy.array((
+ x1*w0 + y1*z0 - z1*y0 + w1*x0,
+ -x1*z0 + y1*w0 + z1*x0 + w1*y0,
+ x1*y0 - y1*x0 + z1*w0 + w1*z0,
+ -x1*x0 - y1*y0 - z1*z0 + w1*w0))
+
+def quaternion_from_sphere_points(v0, v1):
+ """Return quaternion from two points on unit sphere.
+
+ v0 -- E.g. sphere coordinates of cursor at mouse down
+ v1 -- E.g. current sphere coordinates of cursor
+
+ """
+ x, y, z = numpy.cross(v0, v1)
+ return x, y, z, numpy.dot(v0, v1)
+
+def quaternion_to_sphere_points(q):
+ """Return two points on unit sphere from quaternion."""
+ l = math.sqrt(q[0]*q[0] + q[1]*q[1])
+ v0 = numpy.array((0.0, 1.0, 0.0) if l==0.0 else \
+ (-q[1]/l, q[0]/l, 0.0), dtype=numpy.float64)
+ v1 = numpy.array((q[3]*v0[0] - q[3]*v0[1],
+ q[3]*v0[1] + q[3]*v0[0],
+ q[0]*v0[1] - q[1]*v0[0]), dtype=numpy.float64)
+ if q[3] < 0.0:
+ v0 *= -1.0
+ return v0, v1
+
+
+class Arcball(object):
+ """Virtual Trackball Control."""
+
+ def __init__(self, center=None, radius=1.0, initial=None):
+ """Initializes virtual trackball control.
+
+ center -- Window coordinates of trackball center
+ radius -- Radius of trackball in window coordinates
+ initial -- Initial quaternion or rotation matrix
+
+ """
+ self.axis = None
+ self.center = numpy.zeros((3,), dtype=numpy.float64)
+ self.place(center, radius)
+ self.v0 = numpy.array([0., 0., 1.], dtype=numpy.float64)
+ if initial is None:
+ self.q0 = numpy.array([0., 0., 0., 1.], dtype=numpy.float64)
+ else:
+ try:
+ self.q0 = quaternion_from_rotation_matrix(initial)
+ except:
+ self.q0 = initial
+ self.qnow = self.q0
+
+ def place(self, center=[0., 0.], radius=1.0):
+ """Place Arcball, e.g. when window size changes."""
+ self.radius = float(radius)
+ self.center[0:2] = center[0:2]
+
+ def click(self, position, axis=None):
+ """Set axis constraint and initial window coordinates of cursor."""
+ self.axis = axis
+ self.q0 = self.qnow
+ self.v0 = self._map_to_sphere(position, self.center, self.radius)
+
+ def drag(self, position):
+ """Return rotation matrix from updated window coordinates of cursor."""
+ v0 = self.v0
+ v1 = self._map_to_sphere(position, self.center, self.radius)
+
+ if self.axis is not None:
+ v0 = self._constrain_to_axis(v0, self.axis)
+ v1 = self._constrain_to_axis(v1, self.axis)
+
+ t = numpy.cross(v0, v1)
+ if numpy.dot(t, t) < _EPS:
+ # v0 and v1 coincide. no additional rotation
+ self.qnow = self.q0
+ else:
+ q1 = [t[0], t[1], t[2], numpy.dot(v0, v1)]
+ self.qnow = quaternion_multiply(q1, self.q0)
+
+ return rotation_matrix_from_quaternion(self.qnow)
+
+ def _map_to_sphere(self, position, center, radius):
+ """Map window coordinates to unit sphere coordinates."""
+ v = numpy.array([position[0], position[1], 0.0], dtype=numpy.float64)
+ v -= center
+ v /= radius
+ v[1] *= -1
+ l = numpy.dot(v, v)
+ if l > 1.0:
+ v /= math.sqrt(l) # position outside of sphere
+ else:
+ v[2] = math.sqrt(1.0 - l)
+ return v
+
+ def _constrain_to_axis(self, point, axis):
+ """Return sphere point perpendicular to axis."""
+ v = numpy.array(point, dtype=numpy.float64)
+ a = numpy.array(axis, dtype=numpy.float64, copy=True)
+ a /= numpy.dot(a, v)
+ v -= a # on plane
+ n = numpy.dot(v, v)
+ if n > 0.0:
+ v /= math.sqrt(n)
+ return v
+ if a[2] == 1.0:
+ return numpy.array([1.0, 0.0, 0.0], dtype=numpy.float64)
+ v[:] = -a[1], a[0], 0.0
+ v /= math.sqrt(numpy.dot(v, v))
+ return v
+
+ def _nearest_axis(self, point, *axes):
+ """Return axis, which arc is nearest to point."""
+ nearest = None
+ max = -1.0
+ for axis in axes:
+ t = numpy.dot(self._constrain_to_axis(point, axis), point)
+ if t > max:
+ nearest = axis
+ max = d
+ return nearest
+
+# axis sequences for Euler angles
+_NEXT_AXIS = [1, 2, 0, 1]
+_AXES2TUPLE = { # axes string -> (inner axis, parity, repetition, frame)
+ "sxyz": (0, 0, 0, 0), "sxyx": (0, 0, 1, 0), "sxzy": (0, 1, 0, 0),
+ "sxzx": (0, 1, 1, 0), "syzx": (1, 0, 0, 0), "syzy": (1, 0, 1, 0),
+ "syxz": (1, 1, 0, 0), "syxy": (1, 1, 1, 0), "szxy": (2, 0, 0, 0),
+ "szxz": (2, 0, 1, 0), "szyx": (2, 1, 0, 0), "szyz": (2, 1, 1, 0),
+ "rzyx": (0, 0, 0, 1), "rxyx": (0, 0, 1, 1), "ryzx": (0, 1, 0, 1),
+ "rxzx": (0, 1, 1, 1), "rxzy": (1, 0, 0, 1), "ryzy": (1, 0, 1, 1),
+ "rzxy": (1, 1, 0, 1), "ryxy": (1, 1, 1, 1), "ryxz": (2, 0, 0, 1),
+ "rzxz": (2, 0, 1, 1), "rxyz": (2, 1, 0, 1), "rzyz": (2, 1, 1, 1)}
+_TUPLE2AXES = dict((v, k) for k, v in _AXES2TUPLE.items())
+
+try:
+ # import faster functions from C extension module
+ import _vlfdlib
+ rotation_matrix_from_quaternion = _vlfdlib.quaternion_to_matrix
+ quaternion_from_rotation_matrix = _vlfdlib.quaternion_from_matrix
+ quaternion_multiply = _vlfdlib.quaternion_multiply
+except ImportError:
+ pass
+
+def test_transformations_module(*args, **kwargs):
+ """Test transformation module."""
+ v = numpy.array([6.67,3.69,4.82], dtype=numpy.float64)
+ I = numpy.identity(4, dtype=numpy.float64)
+ T = translation_matrix(-v)
+ M = mirror_matrix([0,0,0], v)
+ R = rotation_matrix(math.pi, [1,0,0], point=v)
+ P = projection_matrix(-v, v, perspective=10*v)
+ P = projection_matrix(-v, v, direction=v)
+ P = projection_matrix(-v, v)
+ S = scaling_matrix(0.25, v, direction=None) # reduce size
+ S = scaling_matrix(-1.0) # point symmetry
+ S = scaling_matrix(10.0)
+ O = orthogonalization_matrix(10.0, 10.0, 10.0, 90.0, 90.0, 90.0)
+ assert numpy.allclose(S, O)
+
+ angles = (1, -2, 3)
+ for axes in sorted(_AXES2TUPLE.keys()):
+ assert axes == _TUPLE2AXES[_AXES2TUPLE[axes]]
+ Me = rotation_matrix_from_euler(axes=axes, *angles)
+ em = euler_from_rotation_matrix(Me, axes)
+ Mf = rotation_matrix_from_euler(axes=axes, *em)
+ assert numpy.allclose(Me, Mf)
+
+ axes = 'sxyz'
+ euler = (0.0, 0.2, 0.0)
+ qe = quaternion_from_euler(axes=axes, *euler)
+ Mr = rotation_matrix(0.2, [0,1,0])
+ Me = rotation_matrix_from_euler(axes=axes, *euler)
+ Mq = rotation_matrix_from_quaternion(qe)
+ assert numpy.allclose(Mr, Me)
+ assert numpy.allclose(Mr, Mq)
+ em = euler_from_rotation_matrix(Mr, axes)
+ eq = euler_from_quaternion(qe, axes)
+ assert numpy.allclose(em, eq)
+ qm = quaternion_from_rotation_matrix(Mq)
+ assert numpy.allclose(qe, qm)
+
+ assert numpy.allclose(
+ rotation_matrix_from_quaternion(
+ quaternion_about_axis(1.0, [1,-0.5,1])),
+ rotation_matrix(1.0, [1,-0.5,1]))
+
+ ball = Arcball([320,320], 320)
+ ball.click([500,250])
+ R = ball.drag([475, 275])
+ assert numpy.allclose(R, [[ 0.9787566, 0.03798976, -0.20147528, 0.],
+ [-0.06854143, 0.98677273, -0.14690692, 0.],
+ [ 0.19322935, 0.15759552, 0.9684142, 0.],
+ [ 0., 0., 0., 1.]])
+
+if __name__ == "__main__":
+ test_transformations_module()
+
Deleted: pkg/trunk/prcore/tf/src/transformations.py
===================================================================
--- pkg/trunk/prcore/tf/src/transformations.py 2009-03-02 17:56:22 UTC (rev 11986)
+++ pkg/trunk/prcore/tf/src/transformations.py 2009-03-02 18:15:46 UTC (rev 11987)
@@ -1,647 +0,0 @@
-# -*- coding: utf-8 -*-
-# transformations.py
-
-# Copyright (c) 2006-2007, Christoph Gohlke
-# Copyright (c) 2006-2007, The Regents of the University of California
-# 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 copyright holders nor the names of any
-# 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.
-
-# Source: http://lfd.uci.edu/~gohlke/code/transformations.py.html
-
-"""Homogeneous Transformation Matrices and Quaternions.
-
-Functions for calculating 4x4 matrices for translating, rotating, mirroring,
-scaling, projecting, orthogonalization, and superimposition of arrays of
-homogenous coordinates as well as for converting between rotation matrices,
-Euler angles, and quaternions.
-
-Matrices can be inverted using numpy.linalg.inv(M), concatenated using
-numpy.dot(M0,M1), or used to transform homogeneous points using
-numpy.dot(v, M) for shape (4,*) "point of arrays", respectively
-numpy.dot(v, M.T) for shape (*,4) "array of points".
-
-Quaternions ix+jy+kz+w are represented as [x, y, z, w].
-
-Angles are in radians unless specified otherwise.
-
-The 24 ways of specifying rotations for a given triple of Euler angles,
-can be represented by a 4 character string or encoded 4-tuple:
-
- Axes 4-string:
- first character -- rotations are applied to 's'tatic or 'r'otating frame
- remaining characters -- successive rotation axis 'x', 'y', or 'z'
- Axes 4-tuple:
- inner axis -- code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix.
- parity -- even (0) if inner axis 'x' is followed by 'y', 'y' is followed
- by 'z', or 'z' is followed by 'x'. Otherwise odd (1).
- repetition -- first and last axis are same (1) or different (0).
- frame -- rotations are applied to static (0) or rotating (1) frame.
- Examples of tuple codes:
- 'sxyz' <-> (0, 0, 0, 0)
- 'ryxy' <-> (1, 1, 1, 1)
-
-Author:
- Christoph Gohlke, http://www.lfd.uci.edu/~gohlke/
- Laboratory for Fluorescence Dynamics, University of California, Irvine
-
-Requirements:
- Python 2.5 (http://www.python.org)
- Numpy 1.0 (http://numpy.scipy.org)
-
-References:
-(1) Matrices and Transformations. Ronald Goldman.
- In "Graphics Gems I", pp 472-475. Morgan Kaufmann, 1990.
-(2) Euler Angle Conversion. Ken Shoemake.
- In "Graphics Gems IV", pp 222-229. Morgan Kaufmann, 1994.
-(3) Arcball Rotation Control. Ken Shoemake.
- In "Graphics Gems IV", pp 175-192. Morgan Kaufmann, 1994.
-
-"""
-
-from __future__ import division
-
-import math
-import numpy
-
-_EPS = numpy.finfo(float).eps * 4.0
-
-def concatenate_transforms(*args):
- "...
[truncated message content] |
|
From: <is...@us...> - 2009-03-02 17:51:11
|
Revision: 11985
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=11985&view=rev
Author: isucan
Date: 2009-03-02 17:51:01 +0000 (Mon, 02 Mar 2009)
Log Message:
-----------
cleaning up the way we deal with shapes
Modified Paths:
--------------
pkg/trunk/deprecated/robot_filter/include/robot_filter/RobotFilter.h
pkg/trunk/deprecated/robot_filter/src/robot_filter.cpp
pkg/trunk/motion_planning/kinematic_planning/include/kinematic_planning/CollisionSpaceMonitor.h
pkg/trunk/motion_planning/kinematic_planning/src/display_planner_collision_model.cpp
pkg/trunk/motion_planning/test_collision_space/CMakeLists.txt
pkg/trunk/motion_planning/test_collision_space/manifest.xml
pkg/trunk/world_models/robot_models/collision_space/CMakeLists.txt
pkg/trunk/world_models/robot_models/collision_space/include/collision_space/environmentODE.h
pkg/trunk/world_models/robot_models/collision_space/src/collision_space/environmentODE.cpp
pkg/trunk/world_models/robot_models/planning_models/include/planning_models/kinematic.h
pkg/trunk/world_models/robot_models/planning_models/src/kinematic.cpp
Added Paths:
-----------
pkg/trunk/motion_planning/test_collision_space/src/test_cs_point_inclusion.cpp
pkg/trunk/world_models/robot_models/collision_space/include/collision_space/point_inclusion.h
pkg/trunk/world_models/robot_models/collision_space/src/collision_space/point_inclusion.cpp
pkg/trunk/world_models/robot_models/collision_space/test/test_point_inclusion.cpp
pkg/trunk/world_models/robot_models/planning_models/include/planning_models/shapes.h
Removed Paths:
-------------
pkg/trunk/motion_planning/test_collision_space/src/test_cs_util.cpp
pkg/trunk/world_models/robot_models/collision_space/include/collision_space/util.h
pkg/trunk/world_models/robot_models/collision_space/test/test_util.cpp
Modified: pkg/trunk/deprecated/robot_filter/include/robot_filter/RobotFilter.h
===================================================================
--- pkg/trunk/deprecated/robot_filter/include/robot_filter/RobotFilter.h 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/deprecated/robot_filter/include/robot_filter/RobotFilter.h 2009-03-02 17:51:01 UTC (rev 11985)
@@ -35,7 +35,7 @@
/** \author Ioan Sucan */
-#include <collision_space/util.h>
+#include <collision_space/point_inclusion.h>
#include <robot_model/knode.h>
@@ -73,7 +73,7 @@
class RobotFilter {
private:
struct RobotPart {
- collision_space::bodies::Shape *body;
+ collision_space::bodies::Body *body;
planning_models::KinematicModel::Link *link;
};
std::vector<RobotPart> m_selfSeeParts;
Modified: pkg/trunk/deprecated/robot_filter/src/robot_filter.cpp
===================================================================
--- pkg/trunk/deprecated/robot_filter/src/robot_filter.cpp 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/deprecated/robot_filter/src/robot_filter.cpp 2009-03-02 17:51:01 UTC (rev 11985)
@@ -77,37 +77,8 @@
if (link)
{
RobotPart rp = { NULL, link };
-
- switch (link->shape->type)
- {
- case planning_models::KinematicModel::Shape::BOX:
- rp.body = new collision_space::bodies::Box();
- {
- const double* size = static_cast<planning_models::KinematicModel::Box*>(link->shape)->size;
- rp.body->setDimensions(size);
- }
- break;
- case planning_models::KinematicModel::Shape::SPHERE:
- rp.body = new collision_space::bodies::Sphere();
- {
- double size[1];
- size[0] = static_cast<planning_models::KinematicModel::Sphere*>(link->shape)->radius;
- rp.body->setDimensions(size);
- }
- break;
- case planning_models::KinematicModel::Shape::CYLINDER:
- rp.body = new collision_space::bodies::Cylinder();
- {
- double size[2];
- size[0] = static_cast<planning_models::KinematicModel::Cylinder*>(link->shape)->length;
- size[1] = static_cast<planning_models::KinematicModel::Cylinder*>(link->shape)->radius;
- rp.body->setDimensions(size);
- }
- break;
- default:
- break;
- }
-
+ rp.body = collision_space::bodies::createBodyFromShape(link->shape);
+
if (!rp.body)
{
fprintf(stderr, "Unknown body type: %d\n", link->shape->type);
Modified: pkg/trunk/motion_planning/kinematic_planning/include/kinematic_planning/CollisionSpaceMonitor.h
===================================================================
--- pkg/trunk/motion_planning/kinematic_planning/include/kinematic_planning/CollisionSpaceMonitor.h 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/motion_planning/kinematic_planning/include/kinematic_planning/CollisionSpaceMonitor.h 2009-03-02 17:51:01 UTC (rev 11985)
@@ -151,7 +151,7 @@
link->attachedBodies[i]->attachTrans.setOrigin(btVector3(centerP.point.x, centerP.point.y, centerP.point.z));
// this is a HACK! we should have orientation
- planning_models::KinematicModel::Box *box = new planning_models::KinematicModel::Box();
+ planning_models::shapes::Box *box = new planning_models::shapes::Box();
box->size[0] = m_attachedObject.objects[i].max_bound.x - m_attachedObject.objects[i].min_bound.x;
box->size[1] = m_attachedObject.objects[i].max_bound.y - m_attachedObject.objects[i].min_bound.y;
box->size[2] = m_attachedObject.objects[i].max_bound.z - m_attachedObject.objects[i].min_bound.z;
Modified: pkg/trunk/motion_planning/kinematic_planning/src/display_planner_collision_model.cpp
===================================================================
--- pkg/trunk/motion_planning/kinematic_planning/src/display_planner_collision_model.cpp 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/motion_planning/kinematic_planning/src/display_planner_collision_model.cpp 2009-03-02 17:51:01 UTC (rev 11985)
@@ -134,7 +134,7 @@
header.frame_id = link->name;
for (unsigned int i = 0 ; i < link->attachedBodies.size() ; ++i)
{
- planning_models::KinematicModel::Box *box = dynamic_cast<planning_models::KinematicModel::Box*>(link->attachedBodies[i]->shape);
+ planning_models::shapes::Box *box = dynamic_cast<planning_models::shapes::Box*>(link->attachedBodies[i]->shape);
if (box)
{
btVector3 &v = link->attachedBodies[i]->attachTrans.getOrigin();
Modified: pkg/trunk/motion_planning/test_collision_space/CMakeLists.txt
===================================================================
--- pkg/trunk/motion_planning/test_collision_space/CMakeLists.txt 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/motion_planning/test_collision_space/CMakeLists.txt 2009-03-02 17:51:01 UTC (rev 11985)
@@ -2,4 +2,4 @@
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
rospack(test_collision_space)
-rospack_add_executable(test_cs_util src/test_cs_util.cpp)
+rospack_add_executable(test_cs_point_inclusion src/test_cs_point_inclusion.cpp)
Modified: pkg/trunk/motion_planning/test_collision_space/manifest.xml
===================================================================
--- pkg/trunk/motion_planning/test_collision_space/manifest.xml 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/motion_planning/test_collision_space/manifest.xml 2009-03-02 17:51:01 UTC (rev 11985)
@@ -12,6 +12,7 @@
<depend package="roslib"/>
<depend package="robot_msgs"/>
+ <depend package="planning_models"/>
<depend package="collision_space"/>
</package>
Copied: pkg/trunk/motion_planning/test_collision_space/src/test_cs_point_inclusion.cpp (from rev 11980, pkg/trunk/motion_planning/test_collision_space/src/test_cs_util.cpp)
===================================================================
--- pkg/trunk/motion_planning/test_collision_space/src/test_cs_point_inclusion.cpp (rev 0)
+++ pkg/trunk/motion_planning/test_collision_space/src/test_cs_point_inclusion.cpp 2009-03-02 17:51:01 UTC (rev 11985)
@@ -0,0 +1,258 @@
+/*********************************************************************
+* 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 <cstdlib>
+#include <ros/node.h>
+#include <ros/publisher.h>
+#include <ros/time.h>
+#include <collision_space/environmentODE.h>
+#include <algorithm>
+#include <robot_msgs/VisualizationMarker.h>
+#include <roslib/Time.h>
+#include <collision_space/point_inclusion.h>
+using namespace collision_space;
+
+const int TEST_TIMES = 3;
+const int TEST_POINTS = 50000;
+
+class TestVM
+{
+public:
+
+ TestVM(void) : m_node("TVM")
+ {
+ m_node.advertise<robot_msgs::VisualizationMarker>("visualizationMarker", 10240);
+ m_id = 1;
+ }
+
+ virtual ~TestVM(void)
+ {
+ }
+
+ void sendPoint(double x, double y, double z)
+ {
+ robot_msgs::VisualizationMarker mk;
+
+ mk.header.stamp = m_tm;
+
+ mk.header.frame_id = "base_link";
+
+ mk.id = m_id++;
+ mk.type = robot_msgs::VisualizationMarker::SPHERE;
+ mk.action = robot_msgs::VisualizationMarker::ADD;
+ mk.x = x;
+ mk.y = y;
+ mk.z = z;
+
+ mk.roll = 0;
+ mk.pitch = 0;
+ mk.yaw = 0;
+
+ mk.xScale = 0.2;
+ mk.yScale = 0.2;
+ mk.zScale = 0.2;
+
+ mk.alpha = 255;
+ mk.r = 255;
+ mk.g = 10;
+ mk.b = 10;
+
+ m_node.publish("visualizationMarker", mk);
+ }
+
+ void testShape(collision_space::bodies::Body *s)
+ {
+ for (int i = 0 ; i < TEST_POINTS ; ++i)
+ {
+ double x = uniform(5.0);
+ double y = uniform(5.0);
+ double z = uniform(5.0);
+ if (!s->containsPoint(x, y, z))
+ continue;
+ sendPoint(x, y, z);
+ }
+ }
+
+ void setShapeTransformAndMarker(collision_space::bodies::Body *s,
+ robot_msgs::VisualizationMarker &mk)
+ {
+ btTransform t;
+
+ double yaw = uniform(M_PI);
+ double pitch = uniform(M_PI);
+ double roll = uniform(M_PI);
+
+ double x = uniform(3.0);
+ double y = uniform(3.0);
+ double z = uniform(3.0);
+
+ t.setRotation(btQuaternion(yaw, pitch, roll));
+ t.setOrigin(btVector3(btScalar(x), btScalar(y), btScalar(z)));
+
+ s->setPose(t);
+ s->setScale(0.99);
+
+ mk.header.stamp = m_tm;
+ mk.header.frame_id = "base_link";
+ mk.id = m_id++;
+
+ mk.action = robot_msgs::VisualizationMarker::ADD;
+
+ mk.x = x;
+ mk.y = y;
+ mk.z = z;
+
+ mk.roll = roll;
+ mk.pitch = pitch;
+ mk.yaw = yaw;
+
+ mk.alpha = 150;
+ mk.r = 0;
+ mk.g = 100;
+ mk.b = 255;
+ }
+
+ void testSphere(void)
+ {
+ planning_models::shapes::Sphere shape(2.0);
+ collision_space::bodies::Body *s = new collision_space::bodies::Sphere(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::SPHERE;
+ mk.xScale = shape.radius*2.0;
+ mk.yScale = shape.radius*2.0;
+ mk.zScale = shape.radius*2.0;
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void testBox(void)
+ {
+ planning_models::shapes::Box shape(2.0, 1.33, 1.5);
+ collision_space::bodies::Body *s = new collision_space::bodies::Box(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::CUBE;
+ mk.xScale = shape.size[0]; // length
+ mk.yScale = shape.size[1]; // width
+ mk.zScale = shape.size[2]; // height
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void testCylinder(void)
+ {
+ planning_models::shapes::Cylinder shape(0.5, 2.5);
+ collision_space::bodies::Body *s = new collision_space::bodies::Cylinder(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::CUBE;
+ mk.xScale = shape.radius * 2.0; // radius
+ mk.yScale = shape.radius * 2.0; // radius
+ mk.zScale = shape.length; //length
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void run()
+ {
+ ros::Duration d;
+ d.fromSec(2);
+ d.sleep();
+
+ m_tm = ros::Time::now();
+
+ testSphere();
+ testBox();
+ testCylinder();
+
+ m_node.spin();
+ m_node.shutdown();
+
+ }
+
+protected:
+
+ // return a random number (uniform distribution)
+ // between -magnitude and magnitude
+ double uniform(double magnitude)
+ {
+ return (2.0 * drand48() - 1.0) * magnitude;
+ }
+
+ ros::Node m_node;
+ ros::Time m_tm;
+ int m_id;
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+
+ TestVM tvm;
+ tvm.run();
+
+ return 0;
+}
Deleted: pkg/trunk/motion_planning/test_collision_space/src/test_cs_util.cpp
===================================================================
--- pkg/trunk/motion_planning/test_collision_space/src/test_cs_util.cpp 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/motion_planning/test_collision_space/src/test_cs_util.cpp 2009-03-02 17:51:01 UTC (rev 11985)
@@ -1,261 +0,0 @@
-/*********************************************************************
-* 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 <cstdlib>
-#include <ros/node.h>
-#include <ros/publisher.h>
-#include <ros/time.h>
-#include <collision_space/environmentODE.h>
-#include <algorithm>
-#include <robot_msgs/VisualizationMarker.h>
-#include <roslib/Time.h>
-#include <collision_space/util.h>
-using namespace collision_space;
-
-const int TEST_TIMES = 3;
-const int TEST_POINTS = 50000;
-
-class TestVM
-{
-public:
-
- TestVM(void) : m_node("TVM")
- {
- m_node.advertise<robot_msgs::VisualizationMarker>("visualizationMarker", 10240);
- m_id = 1;
- }
-
- virtual ~TestVM(void)
- {
- }
-
- void sendPoint(double x, double y, double z)
- {
- robot_msgs::VisualizationMarker mk;
-
- mk.header.stamp = m_tm;
-
- mk.header.frame_id = "base_link";
-
- mk.id = m_id++;
- mk.type = robot_msgs::VisualizationMarker::SPHERE;
- mk.action = robot_msgs::VisualizationMarker::ADD;
- mk.x = x;
- mk.y = y;
- mk.z = z;
-
- mk.roll = 0;
- mk.pitch = 0;
- mk.yaw = 0;
-
- mk.xScale = 0.2;
- mk.yScale = 0.2;
- mk.zScale = 0.2;
-
- mk.alpha = 255;
- mk.r = 255;
- mk.g = 10;
- mk.b = 10;
-
- m_node.publish("visualizationMarker", mk);
- }
-
- void testShape(collision_space::bodies::Shape *s)
- {
- for (int i = 0 ; i < TEST_POINTS ; ++i)
- {
- double x = uniform(5.0);
- double y = uniform(5.0);
- double z = uniform(5.0);
- if (!s->containsPoint(x, y, z))
- continue;
- sendPoint(x, y, z);
- }
- }
-
- void setShapeTransformAndMarker(collision_space::bodies::Shape *s,
- robot_msgs::VisualizationMarker &mk)
- {
- btTransform t;
-
- double yaw = uniform(M_PI);
- double pitch = uniform(M_PI);
- double roll = uniform(M_PI);
-
- double x = uniform(3.0);
- double y = uniform(3.0);
- double z = uniform(3.0);
-
- t.setRotation(btQuaternion(yaw, pitch, roll));
- t.setOrigin(btVector3(btScalar(x), btScalar(y), btScalar(z)));
-
- s->setPose(t);
- s->setScale(0.99);
-
- mk.header.stamp = m_tm;
- mk.header.frame_id = "base_link";
- mk.id = m_id++;
-
- mk.action = robot_msgs::VisualizationMarker::ADD;
-
- mk.x = x;
- mk.y = y;
- mk.z = z;
-
- mk.roll = roll;
- mk.pitch = pitch;
- mk.yaw = yaw;
-
- mk.alpha = 150;
- mk.r = 0;
- mk.g = 100;
- mk.b = 255;
- }
-
- void testSphere(void)
- {
- collision_space::bodies::Shape *s = new collision_space::bodies::Sphere();
- double radius[1] = {2.0};
- s->setDimensions(radius);
-
- for (int i = 0 ; i < TEST_TIMES ; ++i)
- {
- robot_msgs::VisualizationMarker mk;
- setShapeTransformAndMarker(s, mk);
-
- mk.type = robot_msgs::VisualizationMarker::SPHERE;
- mk.xScale = radius[0]*2.0;
- mk.yScale = radius[0]*2.0;
- mk.zScale = radius[0]*2.0;
-
- m_node.publish("visualizationMarker", mk);
-
- testShape(s);
- }
-
- delete s;
- }
-
- void testBox(void)
- {
- collision_space::bodies::Shape *s = new collision_space::bodies::Box();
- double dims[3] = {2.0, 1.33, 1.5};
- s->setDimensions(dims);
-
- for (int i = 0 ; i < TEST_TIMES ; ++i)
- {
- robot_msgs::VisualizationMarker mk;
- setShapeTransformAndMarker(s, mk);
-
- mk.type = robot_msgs::VisualizationMarker::CUBE;
- mk.xScale = dims[0]; // length
- mk.yScale = dims[1]; // width
- mk.zScale = dims[2]; // height
-
- m_node.publish("visualizationMarker", mk);
-
- testShape(s);
- }
-
- delete s;
- }
-
- void testCylinder(void)
- {
- collision_space::bodies::Shape *s = new collision_space::bodies::Cylinder();
- double dims[2] = {2.5, 0.5};
- s->setDimensions(dims);
-
- for (int i = 0 ; i < TEST_TIMES ; ++i)
- {
- robot_msgs::VisualizationMarker mk;
- setShapeTransformAndMarker(s, mk);
-
- mk.type = robot_msgs::VisualizationMarker::CUBE;
- mk.xScale = dims[1] * 2.0; // radius
- mk.yScale = dims[1] * 2.0; // radius
- mk.zScale = dims[0]; //length
-
- m_node.publish("visualizationMarker", mk);
-
- testShape(s);
- }
-
- delete s;
- }
-
- void run()
- {
- ros::Duration d;
- d.fromSec(2);
- d.sleep();
-
- m_tm = ros::Time::now();
-
- testSphere();
- testBox();
- testCylinder();
-
- m_node.spin();
- m_node.shutdown();
-
- }
-
-protected:
-
- // return a random number (uniform distribution)
- // between -magnitude and magnitude
- double uniform(double magnitude)
- {
- return (2.0 * drand48() - 1.0) * magnitude;
- }
-
- ros::Node m_node;
- ros::Time m_tm;
- int m_id;
-
-};
-
-
-int main(int argc, char **argv)
-{
- ros::init(argc, argv);
-
- TestVM tvm;
- tvm.run();
-
- return 0;
-}
Modified: pkg/trunk/world_models/robot_models/collision_space/CMakeLists.txt
===================================================================
--- pkg/trunk/world_models/robot_models/collision_space/CMakeLists.txt 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/world_models/robot_models/collision_space/CMakeLists.txt 2009-03-02 17:51:01 UTC (rev 11985)
@@ -6,12 +6,13 @@
set(CMAKE_BUILD_TYPE Release)
-rospack_add_library(collision_space src/collision_space/environment.cpp
- src/collision_space/output.cpp
+rospack_add_library(collision_space src/collision_space/output.cpp
+ src/collision_space/point_inclusion.cpp
+ src/collision_space/environment.cpp
src/collision_space/environmentODE.cpp)
rospack_link_boost(collision_space thread)
# Unit tests
-rospack_add_gtest(test_util test/test_util.cpp)
-target_link_libraries(test_util collision_space)
+rospack_add_gtest(test_point_inclusion test/test_point_inclusion.cpp)
+target_link_libraries(test_point_inclusion collision_space)
Modified: pkg/trunk/world_models/robot_models/collision_space/include/collision_space/environmentODE.h
===================================================================
--- pkg/trunk/world_models/robot_models/collision_space/include/collision_space/environmentODE.h 2009-03-02 17:40:16 UTC (rev 11984)
+++ pkg/trunk/world_models/robot_models/collision_space/include/collision_space/environmentODE.h 2009-03-02 17:51:01 UTC (rev 11985)
@@ -237,7 +237,7 @@
std::vector< std::vector<unsigned int> > selfCollision;
};
- dGeomID createODEGeom(dSpaceID space, planning_models::KinematicModel::Shape *shape, double scale, double padding) const;
+ dGeomID createODEGeom(dSpaceID space, planning_models::shapes::Shape *shape, double scale, double padding) const;
void updateGeom(dGeomID geom, btTransform &pose) const;
void freeMemory(void);
Added: pkg/trunk/world_models/robot_models/collision_space/include/collision_space/point_inclusion.h
===================================================================
--- pkg/trunk/world_models/robot_models/collision_space/include/collision_space/point_inclusion.h (rev 0)
+++ pkg/trunk/world_models/robot_models/collision_space/include/collision_space/point_inclusion.h 2009-03-02 17:51:01 UTC (rev 11985)
@@ -0,0 +1,321 @@
+/*********************************************************************
+* 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 COLLISION_SPACE_POINT_INCLUSION_
+#define COLLISION_SPACE_POINT_INCLUSION_
+
+#include <planning_models/shapes.h>
+#include <LinearMath/btTransform.h>
+#include <cmath>
+
+/**
+ This set of classes allows quickly detecting whether a given point
+ is inside an object or not. Only basic (simple) types of objects
+ are supported: spheres, cylinders, boxes. This capability is useful
+ when removing points from inside the robot (when the robot sees its
+ arms, for example).
+*/
+
+namespace collision_space
+{
+
+ namespace bodies
+ {
+
+ class Body
+ {
+ public:
+ Body(void)
+ {
+ m_scale = 1.0;
+ m_padding = 0.0;
+ m_pose.setIdentity();
+ }
+
+ virtual ~Body(void)
+ {
+ }
+
+ void setScale(double scale)
+ {
+ m_scale = scale;
+ updateInternalData();
+ }
+
+ double getScale(void) const
+ {
+ return m_scale;
+ }
+
+ void setPadding(double padd)
+ {
+ m_padding = padd;
+ updateInternalData();
+ }
+
+ double getPadding(void) const
+ {
+ return m_padding;
+ }
+
+ void setPose(const btTransform &pose)
+ {
+ m_pose = pose;
+ updateInternalData();
+ }
+
+ const btTransform& getPose(void) const
+ {
+ return m_pose;
+ }
+
+ void setDimensions(const planning_models::shapes::Shape *shape)
+ {
+ useDimensions(shape);
+ updateInternalData();
+ }
+
+ bool containsPoint(double x, double y, double z) const
+ {
+ return containsPoint(btVector3(btScalar(x), btScalar(y), btScalar(z)));
+ }
+
+ virtual bool containsPoint(const btVector3 &p) const = 0;
+
+ protected:
+
+ virtual void updateInternalData(void) = 0;
+ virtual void useDimensions(const planning_models::shapes::Shape *shape) = 0;
+
+ btTransform m_pose;
+ double m_scale;
+ double m_padding;
+ };
+
+ class Sphere : public Body
+ {
+ public:
+ Sphere(void) : Body()
+ {
+ m_radius = 0.0;
+ }
+
+ Sphere(const planning_models::shapes::Shape *shape) : Body()
+ {
+ setDimensions(shape);
+ }
+
+ virtual ~Sphere(void)
+ {
+ }
+
+ virtual bool containsPoint(const btVector3 &p) const
+ {
+ return (m_center - p).length2() < m_radius2;
+ }
+
+ protected:
+
+ virtual void useDimensions(const planning_models::shapes::Shape *shape) // radius
+ {
+ m_radius = static_cast<const planning_models::shapes::Sphere*>(shape)->radius;
+ }
+
+ virtual void updateInternalData(void)
+ {
+ m_radius2 = m_radius * m_scale + m_padding;
+ m_radius2 = m_radius2 * m_radius2;
+ m_center = m_pose.getOrigin();
+ }
+
+ btVector3 m_center;
+ double m_radius;
+ double m_radius2;
+ };
+
+ class Cylinder : public Body
+ {
+ public:
+ Cylinder(void) : Body()
+ {
+ m_length = m_radius = 0.0;
+ }
+
+ Cylinder(const planning_models::shapes::Shape *shape) : Body()
+ {
+ setDimensions(shape);
+ }
+
+ virtual ~Cylinder(void)
+ {
+ }
+
+ virtual bool containsPoint(const btVector3 &p) const
+ {
+ btVector3 v = p - m_center;
+ double pH = v.dot(m_normalH);
+
+ if (fabs(pH) > m_length2)
+ return false;
+
+ double pB1 = v.dot(m_normalB1);
+ double remaining = m_radius2 - pB1 * pB1;
+
+ if (remaining < 0.0)
+ return false;
+ else
+ {
+ double pB2 = v.dot(m_normalB2);
+ return pB2 * pB2 < remaining;
+ }
+ }
+
+ protected:
+
+ virtual void useDimensions(const planning_models::shapes::Shape *shape) // (length, radius)
+ {
+ m_length = static_cast<const planning_models::shapes::Cylinder*>(shape)->length;
+ m_radius = static_cast<const planning_models::shapes::Cylinder*>(shape)->radius;
+ }
+
+ virtual void updateInternalData(void)
+ {
+ m_radius2 = m_radius * m_scale + m_padding;
+ m_radius2 = m_radius2 * m_radius2;
+ m_length2 = (m_scale * m_length + m_padding) / 2.0;
+ m_center = m_pose.getOrigin();
+
+ const btMatrix3x3& basis = m_pose.getBasis();
+ m_normalB1 = basis.getColumn(0);
+ m_normalB2 = basis.getColumn(1);
+ m_normalH = basis.getColumn(2);
+ }
+
+ btVector3 m_center;
+ btVector3 m_normalH;
+ btVector3 m_normalB1;
+ btVector3 m_normalB2;
+
+ double m_length;
+ double m_length2;
+ double m_radius;
+ double m_radius2;
+ };
+
+
+ class Box : public Body
+ {
+ public:
+ Box(void) : Body()
+ {
+ m_length = m_w...
[truncated message content] |
|
From: <is...@us...> - 2009-03-03 00:34:08
|
Revision: 12008
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12008&view=rev
Author: isucan
Date: 2009-03-03 00:34:01 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
renaming kinematic_planning to ompl_planning
Modified Paths:
--------------
pkg/trunk/demos/tabletop_manipulation/launch/planning.launch
pkg/trunk/demos/tabletop_manipulation/manifest.xml
pkg/trunk/highlevel/test_executive_trex_pr2/manifest.xml
pkg/trunk/motion_planning/plan_kinematic_path/manifest.xml
Added Paths:
-----------
pkg/trunk/motion_planning/ompl_planning/
pkg/trunk/motion_planning/ompl_planning/CMakeLists.txt
pkg/trunk/motion_planning/ompl_planning/Makefile
pkg/trunk/motion_planning/ompl_planning/include/
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/CollisionSpaceMonitor.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/KinematicStateMonitor.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPBasicRequest.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPBasicRequestLinkPosition.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPBasicRequestState.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPConstraintEvaluator.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPModel.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/RKPModelBase.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_extensions/
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_extensions/RKPDistanceEvaluators.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_extensions/RKPProjectionEvaluators.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_extensions/RKPSpaceInformation.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_extensions/RKPStateValidator.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPESTSetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPIKKPIECESetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPIKSBLSetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPKPIECESetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPLazyRRTSetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPPlannerSetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPRRTSetup.h
pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/ompl_planner/RKPSBLSetup.h
pkg/trunk/motion_planning/ompl_planning/manifest.xml
pkg/trunk/motion_planning/ompl_planning/motion_planning.launch
pkg/trunk/motion_planning/ompl_planning/src/
pkg/trunk/motion_planning/ompl_planning/src/display_planner_collision_model.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPESTSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPIKKPIECESetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPIKSBLSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPKPIECESetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPLazyRRTSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPPlannerSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPRRTSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/helpers/ompl_planner/RKPSBLSetup.cpp
pkg/trunk/motion_planning/ompl_planning/src/motion_planner.cpp
pkg/trunk/motion_planning/ompl_planning/src/motion_validator.cpp
pkg/trunk/motion_planning/ompl_planning/src/state_validity_monitor.cpp
pkg/trunk/motion_planning/ompl_planning/test/
pkg/trunk/motion_planning/ompl_planning/test/CMakeLists.txt
pkg/trunk/motion_planning/ompl_planning/test/avoid_monster.cpp
pkg/trunk/motion_planning/ompl_planning/test/avoid_monster.xml
pkg/trunk/motion_planning/ompl_planning/test/monster.bag
Removed Paths:
-------------
pkg/trunk/motion_planning/kinematic_planning/
Modified: pkg/trunk/demos/tabletop_manipulation/launch/planning.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/planning.launch 2009-03-03 00:21:14 UTC (rev 12007)
+++ pkg/trunk/demos/tabletop_manipulation/launch/planning.launch 2009-03-03 00:34:01 UTC (rev 12008)
@@ -2,7 +2,7 @@
<param name="refresh_interval_collision_map" type="double" value="5.0" />
<param name="refresh_interval_kinematic_state" type="double" value="0.2" />
<param name="refresh_interval_base_pose" type="double" value="0.2" />
- <node pkg="kinematic_planning" type="kinematic_planning" args="robot_description:=robotdesc/pr2 collision_map:=collision_map_buffer" respawn="true" output="screen" />
+ <node pkg="ompl_planning" type="motion_planner" args="robot_description:=robotdesc/pr2 collision_map:=collision_map_buffer" respawn="true" output="screen" />
<!--node pkg="highlevel_controllers" type="move_arm2" args="right">
<remap from="robot_description" to="robotdesc/pr2"/>
</node-->
Modified: pkg/trunk/demos/tabletop_manipulation/manifest.xml
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/manifest.xml 2009-03-03 00:21:14 UTC (rev 12007)
+++ pkg/trunk/demos/tabletop_manipulation/manifest.xml 2009-03-03 00:34:01 UTC (rev 12008)
@@ -10,7 +10,7 @@
<depend package="point_cloud_assembler"/>
<depend package="table_object_detector"/>
<depend package="collision_map"/>
- <depend package="kinematic_planning"/>
+ <depend package="ompl_planning"/>
<depend package="executive_python"/>
<depend package="plan_kinematic_path"/>
<depend package="pr2_msgs"/>
Modified: pkg/trunk/highlevel/test_executive_trex_pr2/manifest.xml
===================================================================
--- pkg/trunk/highlevel/test_executive_trex_pr2/manifest.xml 2009-03-03 00:21:14 UTC (rev 12007)
+++ pkg/trunk/highlevel/test_executive_trex_pr2/manifest.xml 2009-03-03 00:34:01 UTC (rev 12008)
@@ -21,6 +21,6 @@
<depend package="point_cloud_assembler"/>
<depend package="collision_map"/>
<depend package="laser_scan"/>
- <depend package="kinematic_planning"/>
+ <depend package="ompl_planning"/>
<depend package="robot_pose_ekf"/>
</package>
Added: pkg/trunk/motion_planning/ompl_planning/CMakeLists.txt
===================================================================
--- pkg/trunk/motion_planning/ompl_planning/CMakeLists.txt (rev 0)
+++ pkg/trunk/motion_planning/ompl_planning/CMakeLists.txt 2009-03-03 00:34:01 UTC (rev 12008)
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.4.6)
+include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
+rospack(ompl_planning)
+
+rospack_add_boost_directories()
+
+rospack_add_library(ompl_planning_helpers src/helpers/ompl_planner/RKPPlannerSetup.cpp
+ src/helpers/ompl_planner/RKPESTSetup.cpp
+ src/helpers/ompl_planner/RKPIKSBLSetup.cpp
+ src/helpers/ompl_planner/RKPLazyRRTSetup.cpp
+ src/helpers/ompl_planner/RKPRRTSetup.cpp
+ src/helpers/ompl_planner/RKPIKKPIECESetup.cpp
+ src/helpers/ompl_planner/RKPKPIECESetup.cpp
+ src/helpers/ompl_planner/RKPSBLSetup.cpp
+ )
+
+rospack_add_executable(motion_planner src/motion_planner.cpp)
+rospack_add_executable(motion_validator src/motion_validator.cpp)
+rospack_add_executable(state_validity_monitor src/state_validity_monitor.cpp)
+rospack_add_executable(display_planner_collision_model src/display_planner_collision_model.cpp)
+
+rospack_link_boost(motion_planner thread)
+rospack_link_boost(motion_validator thread)
+rospack_link_boost(state_validity_monitor thread)
+rospack_link_boost(display_planner_collision_model thread)
+
+target_link_libraries(motion_planner ompl_planning_helpers)
+target_link_libraries(motion_validator ompl_planning_helpers)
+target_link_libraries(state_validity_monitor ompl_planning_helpers)
+target_link_libraries(display_planner_collision_model ompl_planning_helpers)
+
+add_subdirectory(test)
Added: pkg/trunk/motion_planning/ompl_planning/Makefile
===================================================================
--- pkg/trunk/motion_planning/ompl_planning/Makefile (rev 0)
+++ pkg/trunk/motion_planning/ompl_planning/Makefile 2009-03-03 00:34:01 UTC (rev 12008)
@@ -0,0 +1 @@
+include $(shell rospack find mk)/cmake.mk
Added: pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/CollisionSpaceMonitor.h
===================================================================
--- pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/CollisionSpaceMonitor.h (rev 0)
+++ pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/CollisionSpaceMonitor.h 2009-03-03 00:34:01 UTC (rev 12008)
@@ -0,0 +1,292 @@
+/*********************************************************************
+* 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 "kinematic_planning/KinematicStateMonitor.h"
+#include <collision_space/environmentODE.h>
+
+#include <robot_msgs/PointCloud.h>
+#include <robot_msgs/CollisionMap.h>
+#include <robot_msgs/AttachedObject.h>
+#include <robot_srvs/CollisionCheckState.h>
+
+/** Main namespace */
+namespace kinematic_planning
+{
+
+ /**
+
+ @b CollisionSpaceMonitor is a class which in addition to being aware of a robot model,
+ is also aware of a collision space.
+
+ <hr>
+
+ @section topic ROS topics
+
+ Subscribes to (name/type):
+ - @b "collision_map"/CollisionMap : data describing the 3D environment
+ - @b "attach_object"/AttachedObject : data describing an object to be attached to a link
+
+ Publishes to (name/type):
+ - None
+
+ <hr>
+
+ @section services ROS services
+
+ Uses (name/type):
+ - None
+
+ Provides (name/type):
+ - @b "set_collision_state"/CollisionCheckState : service to allow enabling and disabling collision checking for links
+
+ <hr>
+
+ @section notes Notes
+
+ This class inherits from KinematicStateMonitor. Additional
+ relevant topics, services and parameters are documented in
+ KinematicStateMonitor.
+
+ This class uses the following special groups (from the URDF document)
+
+ - "collision_check" with the flag "collision": if present, this is used
+ to define the links of the robot that are to be checked for
+ collision. If not present, NO COLLISION CHECKING IS PERFORMED!
+
+ - any group name with the flag "self_collision": checks the links in
+ each group for collision against every other link in the same group.
+
+ **/
+
+ class CollisionSpaceMonitor : public KinematicStateMonitor
+ {
+
+ public:
+
+ CollisionSpaceMonitor(ros::Node *node, collision_space::EnvironmentModel *collisionSpace = NULL) : KinematicStateMonitor(node)
+ {
+ if (collisionSpace)
+ m_collisionSpace = collisionSpace;
+ else
+ m_collisionSpace = new collision_space::EnvironmentModelODE();
+ m_collisionSpace->setSelfCollision(true);
+ // hack for having ground plane
+ m_collisionSpace->addStaticPlane(0.0, 0.0, 1.0, -0.01);
+
+ m_node->subscribe("collision_map", m_collisionMap, &CollisionSpaceMonitor::collisionMapCallback, this, 1);
+ m_node->advertiseService("set_collision_state", &CollisionSpaceMonitor::setCollisionState, this);
+
+ m_node->subscribe("attach_object", m_attachedObject, &CollisionSpaceMonitor::attachObject, this, 1);
+ }
+
+ virtual ~CollisionSpaceMonitor(void)
+ {
+ if (m_collisionSpace)
+ {
+ delete m_collisionSpace;
+ m_kmodel = NULL;
+ }
+ }
+
+ void attachObject(void)
+ {
+ m_collisionSpace->lock();
+ int model_id = m_collisionSpace->getModelID(m_attachedObject.robot_name);
+ planning_models::KinematicModel::Link *link = model_id >= 0 ? m_kmodel->getLink(m_attachedObject.link_name) : NULL;
+
+ if (link)
+ {
+ // clear the previously attached bodies
+ for (unsigned int i = 0 ; i < link->attachedBodies.size() ; ++i)
+ delete link->attachedBodies[i];
+ unsigned int n = m_attachedObject.get_objects_size();
+ link->attachedBodies.resize(n);
+
+ // create the new ones
+ for (unsigned int i = 0 ; i < n ; ++i)
+ {
+ link->attachedBodies[i] = new planning_models::KinematicModel::AttachedBody();
+
+ robot_msgs::PointStamped center;
+ robot_msgs::PointStamped centerP;
+ center.point.x = m_attachedObject.objects[i].center.x;
+ center.point.y = m_attachedObject.objects[i].center.y;
+ center.point.z = m_attachedObject.objects[i].center.z;
+ center.header = m_attachedObject.header;
+ m_tf.transformPoint(m_attachedObject.link_name, center, centerP);
+
+ link->attachedBodies[i]->attachTrans.setOrigin(btVector3(centerP.point.x, centerP.point.y, centerP.point.z));
+
+ // this is a HACK! we should have orientation
+ planning_models::shapes::Box *box = new planning_models::shapes::Box();
+ box->size[0] = m_attachedObject.objects[i].max_bound.x - m_attachedObject.objects[i].min_bound.x;
+ box->size[1] = m_attachedObject.objects[i].max_bound.y - m_attachedObject.objects[i].min_bound.y;
+ box->size[2] = m_attachedObject.objects[i].max_bound.z - m_attachedObject.objects[i].min_bound.z;
+ link->attachedBodies[i]->shape = box;
+ }
+
+ // update the collision model
+ m_collisionSpace->updateAttachedBodies(model_id);
+ ROS_INFO("Link '%s' on '%s' has %d objects attached", m_attachedObject.link_name.c_str(), m_attachedObject.robot_name.c_str(), n);
+ }
+ else
+ ROS_WARN("Unable to attach object to link '%s' on '%s'", m_attachedObject.link_name.c_str(), m_attachedObject.robot_name.c_str());
+ m_collisionSpace->unlock();
+ if (link)
+ afterAttachBody(link);
+ }
+
+ bool setCollisionState(robot_srvs::CollisionCheckState::Request &req, robot_srvs::CollisionCheckState::Response &res)
+ {
+ m_collisionSpace->lock();
+ int model_id = m_collisionSpace->getModelID(req.robot_name);
+ if (model_id >= 0)
+ res.value = m_collisionSpace->setCollisionCheck(model_id, req.link_name, req.value ? true : false);
+ else
+ res.value = -1;
+ m_collisionSpace->unlock();
+ if (res.value == -1)
+ ROS_WARN("Unable to change collision checking state for link '%s' on '%s'", req.link_name.c_str(), req.robot_name.c_str());
+ else
+ ROS_INFO("Collision checking for link '%s' on '%s' is now %s", req.link_name.c_str(), req.robot_name.c_str(), res.value ? "enabled" : "disabled");
+ return true;
+ }
+
+ virtual void setRobotDescription(robot_desc::URDF *file)
+ {
+ KinematicStateMonitor::setRobotDescription(file);
+ if (m_kmodel)
+ {
+ std::vector<std::string> links;
+ robot_desc::URDF::Group *g = file->getGroup("collision_check");
+ if (g && g->hasFlag("collision"))
+ links = g->linkNames;
+ m_collisionSpace->lock();
+ unsigned int cid = m_collisionSpace->addRobotModel(m_kmodel, links);
+ m_collisionSpace->unlock();
+ addSelfCollisionGroups(cid, file);
+ }
+ }
+
+ virtual void defaultPosition(void)
+ {
+ KinematicStateMonitor::defaultPosition();
+ if (m_collisionSpace && m_collisionSpace->getModelCount() == 1)
+ m_collisionSpace->updateRobotModel(0);
+ }
+
+ bool isMapUpdated(double sec)
+ {
+ if (sec > 0 && m_lastMapUpdate < ros::Time::now() - ros::Duration(sec))
+ return false;
+ else
+ return true;
+ }
+
+ protected:
+
+ void addSelfCollisionGroups(unsigned int cid, robot_desc::URDF *model)
+ {
+ std::vector<robot_desc::URDF::Group*> groups;
+ model->getGroups(groups);
+
+ m_collisionSpace->lock();
+ for (unsigned int i = 0 ; i < groups.size() ; ++i)
+ if (groups[i]->hasFlag("self_collision"))
+ m_collisionSpace->addSelfCollisionGroup(cid, groups[i]->linkNames);
+ m_collisionSpace->unlock();
+ }
+
+ void collisionMapCallback(void)
+ {
+ unsigned int n = m_collisionMap.get_boxes_size();
+ ROS_INFO("Received %u points (collision map)", n);
+
+ beforeWorldUpdate();
+
+ ros::Time startTime = ros::Time::now();
+ double *data = new double[4 * n];
+ for (unsigned int i = 0 ; i < n ; ++i)
+ {
+ unsigned int i4 = i * 4;
+ data[i4 ] = m_collisionMap.boxes[i].center.x;
+ data[i4 + 1] = m_collisionMap.boxes[i].center.y;
+ data[i4 + 2] = m_collisionMap.boxes[i].center.z;
+
+ data[i4 + 3] = radiusOfBox(m_collisionMap.boxes[i].extents);
+ }
+
+ m_collisionSpace->lock();
+ m_collisionSpace->clearObstacles();
+ m_collisionSpace->addPointCloud(n, data);
+ m_collisionSpace->unlock();
+
+ delete[] data;
+
+ double tupd = (ros::Time::now() - startTime).toSec();
+ ROS_INFO("Updated world model in %f seconds", tupd);
+ m_lastMapUpdate = ros::Time::now();
+
+ afterWorldUpdate();
+ }
+
+ virtual void beforeWorldUpdate(void)
+ {
+ }
+
+ virtual void afterWorldUpdate(void)
+ {
+ }
+
+ virtual void afterAttachBody(planning_models::KinematicModel::Link *link)
+ {
+ }
+
+ double radiusOfBox(robot_msgs::Point32 &point)
+ {
+ return std::max(std::max(point.x, point.y), point.z) * 1.73;
+ }
+
+ robot_msgs::CollisionMap m_collisionMap;
+ collision_space::EnvironmentModel *m_collisionSpace;
+
+ // add or remove objects to be attached to a link
+ robot_msgs::AttachedObject m_attachedObject;
+
+ ros::Time m_lastMapUpdate;
+ };
+
+} // kinematic_planning
Added: pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/KinematicStateMonitor.h
===================================================================
--- pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/KinematicStateMonitor.h (rev 0)
+++ pkg/trunk/motion_planning/ompl_planning/include/kinematic_planning/KinematicStateMonitor.h 2009-03-03 00:34:01 UTC (rev 12008)
@@ -0,0 +1,326 @@
+/*********************************************************************
+* 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 */
+
+/**
+ This class simply allows a node class to be aware of the kinematic
+ state the robot is currently in.
+*/
+
+#include <ros/node.h>
+#include <ros/time.h>
+#include <ros/console.h>
+
+#include <urdf/URDF.h>
+#include <planning_models/kinematic.h>
+#include <tf/transform_datatypes.h>
+#include <tf/transform_listener.h>
+#include <sstream>
+#include <cmath>
+
+#include <robot_msgs/MechanismState.h>
+#include <robot_msgs/PoseWithCovariance.h>
+
+/** Main namespace */
+namespace kinematic_planning
+{
+ /**
+ @b KinematicStateMonitor is a class that is also of a given robot model and
+ uses a ROS node to retrieve the necessary data.
+
+ <hr>
+
+ @section topic ROS topics
+
+ Subscribes to (name/type):
+ - @b "mechanism_model"/MechanismModel : position for each of the robot's joints
+ - @b "odom_combined"/PoseWithCovariance : localized robot pose
+
+ Publishes to (name/type):
+ - None
+
+ <hr>
+
+ @section services ROS services
+
+ Uses (name/type):
+ - None
+
+ Provides (name/type):
+ - None
+
+ <hr>
+
+ @section parameters ROS parameters
+ - @b "robot_description"/string : the URDF description of the robot we are monitoring
+
+ **/
+
+ class KinematicStateMonitor
+ {
+
+ public:
+ planning_models::KinematicModel* getKModel(void) { return m_kmodel; }
+ planning_models::KinematicModel::StateParams* getRobotState() { return m_robotState; }
+
+ KinematicStateMonitor(ros::Node *node) : m_tf(*node, true, ros::Duration(1))
+ {
+ m_tf.setExtrapolationLimit(ros::Duration().fromSec(10));
+
+ m_urdf = NULL;
+ m_kmodel = NULL;
+ m_robotState = NULL;
+ m_node = node;
+ m_basePos[0] = m_basePos[1] = m_basePos[2] = 0.0;
+
+ m_includeBaseInState = false;
+ m_haveMechanismState = false;
+ m_haveBasePos = false;
+
+ m_node->subscribe("mechanism_state", m_mechanismState, &KinematicStateMonitor::mechanismStateCallback, this, 1);
+ m_node->subscribe("odom_combined", m_localizedPose, &KinematicStateMonitor::localizedPoseCallback, this, 1);
+ }
+
+ virtual ~KinematicStateMonitor(void)
+ {
+ if (m_urdf)
+ delete m_urdf;
+ if (m_robotState)
+ delete m_robotState;
+ if (m_kmodel)
+ delete m_kmodel;
+ }
+
+ void setIncludeBaseInState(bool value)
+ {
+ m_includeBaseInState = value;
+ }
+
+ void setRobotDescriptionFromData(const char *data)
+ {
+ robot_desc::URDF *file = new robot_desc::URDF();
+ if (file->loadString(data))
+ setRobotDescription(file);
+ else
+ delete file;
+ }
+
+ void setRobotDescriptionFromFile(const char *filename)
+ {
+ robot_desc::URDF *file = new robot_desc::URDF();
+ if (file->loadFile(filename))
+ setRobotDescription(file);
+ else
+ delete file;
+ }
+
+ virtual void setRobotDescription(robot_desc::URDF *file)
+ {
+ if (m_urdf)
+ delete m_urdf;
+ if (m_kmodel)
+ delete m_kmodel;
+
+ m_urdf = file;
+ m_kmodel = new planning_models::KinematicModel();
+ m_kmodel->setVerbose(false);
+ m_kmodel->build(*file);
+ m_kmodel->reduceToRobotFrame();
+
+ m_robotState = m_kmodel->newStateParams();
+ m_robotState->setInRobotFrame();
+
+ m_haveMechanismState = false;
+ m_haveBasePos = false;
+ }
+
+ virtual void loadRobotDescription(void)
+ {
+ std::string content;
+ if (m_node->getParam("robot_description", content))
+ setRobotDescriptionFromData(content.c_str());
+ else
+ ROS_ERROR("Robot model not found! Did you remap robot_description?");
+ }
+
+ virtual void defaultPosition(void)
+ {
+ if (m_kmodel)
+ m_kmodel->defaultState();
+ }
+
+ bool loadedRobot(void) const
+ {
+ return m_kmodel != NULL;
+ }
+
+ void waitForState(void)
+ {
+ ROS_INFO("Waiting for mechanism state ...");
+ while (m_node->ok() && (m_haveMechanismState ^ loadedRobot()))
+ ros::Duration().fromSec(0.05).sleep();
+ ROS_INFO("Mechanism state received!");
+ }
+
+ void waitForPose(void)
+ {
+ ROS_INFO("Waiting for robot pose ...");
+ while (m_node->ok() && (m_haveBasePos ^ loadedRobot()))
+ ros::Duration().fromSec(0.05).sleep();
+ ROS_INFO("Robot pose received!");
+ }
+
+ void printCurrentState(void)
+ {
+ std::stringstream ss;
+ m_robotState->print(ss);
+ ROS_INFO("%s", ss.str().c_str());
+ }
+
+ bool isStateUpdated(double sec)
+ {
+ if (sec > 0 && m_lastStateUpdate < ros::Time::now() - ros::Duration(sec))
+ return false;
+ else
+ return true;
+ }
+
+ bool isBaseUpdated(double sec)
+ {
+ if (sec > 0 && m_lastBaseUpdate < ros::Time::now() - ros::Duration(sec))
+ return false;
+ else
+ return true;
+ }
+
+ protected:
+
+ virtual void stateUpdate(void)
+ {
+ }
+
+ virtual void baseUpdate(void)
+ {
+ bool change = false;
+ if (m_robotState && m_includeBaseInState)
+ for (unsigned int i = 0 ; i < m_kmodel->getRobotCount() ; ++i)
+ {
+ planning_models::KinematicModel::PlanarJoint* pj =
+ dynamic_cast<planning_models::KinematicModel::PlanarJoint*>(m_kmodel->getRobot(i)->chain);
+ if (pj)
+ {
+ bool this_changed = m_robotState->setParamsJoint(m_basePos, pj->name);
+ change = change || this_changed;
+ }
+ }
+ if (change)
+ stateUpdate();
+ }
+
+ void localizedPoseCallback(void)
+ {
+ tf::PoseMsgToTF(m_localizedPose.pose, m_pose);
+ if (std::isfinite(m_pose.getOrigin().x()))
+ m_basePos[0] = m_pose.getOrigin().x();
+ if (std::isfinite(m_pose.getOrigin().y()))
+ m_basePos[1] = m_pose.getOrigin().y();
+ double yaw, pitch, roll;
+ m_pose.getBasis().getEulerZYX(yaw, pitch, roll);
+ if (std::isfinite(yaw))
+ m_basePos[2] = yaw;
+ m_haveBasePos = true;
+ m_lastBaseUpdate = ros::Time::now();
+ baseUpdate();
+ }
+
+ void mechanismStateCallback(void)
+ {
+ bool change = false;
+ if (m_robotState)
+ {
+ unsigned int n = m_mechanismState.get_joint_states_size();
+ for (unsigned int i = 0 ; i < n ; ++i)
+ {
+ planning_models::KinematicModel::Joint* joint = m_kmodel->getJoint(m_mechanismState.joint_states[i].name);
+ if (joint)
+ {
+ if (joint->usedParams == 1)
+ {
+ double pos = m_mechanismState.joint_states[i].position;
+ bool this_changed = m_robotState->setParamsJoint(&pos, m_mechanismState.joint_states[i].name);
+ change = change || this_changed;
+ }
+ // else
+ // ROS_WARN("Incorrect number of parameters: %s (expected %d, had 1)", m_mechanismState.joint_states[i].name.c_str(), joint->usedParams);
+ }
+ else
+ ROS_ERROR("Unknown joint: %s", m_mechanismState.joint_states[i].name.c_str());
+ }
+
+ if (!m_haveMechanismState)
+ m_haveMechanismState = m_robotState->seenAll();
+ m_lastStateUpdate = ros::Time::now();
+ }
+ if (change)
+ stateUpdate();
+ }
+
+ ros::Node *m_node;
+ tf::TransformListener m_tf;
+ robot_desc::URDF *m_urdf;
+ planning_models::KinematicModel *m_kmodel;
+
+ // info about the pose; this is not placed in the robot's kinematic state
+ bool m_haveBasePos;
+ double m_basePos[3];
+ tf::Pose m_pose;
+ robot_msgs::PoseWithCovariance m_localizedPose;
+
+ // info about the robot's joints
+ robot_msgs::MechanismState m_mechanismState;
+ bool m_haveMechanismState;
+...
[truncated message content] |
|
From: <is...@us...> - 2009-03-03 00:38:08
|
Revision: 12010
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12010&view=rev
Author: isucan
Date: 2009-03-03 00:38:05 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
renaming plan_kinematic_path to plan_ompl_path
Modified Paths:
--------------
pkg/trunk/demos/tabletop_manipulation/manifest.xml
Added Paths:
-----------
pkg/trunk/motion_planning/plan_ompl_path/
pkg/trunk/motion_planning/plan_ompl_path/CMakeLists.txt
pkg/trunk/motion_planning/plan_ompl_path/Makefile
pkg/trunk/motion_planning/plan_ompl_path/manifest.xml
pkg/trunk/motion_planning/plan_ompl_path/src/
pkg/trunk/motion_planning/plan_ompl_path/src/base/
pkg/trunk/motion_planning/plan_ompl_path/src/base/execute_plan_to_state_minimal.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/plan_kinematic_path.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/call_plan_to_state.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_position_minimal.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_state.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_state_minimal.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_replan_to_state.cpp
pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/test_path_execution.cpp
Removed Paths:
-------------
pkg/trunk/motion_planning/plan_kinematic_path/
Modified: pkg/trunk/demos/tabletop_manipulation/manifest.xml
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/manifest.xml 2009-03-03 00:37:43 UTC (rev 12009)
+++ pkg/trunk/demos/tabletop_manipulation/manifest.xml 2009-03-03 00:38:05 UTC (rev 12010)
@@ -12,7 +12,7 @@
<depend package="collision_map"/>
<depend package="ompl_planning"/>
<depend package="executive_python"/>
- <depend package="plan_kinematic_path"/>
+ <depend package="plan_ompl_path"/>
<depend package="pr2_msgs"/>
<depend package="rosviz"/>
<depend package="tf"/>
Added: pkg/trunk/motion_planning/plan_ompl_path/CMakeLists.txt
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/CMakeLists.txt (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/CMakeLists.txt 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.4.6)
+include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
+rospack(plan_ompl_path)
+
+rospack_add_executable(plan_kinematic_path src/plan_kinematic_path.cpp)
+
+rospack_add_executable(rarm_execute_plan_to_state src/right_arm/execute_plan_to_state.cpp)
+rospack_add_executable(rarm_execute_plan_to_state_minimal src/right_arm/execute_plan_to_state_minimal.cpp)
+rospack_add_executable(rarm_execute_plan_to_position_minimal src/right_arm/execute_plan_to_position_minimal.cpp)
+rospack_add_executable(rarm_execute_replan_to_state src/right_arm/execute_replan_to_state.cpp)
+rospack_add_executable(rarm_test_path_execution src/right_arm/test_path_execution.cpp)
+rospack_add_executable(rarm_call_plan_to_state src/right_arm/call_plan_to_state.cpp)
+
+rospack_add_executable(base_execute_plan_to_state_minimal src/base/execute_plan_to_state_minimal.cpp)
Added: pkg/trunk/motion_planning/plan_ompl_path/Makefile
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/Makefile (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/Makefile 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1 @@
+include $(shell rospack find mk)/cmake.mk
Added: pkg/trunk/motion_planning/plan_ompl_path/manifest.xml
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/manifest.xml (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/manifest.xml 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,24 @@
+<package>
+ <description>Test package that can plan a kinematic path. Various examples on how to use the available sampling-based planners in conjunction with controllers</description>
+ <author>Ioan A. Sucan</author>
+ <license>BSD</license>
+ <review status="unreviewed" notes=""/>
+ <depend package="roscpp" />
+ <depend package="rosconsole" />
+
+ <depend package="std_msgs" />
+ <depend package="std_srvs" />
+
+ <depend package="robot_msgs" />
+ <depend package="robot_srvs" />
+
+ <depend package="pr2_msgs" />
+ <depend package="pr2_srvs" />
+
+ <depend package="planning_models" />
+ <depend package="ompl_planning" />
+
+ <depend package="robot_mechanism_controllers" />
+ <depend package="pr2_mechanism_controllers" />
+
+</package>
Added: pkg/trunk/motion_planning/plan_ompl_path/src/base/execute_plan_to_state_minimal.cpp
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/src/base/execute_plan_to_state_minimal.cpp (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/src/base/execute_plan_to_state_minimal.cpp 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,136 @@
+/*********************************************************************
+* 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 */
+
+/** This is a simple program that shows how to plan a motion to a state.
+ The minimum number of things to get the base to move is done.
+
+ This example is incomplete since I do not know how to interact
+ with the base controller, and the kinematic_planning node still
+ runs in the robot frame. We need to switch to the map frame at
+ some point, if we want to do planning for the base.
+*/
+
+#include <kinematic_planning/KinematicStateMonitor.h>
+
+// service for planning to a state
+#include <robot_srvs/KinematicPlanState.h>
+
+
+static const std::string GROUPNAME = "pr2::base";
+
+class Example : public kinematic_planning::KinematicStateMonitor
+{
+public:
+
+ Example(ros::Node *node) : kinematic_planning::KinematicStateMonitor(node)
+ {
+ }
+
+ void runExample(void)
+ {
+ // construct the request for the motion planner
+ robot_msgs::KinematicPlanStateRequest req;
+
+ req.params.model_id = GROUPNAME;
+ req.params.distance_metric = "L2Square";
+ req.params.planner_id = "SBL";
+ req.threshold = 0.1;
+ req.interpolate = 1;
+ req.times = 1;
+
+ // skip setting the start state
+
+ // 3 DOF for the base; pick a goal state (joint angles)
+ req.goal_state.set_vals_size(3);
+ for (unsigned int i = 0 ; i < req.goal_state.get_vals_size(); ++i)
+ req.goal_state.vals[i] = m_basePos[i];
+
+ // move by one meter on X or Y
+ req.goal_state.vals[0] = 1;
+
+ // set the 2D space in which the base is allowed to move
+ req.params.volumeMin.x = -5.0 + m_basePos[0];
+ req.params.volumeMin.y = -5.0 + m_basePos[1];
+ req.params.volumeMin.z = 0.0;
+
+ req.params.volumeMax.x = 5.0 + m_basePos[0];
+ req.params.volumeMax.y = 5.0 + m_basePos[1];
+ req.params.volumeMax.z = 0.0;
+
+ // allow 1 second computation time
+ req.allowed_time = 1.0;
+
+ // define the service messages
+ robot_srvs::KinematicPlanState::Request s_req;
+ robot_srvs::KinematicPlanState::Response s_res;
+ s_req.value = req;
+
+ if (ros::service::call("plan_kinematic_path_state", s_req, s_res))
+ {
+ // send command to the base
+ // no idea how to interface with that yet ...
+ }
+ else
+ ROS_ERROR("Service 'plan_kinematic_path_state' failed");
+ }
+
+ void run(void)
+ {
+ loadRobotDescription();
+ if (loadedRobot())
+ {
+ sleep(1);
+ runExample();
+ }
+ sleep(1);
+ }
+
+private:
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+
+ ros::Node node("example_execute_plan_to_state_minimal");
+ Example plan(&node);
+ plan.run();
+
+ return 0;
+}
Added: pkg/trunk/motion_planning/plan_ompl_path/src/plan_kinematic_path.cpp
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/src/plan_kinematic_path.cpp (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/src/plan_kinematic_path.cpp 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,324 @@
+/*********************************************************************
+* 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 */
+
+/** This is a simple program that shows how to (re)plan a motion to a
+ state or a link position. The minimum number of things to get the
+ arm to move (and replan) is done.
+ */
+
+#include <kinematic_planning/KinematicStateMonitor.h>
+
+// service for (re)planning to a state
+#include <robot_srvs/KinematicReplanState.h>
+
+// service for (re)planning to a link position
+#include <robot_srvs/KinematicReplanLinkPosition.h>
+
+// message for receiving the planning status
+#include <robot_msgs/KinematicPlanStatus.h>
+
+// message sent to visualizer to display the path
+#include <robot_msgs/DisplayKinematicPath.h>
+
+// messages to interact with the joint trajectory controller
+#include <robot_msgs/JointTraj.h>
+
+// message to interact with the cartesian trajectory controller
+#include <robot_msgs/PoseStamped.h>
+
+static const std::string GROUPNAME = "pr2::right_arm";
+
+class PlanKinematicPath : public kinematic_planning::KinematicStateMonitor
+{
+public:
+
+ PlanKinematicPath(ros::Node *node) : kinematic_planning::KinematicStateMonitor(node)
+ {
+ plan_id_ = -1;
+ robot_stopped_ = true;
+
+ // we use the topic for sending commands to the controller, so we need to advertise it
+ m_node->advertise<robot_msgs::JointTraj>("right_arm_trajectory_command", 1);
+ m_node->advertise<robot_msgs::PoseStamped>("cartesian_trajectory/command", 1);
+
+ // advertise the topic for displaying kinematic plans
+ m_node->advertise<robot_msgs::DisplayKinematicPath>("display_kinematic_path", 10);
+
+ m_node->subscribe("kinematic_planning_status", plan_status_, &PlanKinematicPath::receiveStatus, this, 1);
+ }
+
+ void runRightArmToPositionA(void)
+ {
+ // construct the request for the motion planner
+ robot_msgs::KinematicPlanStateRequest req;
+
+ req.params.model_id = GROUPNAME;
+ req.params.distance_metric = "L2Square";
+ req.params.planner_id = "KPIECE";
+ req.threshold = 0.1;
+ req.interpolate = 1;
+ req.times = 1;
+
+ // skip setting the start state
+
+ // 7 DOF for the arm; pick a goal state (joint angles)
+ req.goal_state.set_vals_size(7);
+ for (unsigned int i = 0 ; i < req.goal_state.get_vals_size(); ++i)
+ req.goal_state.vals[i] = 0.0;
+ req.goal_state.vals[0] = -1.5;
+ req.goal_state.vals[1] = -0.2;
+
+ // allow 1 second computation time
+ req.allowed_time = 1.0;
+
+ // define the service messages
+ robot_srvs::KinematicReplanState::Request s_req;
+ robot_srvs::KinematicReplanState::Response s_res;
+ s_req.value = req;
+
+ if (ros::service::call("replan_kinematic_path_state", s_req, s_res))
+ plan_id_ = s_res.id;
+ else
+ ROS_ERROR("Service 'replan_kinematic_path_state' failed");
+ }
+
+ void runRightArmToPositionB(void)
+ {
+ // construct the request for the motion planner
+ robot_msgs::KinematicPlanLinkPositionRequest req;
+
+ req.params.model_id = GROUPNAME;
+ req.params.distance_metric = "L2Square";
+ req.params.planner_id = "IKKPIECE";
+ req.interpolate = 1;
+ req.times = 1;
+
+ // skip setting the start state
+
+ // set the goal constraints
+ req.set_goal_constraints_size(1);
+ req.goal_constraints[0].type = robot_msgs::PoseConstraint::POSITION_XYZ + robot_msgs::PoseConstraint::ORIENTATION_RPY;
+ req.goal_constraints[0].robot_link = "r_gripper_r_finger_tip_link";
+ req.goal_constraints[0].x = 0.75025;
+ req.goal_constraints[0].y = -0.188;
+ req.goal_constraints[0].z = 0.829675;
+
+ req.goal_constraints[0].roll = 0.0;
+ req.goal_constraints[0].pitch = 0.0;
+ req.goal_constraints[0].yaw = 0.0;
+
+ req.goal_constraints[0].position_distance = 0.0001;
+ req.goal_constraints[0].orientation_distance = 0.1;
+ req.goal_constraints[0].orientation_importance = 0.0001;
+
+ // allow 1 second computation time
+ req.allowed_time = 0.5;
+
+ // define the service messages
+ robot_srvs::KinematicReplanLinkPosition::Request s_req;
+ robot_srvs::KinematicReplanLinkPosition::Response s_res;
+ s_req.value = req;
+
+ if (ros::service::call("replan_kinematic_path_position", s_req, s_res))
+ plan_id_ = s_res.id;
+ else
+ ROS_ERROR("Service 'replan_kinematic_path_position' failed");
+ }
+
+ void runRightArmToCoordinates(void)
+ {
+ robot_msgs::PoseStamped ps;
+ ps.header.frame_id = "base_link"; // make sure this is true; this should be take from input header
+ ps.header.stamp = ros::Time::now(); // again, should be taken from input header
+ ps.pose.position.x = 0.8;
+ ps.pose.position.y = -0.188;
+ ps.pose.position.z = 0.829675;
+ ps.pose.orientation.x = 0;
+ ps.pose.orientation.y = 0;
+ ps.pose.orientation.z = 0;
+ ps.pose.orientation.w = 1;
+ m_node->publish("cartesian_trajectory/command", ps);
+ }
+
+ void run(void)
+ {
+ loadRobotDescription();
+ if (loadedRobot())
+ {
+ ros::Duration d(1.0);
+ d.sleep();
+
+ while (m_node->ok())
+ {
+ ros::Duration d(10.0);
+
+ runRightArmToPositionA();
+
+ d.sleep();
+
+ runRightArmToPositionB();
+
+ d.sleep();
+ }
+
+ /*
+ sleep(30);
+
+ plan->runRightArmToCoordinates();
+ */
+
+ m_node->spin();
+ }
+ }
+
+protected:
+
+ // handle new status message
+ void receiveStatus(void)
+ {
+ if (plan_id_ >= 0 && plan_status_.id == plan_id_)
+ {
+ if (plan_status_.valid && !plan_status_.unsafe)
+ {
+ if (!plan_status_.path.states.empty())
+ {
+ robot_stopped_ = false;
+ sendArmCommand(plan_status_.path, GROUPNAME);
+ }
+ }
+ else
+ stopRobot();
+ if (plan_status_.done)
+ {
+ plan_id_ = -1;
+ robot_stopped_ = true;
+ ROS_INFO("Execution is complete");
+ }
+ }
+ }
+
+ void stopRobot(void)
+ {
+ if (robot_stopped_)
+ return;
+ robot_stopped_ = true;
+
+ // get the current params for the robot's right arm
+ double cmd[7];
+ m_robotState->copyParamsGroup(cmd, GROUPNAME);
+
+ robot_msgs::KinematicPath stop_path;
+ stop_path.set_states_size(1);
+ stop_path.states[0].set_vals_size(7);
+ for (unsigned int i = 0 ; i < 7 ; ++i)
+ stop_path.states[0].vals[i] = cmd[i];
+
+ sendArmCommand(stop_path, GROUPNAME);
+ }
+
+ // get the current state from the StateParams instance monitored by the KinematicStateMonitor
+ void currentState(robot_msgs::KinematicState &state)
+ {
+ state.set_vals_size(m_kmodel->getModelInfo().stateDimension);
+ for (unsigned int i = 0 ; i < state.get_vals_size() ; ++i)
+ state.vals[i] = m_robotState->getParams()[i];
+ }
+
+ // convert a kinematic path message to a trajectory for the controller
+ void getTrajectoryMsg(robot_msgs::KinematicPath &path, robot_msgs::JointTraj &traj)
+ {
+ traj.set_points_size(path.get_states_size());
+ for (unsigned int i = 0 ; i < path.get_states_size() ; ++i)
+ {
+ traj.points[i].set_positions_size(path.states[i].get_vals_size());
+ for (unsigned int j = 0 ; j < path.states[i].get_vals_size() ; ++j)
+ traj.points[i].positions[j] = path.states[i].vals[j];
+ traj.points[i].time = 0.0;
+ }
+ }
+
+ // send a command to the trajectory controller using a topic
+ void sendArmCommand(robot_msgs::KinematicPath &path, const std::string &model)
+ {
+ sendDisplay(path, model);
+ printPath(path);
+ robot_msgs::JointTraj traj;
+ getTrajectoryMsg(path, traj);
+ m_node->publish("right_arm_trajectory_command", traj);
+ ROS_INFO("Sent trajectory to controller");
+ }
+
+ void sendDisplay(robot_msgs::KinematicPath &path, const std::string &model)
+ {
+ robot_msgs::DisplayKinematicPath dpath;
+ dpath.frame_id = "base_link";
+ dpath.model_name = model;
+ currentState(dpath.start_state);
+ dpath.path = path;
+ m_node->publish("display_kinematic_path", dpath);
+ ROS_INFO("Sent planned path to display");
+ }
+
+ void printPath(robot_msgs::KinematicPath &path)
+ {
+ printf("Path with %d states\n", (int)path.states.size());
+ for (unsigned int i = 0 ; i < path.states.size() ; ++i)
+ {
+ for (unsigned int j = 0 ; j < path.states[i].vals.size() ; ++j)
+ printf("%f ", path.states[i].vals[j]);
+ printf("\n");
+ }
+ printf("\n");
+ }
+
+ robot_msgs::KinematicPlanStatus plan_status_;
+ int plan_id_;
+ bool robot_stopped_;
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+ ros::Node *node = new ros::Node("plan_kinematic_path");
+
+ PlanKinematicPath plan(node);
+ plan.run();
+
+ return 0;
+}
Added: pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/call_plan_to_state.cpp
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/call_plan_to_state.cpp (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/call_plan_to_state.cpp 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,95 @@
+/*********************************************************************
+* 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 */
+
+/** This is a simple program that shows how to plan a motion to a
+ state. The minimum number of things to get the arm to move is
+ done. This code only interfaces with a highlevel controller, so
+ getting the motion executed is no longer our responsibility.
+ */
+
+#include <kinematic_planning/KinematicStateMonitor.h>
+
+// interface to a high level controller
+#include <pr2_msgs/MoveArmGoal.h>
+
+class Example : public kinematic_planning::KinematicStateMonitor
+{
+public:
+
+ Example(ros::Node *node) : kinematic_planning::KinematicStateMonitor(node)
+ {
+ // we use the topic for sending commands to the controller, so we need to advertise it
+ m_node->advertise<pr2_msgs::MoveArmGoal>("right_arm_goal", 1);
+ }
+
+ void runExample(void)
+ {
+ // construct the request for the highlevel controller
+ pr2_msgs::MoveArmGoal ag;
+ ag.enable = 1;
+ ag.timeout = 10.0;
+
+ ag.set_goal_configuration_size(1);
+ ag.goal_configuration[0].name = "r_shoulder_pan_joint";
+ ag.goal_configuration[0].position = -0.5;
+ m_node->publish("right_arm_goal", ag);
+ }
+
+ void run(void)
+ {
+ loadRobotDescription();
+ if (loadedRobot())
+ {
+ sleep(1);
+ runExample();
+ }
+ sleep(1);
+ }
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+
+ ros::Node node("example_call_plan_to_state");
+ Example plan(&node);
+ plan.run();
+
+ return 0;
+}
Added: pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_position_minimal.cpp
===================================================================
--- pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_position_minimal.cpp (rev 0)
+++ pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_position_minimal.cpp 2009-03-03 00:38:05 UTC (rev 12010)
@@ -0,0 +1,158 @@
+/*********************************************************************
+* 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 */
+
+/** This is a simple program that shows how to plan a motion to a link position
+ The minimum number of things to get the arm to move is done.
+ */
+
+#include <kinematic_planning/KinematicStateMonitor.h>
+
+// service for planning to a link position
+#include <robot_srvs/KinematicPlanLinkPosition.h>
+
+// messages to interact with the trajectory controller
+#include <robot_msgs/JointTraj.h>
+
+static const std::string GROUPNAME = "pr2::right_arm";
+
+class Example : public kinematic_planning::KinematicStateMonitor
+{
+public:
+
+ Example(ros::Node *node) : kinematic_planning::KinematicStateMonitor(node)
+ {
+ // we use the topic for sending commands to the controller, so we need to advertise it
+ m_node->advertise<robot_msgs::JointTraj>("right_arm_trajectory_command", 1);
+ }
+
+ void runExample(void)
+ {
+ // construct the request for the motion planner
+ robot_msgs::KinematicPlanLinkPositionRequest req;
+
+ req.params.model_id = GROUPNAME;
+ req.params.distance_metric = "L2Square";
+ req.params.planner_id = "IKSBL";
+ req.interpolate = 1;
+ req.times = 1;
+
+ // skip setting the start state
+
+ // allow 1 second computation time
+ req.allowed_time = 1.0;
+
+
+ // place some constraints on the goal
+ req.set_goal_constraints_size(1);
+ // see the constraints message definition
+ req.goal_constraints[0].type = robot_msgs::PoseConstraint::POSITION_XYZ + robot_msgs::PoseConstraint::ORIENTATION_RY;
+ req.goal_constraints[0].robot_link = "r_gripper_palm_link";
+ req.goal_constraints[0].x = 0.75025;
+ req.goal_constraints[0].y = -0.188;
+ req.goal_constraints[0].z = 0.829675;
+
+ req.goal_constraints[0].roll = 0.0;
+ req.goal_constraints[0].yaw = 0.0;
+
+ // the threshold for solution is position_distance + orientation_distance * orientation_importance
+ // but the distance requirements must be satisfied by
+ req.goal_constraints[0].position_distance = 0.005; // in L2square norm
+ req.goal_constraints[0].orientation_distance = 0.05; // difference in radians between the quaternions
+ req.goal_constraints[0].orientation_importance = 0.005; // factor of importance of orientation relative to importance of position
+
+ // define the service messages
+ robot_srvs::KinematicPlanLinkPosition::Request s_req;
+ robot_srvs::KinematicPlanLinkPosition::Response s_res;
+ s_req.value = req;
+
+ if (ros::service::call("plan_kinematic_path_position", s_req, s_res))
+ sendArmCommand(s_res.value.path, GROUPNAME);
+ else
+ ROS_ERROR("Service 'plan_kinematic_path_state' failed");
+ }
+
+ void run(void)
+ {
+ loadRobotDescription();
+ if (loadedRobot())
+ {
+ sleep(1);
+ runExample();
+ }
+ sleep(1);
+ }
+
+protected:
+
+ // convert a kinematic path message to a trajectory for the controller
+ void getTrajectoryMsg(robot_msgs::KinematicPath &path, robot_msgs::JointTraj &traj)
+ {
+ traj.set_points_size(path.get_states_size());
+ for (unsigned int i = 0 ; i < path.get_states_size() ; ++i)
+ {
+ traj.points[i].set_positions_size(path.states[i].get_vals_size());
+ for (unsigned int j = 0 ; j < path.states[i].get_vals_size() ; ++j)
+ traj.points[i].positions[j] = path.states[i].vals[j];
+ traj.points[i].time = 0.0;
+ }
+ }
+
+ // send a command to the trajectory controller using a topic
+ void sendArmCommand(robot_msgs::KinematicPath &path, const std::string &model)
+ {
+ robot_msgs::JointTraj traj;
+ getTrajectoryMsg(path, traj);
+ m_node->publish("right_arm_trajectory_command", traj);
+ ROS_INFO("Sent trajectory to controller (using a topic)");
+ }
+
+private:
+
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+
+ ros::Node node("example_execute_plan_to_position_minimal");
+ Example plan(&node);
+ plan.run();
+
+ return 0;
+}
Added: pkg/trunk/motion_planning/plan_ompl_path/src/right_arm/execute_plan_to_state.cpp
==================================...
[truncated message content] |
|
From: <ge...@us...> - 2009-03-03 02:32:42
|
Revision: 12028
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12028&view=rev
Author: gerkey
Date: 2009-03-03 02:32:36 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
Merged from tabletop_manipulation_feb-2009 branch. Mostly changes to
tabletop_manipulation package, with a smattering of fixes and tweaks to
other packges.
Modified Paths:
--------------
pkg/trunk/demos/2dnav_pr2/2dnav_pr2_nolocalization.xml
pkg/trunk/demos/tabletop_manipulation/launch/arm.launch
pkg/trunk/demos/tabletop_manipulation/launch/ekf.launch
pkg/trunk/demos/tabletop_manipulation/launch/nav_sim.launch
pkg/trunk/demos/tabletop_manipulation/scripts/approachtable.py
pkg/trunk/demos/tabletop_manipulation/scripts/movearm.py
pkg/trunk/demos/tabletop_manipulation/scripts/tuckarm.py
pkg/trunk/highlevel/highlevel_controllers/src/move_arm.cpp
pkg/trunk/mapping/collision_map/src/collision_map_buffer.cpp
pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_alpha/prf.launch
pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_alpha/teleop_joystick.launch
pkg/trunk/visualization/rviz/src/rviz/displays/collision_map_display.cpp
pkg/trunk/visualization/rviz/src/rviz/displays/planning_display.cpp
Added Paths:
-----------
pkg/trunk/demos/2dnav_pr2/maps/
pkg/trunk/demos/2dnav_pr2/maps/empty_0.05.pgm
pkg/trunk/demos/tabletop_manipulation/launch/hw.launch
pkg/trunk/demos/tabletop_manipulation/launch/nav.launch
pkg/trunk/demos/tabletop_manipulation/launch/r_gripper_effort_controller.xml
pkg/trunk/demos/tabletop_manipulation/launch/teleop.launch
pkg/trunk/demos/tabletop_manipulation/launch/torso_effort_controller.xml
pkg/trunk/demos/tabletop_manipulation/launch/trajectory_controllers.xml
pkg/trunk/demos/tabletop_manipulation/scripts/actuategripper.py
pkg/trunk/demos/tabletop_manipulation/scripts/actuatetorso.py
pkg/trunk/demos/tabletop_manipulation/scripts/detecttable.py
pkg/trunk/demos/tabletop_manipulation/scripts/recordstaticmap.py
pkg/trunk/demos/tabletop_manipulation/scripts/stopbase.py
Removed Paths:
-------------
pkg/trunk/demos/2dnav_pr2/maps/empty_0.05.pgm
pkg/trunk/demos/tabletop_manipulation/trajectory_controllers.xml
Modified: pkg/trunk/demos/2dnav_pr2/2dnav_pr2_nolocalization.xml
===================================================================
--- pkg/trunk/demos/2dnav_pr2/2dnav_pr2_nolocalization.xml 2009-03-03 02:30:35 UTC (rev 12027)
+++ pkg/trunk/demos/2dnav_pr2/2dnav_pr2_nolocalization.xml 2009-03-03 02:32:36 UTC (rev 12028)
@@ -31,7 +31,7 @@
<node pkg="robot_pose_ekf" type="robot_pose_ekf" args="robot_pose_ekf" machine="four"/>
- <node pkg="map_server" type="map_server" args="$(find 2dnav_stage)/maps/willow-empty-0.05.pgm 0.05" respawn="true" machine="four" />
+ <node pkg="map_server" type="map_server" args="$(find 2dnav_pr2)/maps/empty_0.05.pgm 0.05" respawn="true" machine="four" />
<node pkg="highlevel_controllers" type="move_base_navfn" respawn="true" machine="four" output="screen" name="move_base_node">
Deleted: pkg/trunk/demos/2dnav_pr2/maps/empty_0.05.pgm
===================================================================
(Binary files differ)
Copied: pkg/trunk/demos/2dnav_pr2/maps/empty_0.05.pgm (from rev 11953, pkg/branches/tabletop_manipulation_feb-2009/demos/2dnav_pr2/maps/empty_0.05.pgm)
===================================================================
(Binary files differ)
Modified: pkg/trunk/demos/tabletop_manipulation/launch/arm.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/arm.launch 2009-03-03 02:30:35 UTC (rev 12027)
+++ pkg/trunk/demos/tabletop_manipulation/launch/arm.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -1,6 +1,6 @@
<launch>
<!-- Arm trajectory controller -->
- <param name="right_arm_trajectory_controller/velocity_scaling_factor" type="double" value="0.25"/>
+ <param name="right_arm_trajectory_controller/velocity_scaling_factor" type="double" value="0.1"/>
<param name="right_arm_trajectory_controller/trajectory_wait_timeout" type="double" value=".25"/>
<param name="right_arm_trajectory_controller/r_shoulder_pan_joint/goal_reached_threshold" type="double" value="0.1"/>
@@ -27,5 +27,11 @@
<node pkg="mechanism_control" type="spawner.py" args="$(find tabletop_manipulation)/launch/trajectory_controllers.xml" output="screen"/>
+ <!-- Gripper effort controller -->
+ <node pkg="mechanism_control" type="spawner.py" args="$(find tabletop_manipulation)/launch/r_gripper_effort_controller.xml" output="screen"/>
+
+ <!-- Torso effort controller -->
+ <node pkg="mechanism_control" type="spawner.py" args="$(find tabletop_manipulation)/launch/torso_effort_controller.xml" output="screen"/>
+
</launch>
Modified: pkg/trunk/demos/tabletop_manipulation/launch/ekf.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/ekf.launch 2009-03-03 02:30:35 UTC (rev 12027)
+++ pkg/trunk/demos/tabletop_manipulation/launch/ekf.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -1,4 +1,5 @@
<launch>
+ <include file="$(find pr2_alpha)/$(env ROBOT).machine" />
<param name="robot_pose_ekf/freq" value="30.0"/>
<param name="robot_pose_ekf/sensor_timeout" value="1.0"/>
@@ -6,5 +7,6 @@
<param name="robot_pose_ekf/imu_used" value="true"/>
<param name="robot_pose_ekf/vo_used" value="false"/>
- <node pkg="robot_pose_ekf" type="robot_pose_ekf" args="robot_pose_ekf"/>
+ <node pkg="robot_pose_ekf" type="robot_pose_ekf" args="robot_pose_ekf"
+ machine="four"/>
</launch>
Added: pkg/trunk/demos/tabletop_manipulation/launch/hw.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/hw.launch (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/hw.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,20 @@
+<launch>
+ <include file="$(find pr2_alpha)/$(env ROBOT).machine" />
+
+ <!--include file="$(find tabletop_manipulation)/launch/teleop.launch"/-->
+
+ <!-- We're working without a map, relying on IMU-corrected wheel odom -->
+ <param name="/global_frame_id" value="odom_combined_offset"/>
+ <node pkg="tf" type="transform_sender" args="-20 -20 0 0 0 0 odom_combined_offset odom_combined 10"/>
+
+ <!-- Everything depends on ekf.launch, because it defines the
+ odom_combined frame -->
+ <include file="$(find tabletop_manipulation)/launch/ekf.launch"/>
+
+ <include file="$(find tabletop_manipulation)/launch/controllers.launch"/>
+ <include file="$(find tabletop_manipulation)/launch/perception.launch"/>
+ <!-- Note that nav.launch requires perception.launch, because the latter
+ runs the filters on the tilt laser scans -->
+ <include file="$(find tabletop_manipulation)/launch/nav.launch"/>
+ <!--include file="$(find tabletop_manipulation)/launch/planning.launch"/-->
+</launch>
Added: pkg/trunk/demos/tabletop_manipulation/launch/nav.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/nav.launch (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/nav.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,71 @@
+<launch>
+ <group name="wg">
+ <include file="$(find pr2_alpha)/$(env ROBOT).machine" />
+
+ <node pkg="map_server" type="map_server" args="$(find 2dnav_pr2)/maps/empty_0.05.pgm 0.05" respawn="true"/>
+
+
+ <node name="move_base" pkg="highlevel_controllers" type="move_base_navfn" respawn="true" output="screen" machine="three">
+ <remap from="tilt_laser_cloud_filtered" to="robotlinks_cloud_filtered"/>
+
+ <param name="move_base/environmentList" value="2D,3DKIN"/> <!-- future extension -->
+ <param name="move_base/plannerList" value="ADPlanner,ARAPlanner"/> <!-- future extension -->
+ <param name="move_base/plannerType" value="ARAPlanner"/>
+ <param name="move_base/environmentType" value="2D"/>
+ <param name="move_base/controller_frequency" value="30.0"/>
+ <param name="move_base/map_update_frequency" value="2.0"/>
+ <param name="move_base/planner_frequency" value="0.0"/>
+ <param name="move_base/plannerTimeLimit" value="0.5"/>
+ <param name="costmap_2d/base_laser_max_range" value="20.0"/>
+ <param name="costmap_2d/tilt_laser_max_range" value="3.0"/>
+ <param name="costmap_2d/lethal_obstacle_threshold" value="100.0"/>
+ <param name="costmap_2d/z_threshold_max" value="2.0"/>
+ <param name="costmap_2d/z_threshold_min" value="0.13"/>
+ <param name="costmap_2d/no_information_value" value="255"/>
+ <param name="costmap_2d/freespace_projection_height" value="2.0"/>
+ <param name="costmap_2d/inflation_radius" value="0.65"/>
+ <param name="costmap_2d/circumscribed_radius" value="0.46"/>
+ <param name="costmap_2d/inscribed_radius" value="0.325"/>
+ <param name="costmap_2d/raytrace_window" value="10.0"/>
+ <param name="costmap_2d/weight" value="0.1"/>
+
+
+ <param name="trajectory_rollout/map_size" value="4.0" />
+ <param name="trajectory_rollout/acc_limit_x" value="2.5" />
+ <param name="trajectory_rollout/acc_limit_y" value="2.5" />
+ <param name="trajectory_rollout/acc_limit_th" value="3.2" />
+ <param name="trajectory_rollout/sim_time" value="1.0" />
+ <param name="trajectory_rollout/sim_granularity" value="0.05" />
+ <param name="trajectory_rollout/vx_samples" value="15" />
+ <param name="trajectory_rollout/vtheta_samples" value="15" />
+ <param name="trajectory_rollout/path_distance_bias" value="0.6" />
+ <param name="trajectory_rollout/goal_distance_bias" value="0.8" />
+ <param name="trajectory_rollout/occdist_scale" value="0.2" />
+ <param name="trajectory_rollout/heading_lookahead" value="0.325" />
+ <param name="trajectory_rollout/oscillation_reset_dist" value="0.05" />
+ <param name="trajectory_rollout/holonomic_robot" value="true" />
+ <param name="trajectory_rollout/max_vel_x" value="0.5" />
+ <param name="trajectory_rollout/min_vel_x" value="0.1" />
+ <param name="trajectory_rollout/max_vel_th" value="1.0" />
+ <param name="trajectory_rollout/min_vel_th" value="-1.0" />
+ <param name="trajectory_rollout/min_in_place_vel_th" value="0.4" />
+ <param name="trajectory_rollout/freespace_model" value="true" />
+ <param name="trajectory_rollout/dwa" value="false" />
+ <param name="trajectory_rollout/simple_attractor" value="false" />
+
+ <param name="trajectory_rollout/yaw_goal_tolerance" value=".05" />
+ <param name="trajectory_rollout/xy_goal_tolerance" value=".1" />
+
+ <!-- Forces a check that we are receiving base scans that are correctly up to date at a rate of at least 2 Hz. This is
+ way too slow for the real system, but necessary for rosstage, which does not reliably meet a 5Hz update rate. -->
+ <param name="costmap_2d/base_laser_update_rate" value="2.0"/>
+
+ <!-- Setting these parameters to 0.0 disables the watchdog on them. For stage this is required since we
+ are not getting any data -->
+ <param name="costmap_2d/tilt_laser_update_rate" value="2.0"/>
+ <param name="costmap_2d/low_obstacle_update_rate" value="0.0"/>
+ <param name="costmap_2d/stereo_update_rate" value="0.0"/>
+ </node>
+
+ </group>
+</launch>
Modified: pkg/trunk/demos/tabletop_manipulation/launch/nav_sim.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/nav_sim.launch 2009-03-03 02:30:35 UTC (rev 12027)
+++ pkg/trunk/demos/tabletop_manipulation/launch/nav_sim.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -15,6 +15,9 @@
<param name="move_base/map_update_frequency" value="2.0"/>
<param name="move_base/planner_frequency" value="0.0"/>
<param name="move_base/plannerTimeLimit" value="0.5"/>
+ <param name="move_base/trans_stopped_velocity" value="0.01"/>
+ <param name="move_base/rot_stopped_velocity" value="0.01"/>
+
<param name="costmap_2d/base_laser_max_range" value="20.0"/>
<param name="costmap_2d/tilt_laser_max_range" value="3.0"/>
<param name="costmap_2d/lethal_obstacle_threshold" value="100.0"/>
Added: pkg/trunk/demos/tabletop_manipulation/launch/r_gripper_effort_controller.xml
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/r_gripper_effort_controller.xml (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/r_gripper_effort_controller.xml 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+
+<controllers>
+ <controller name="right_gripper/effort_controller" type="JointEffortControllerNode">
+ <joint name="r_gripper_l_finger_joint" />
+ </controller>
+</controllers>
+
Added: pkg/trunk/demos/tabletop_manipulation/launch/teleop.launch
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/teleop.launch (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/teleop.launch 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,17 @@
+<launch>
+ <group name="wg">
+ <include file="$(find pr2_alpha)/$(env ROBOT).machine" />
+
+ <param name="axis_vx" value="3" type="int"/>
+ <param name="axis_vy" value="2" type="int"/>
+ <param name="axis_vw" value="0" type="int"/>
+ <param name="pan" value="4" type="int"/>
+ <param name="tilt" value="5" type="int"/>
+ <param name="max_vw" value="1.0" />
+ <param name="max_vx" value="1.0" />
+ <param name="max_vy" value="1.0" />
+ <param name="deadman_button" value="4" type="int"/>
+ <node pkg="teleop_base" type="teleop_base" args="--deadman_no_publish" respawn="true" machine="four" />
+
+ </group>
+</launch>
Added: pkg/trunk/demos/tabletop_manipulation/launch/torso_effort_controller.xml
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/torso_effort_controller.xml (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/torso_effort_controller.xml 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+
+<controllers>
+ <controller name="torso_lift/effort_controller" type="JointEffortControllerNode">
+ <joint name="torso_lift_joint" />
+ </controller>
+</controllers>
+
+
Added: pkg/trunk/demos/tabletop_manipulation/launch/trajectory_controllers.xml
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/launch/trajectory_controllers.xml (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/launch/trajectory_controllers.xml 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+
+<controllers>
+ <!-- ========================================= -->
+ <!-- right arm array -->
+ <controller name="right_arm_trajectory_controller" type="ArmTrajectoryControllerNode">
+ <listen_topic name="right_arm_trajectory_command" />
+ <kinematics>
+ <elem key="kdl_chain_name">right_arm</elem>
+ </kinematics>
+ <map name="controller_param">
+ <elem key="kdl_chain_name">right_arm</elem>
+ </map>
+ <controller name="r_shoulder_pan_controller" topic="r_shoulder_pan_controller" type="JointPDController">
+ <joint name="r_shoulder_pan_joint" >
+ <pid p="140.0" d="30.0" i="0.8" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="r_shoulder_lift_controller" topic="r_shoulder_pitch_controller" type="JointPDController">
+ <joint name="r_shoulder_lift_joint" >
+ <pid p="70.0" d="20.0" i="0.0" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="r_upperarm_roll_controller" topic="r_upperarm_roll_controller" type="JointPDController">
+ <joint name="r_upper_arm_roll_joint" >
+ <pid p="50.0" d="5.0" i="0.2" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="r_elbow_controller" topic="r_elbow_flex_controller" type="JointPDController">
+ <joint name="r_elbow_flex_joint" >
+ <pid p="100.0" d="5.0" i="0.5" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="r_forearm_roll_controller" topic="r_forearm_roll_controller" type="JointPDController"> <joint name="r_forearm_roll_joint"
+>
+ <pid p="10.0" d="2.0" i="0.1" iClamp="10.0" />
+ </joint>
+ </controller>
+
+ <controller name="r_wrist_flex_controller" type="JointPDController">
+ <joint name="r_wrist_flex_joint">
+ <pid p="10" i="0.1" d="0.5" iClamp="10.0" />
+ </joint> </controller>
+
+ <controller name="r_wrist_roll_controller" type="JointPDController">
+ <joint name="r_wrist_roll_joint">
+ <pid p="10" i="0.1" d="0.5" iClamp="10.0" />
+ </joint> </controller>
+
+ <!--controller name="r_gripper_l_finger_controller" type="JointPDController">
+ <joint name="r_gripper_l_finger_joint">
+ <pid p="100" i="0.1" d="0.5" iClamp="100.0" />
+ </joint> </controller-->
+
+ <trajectory interpolation="cubic" />
+
+ </controller>
+
+ <controller name="left_arm_trajectory_controller" type="ArmTrajectoryControllerNode">
+ <listen_topic name="left_arm_trajectory_command" />
+ <kinematics>
+ <elem key="kdl_chain_name">left_arm</elem>
+ </kinematics>
+ <map name="controller_param">
+ <elem key="kdl_chain_name">left_arm</elem>
+ </map>
+ <controller name="l_shoulder_pan_controller" topic="l_shoulder_pan_controller" type="JointPDController">
+ <joint name="l_shoulder_pan_joint" >
+ <pid p="140.0" d="30.0" i="0.8" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="l_shoulder_lift_controller" topic="l_shoulder_pitch_controller" type="JointPDController">
+ <joint name="l_shoulder_lift_joint" >
+ <pid p="70.0" d="20.0" i="0.0" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="l_upperarm_roll_controller" topic="l_upperarm_roll_controller" type="JointPDController">
+ <joint name="l_upper_arm_roll_joint" >
+ <pid p="50.0" d="5.0" i="0.2" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="l_elbow_controller" topic="l_elbow_flex_controller" type="JointPDController">
+ <joint name="l_elbow_flex_joint" >
+ <pid p="100.0" d="5.0" i="0.5" iClamp="100.0" />
+ </joint>
+ </controller>
+ <controller name="l_forearm_roll_controller" topic="l_forearm_roll_controller" type="JointPDController"> <joint name="l_forearm_roll_joint"
+>
+ <pid p="10.0" d="2.0" i="0.1" iClamp="10.0" />
+ </joint>
+ </controller>
+
+ <controller name="l_wrist_flex_controller" type="JointPDController">
+ <joint name="l_wrist_flex_joint">
+ <pid p="10" i="0.1" d="0.5" iClamp="10.0" />
+ </joint> </controller>
+
+ <controller name="l_wrist_roll_controller" type="JointPDController">
+ <joint name="l_wrist_roll_joint">
+ <pid p="10" i="0.1" d="0.5" iClamp="10.0" />
+ </joint> </controller>
+
+ <!--controller name="l_gripper_l_finger_controller" type="JointPDController">
+ <joint name="l_gripper_l_finger_joint">
+ <pid p="100" i="0.1" d="0.5" iClamp="100.0" />
+ </joint> </controller-->
+
+ <trajectory interpolation="cubic" />
+
+ </controller>
+</controllers>
+
Added: pkg/trunk/demos/tabletop_manipulation/scripts/actuategripper.py
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/scripts/actuategripper.py (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/scripts/actuategripper.py 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2009, 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.
+#
+# Revision $Id: rossync 3844 2009-02-16 19:49:10Z gerkey $
+
+import roslib
+roslib.load_manifest('tabletop_manipulation')
+import rospy
+from std_msgs.msg import Float64
+
+import sys
+
+class ActuateGripper:
+ def __init__(self, side):
+ self.side = side
+ self.status = None
+ self.gripper_close_effort = -0.5
+ self.gripper_open_effort = 6.0
+ self.pub = rospy.Publisher(self.side + '_gripper/effort_controller/set_command', Float64)
+ #rospy.Subscriber(self.side + '_arm_state', MoveArmState, self.movearmCallback)
+
+ def actuateGripper(self, open):
+ msg = Float64()
+ if open:
+ print '[ActuateGripper] Opening gripper...'
+ msg.data = self.gripper_open_effort
+ else:
+ print '[ActuateGripper] Closing gripper...'
+ msg.data = self.gripper_close_effort
+ self.pub.publish(msg)
+
+ # HACK: don't know what to monitor to determine that the gripper is
+ # done opening or closing
+ print '[ActuateGripper] Waiting for gripper to finish moving...'
+ rospy.sleep(4.0)
+
+ return True
+
+USAGE = 'actuategripper.py {right|left} {open|close}'
+if __name__ == '__main__':
+ if len(sys.argv) != 3 or \
+ (sys.argv[1] != 'right' and sys.argv[1] != 'left') or \
+ (sys.argv[2] != 'open' and sys.argv[2] != 'close'):
+ print USAGE
+ sys.exit(-1)
+
+ side = sys.argv[1]
+ open = sys.argv[2] == 'open'
+
+ ag = ActuateGripper(side)
+
+ rospy.init_node('actuate_gripper', anonymous=True)
+
+ # HACK
+ import time
+ time.sleep(2.0)
+
+ res = ag.actuateGripper(open)
+
+ if res:
+ print 'Success!'
+ else:
+ print 'Failure!'
Added: pkg/trunk/demos/tabletop_manipulation/scripts/actuatetorso.py
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/scripts/actuatetorso.py (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/scripts/actuatetorso.py 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2009, 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.
+#
+# Revision $Id: rossync 3844 2009-02-16 19:49:10Z gerkey $
+
+import roslib
+roslib.load_manifest('tabletop_manipulation')
+import rospy
+from std_msgs.msg import Float64
+
+import sys
+
+class ActuateTorso:
+ def __init__(self):
+ self.status = None
+ self.torso_down_effort = -4000.0
+ self.torso_up_effort = 4000.0
+ self.pub = rospy.Publisher('torso_lift/effort_controller/set_command', Float64)
+ #rospy.Subscriber(self.side + '_arm_state', MoveArmState, self.movearmCallback)
+
+ def actuateTorso(self, up):
+ msg = Float64()
+ if up:
+ print '[ActuateTorso] Raising torso...'
+ msg.data = self.torso_up_effort
+ else:
+ print '[ActuateTorso] Lowering torso...'
+ msg.data = self.torso_down_effort
+ self.pub.publish(msg)
+
+ # HACK: don't know what to monitor to determine that the torso is
+ # done raising or lowering
+ print '[ActuateTorso] Waiting for torso to finish moving...'
+ rospy.sleep(4.0)
+
+ return True
+
+USAGE = 'actuatetorso.py {up|down}'
+if __name__ == '__main__':
+ if len(sys.argv) != 2 or \
+ (sys.argv[1] != 'up' and sys.argv[1] != 'down'):
+ print USAGE
+ sys.exit(-1)
+
+ up = sys.argv[1] == 'up'
+
+ ag = ActuateTorso()
+
+ rospy.init_node('actuate_torso', anonymous=True)
+
+ # HACK
+ import time
+ time.sleep(2.0)
+
+ res = ag.actuateTorso(up)
+
+ if res:
+ print 'Success!'
+ else:
+ print 'Failure!'
Modified: pkg/trunk/demos/tabletop_manipulation/scripts/approachtable.py
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/scripts/approachtable.py 2009-03-03 02:30:35 UTC (rev 12027)
+++ pkg/trunk/demos/tabletop_manipulation/scripts/approachtable.py 2009-03-03 02:32:36 UTC (rev 12028)
@@ -115,6 +115,7 @@
if not ts.tiltScan(2.0):
print '[ApproachTable] Failed to change tilt scan'
return False
+
# Call out to blocking MoveBase
return self.mb.moveBase(resp.table.header.frame_id,
approach_pose[0],
@@ -302,8 +303,8 @@
if at.approachTable(1.0, True):
res = at.approachTable(0.4, True)
- if res:
+ if not res:
+ print 'Failure!'
+ else:
print 'Success!'
- else:
- print 'Failure!'
Added: pkg/trunk/demos/tabletop_manipulation/scripts/detecttable.py
===================================================================
--- pkg/trunk/demos/tabletop_manipulation/scripts/detecttable.py (rev 0)
+++ pkg/trunk/demos/tabletop_manipulation/scripts/detecttable.py 2009-03-03 02:32:36 UTC (rev 12028)
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2009, 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.
+#
+# Revision $Id: rossync 3844 2009-02-16 19:49:10Z gerkey $
+
+import roslib
+roslib.load_manifest('tabletop_manipulation')
+import rospy
+from robot_srvs.srv import Fin...
[truncated message content] |
|
From: <vij...@us...> - 2009-03-03 22:40:46
|
Revision: 12062
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12062&view=rev
Author: vijaypradeep
Date: 2009-03-03 22:40:37 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
Working on updating laser_traj_controller to use the new filter API/xml
Modified Paths:
--------------
pkg/trunk/controllers/pr2_mechanism_controllers/include/pr2_mechanism_controllers/laser_scanner_traj_controller.h
pkg/trunk/controllers/pr2_mechanism_controllers/src/laser_scanner_traj_controller.cpp
pkg/trunk/robot_descriptions/pr2/pr2_experimental_controllers/laser_tilt/laser_tilt_controller.xml
Modified: pkg/trunk/controllers/pr2_mechanism_controllers/include/pr2_mechanism_controllers/laser_scanner_traj_controller.h
===================================================================
--- pkg/trunk/controllers/pr2_mechanism_controllers/include/pr2_mechanism_controllers/laser_scanner_traj_controller.h 2009-03-03 22:39:59 UTC (rev 12061)
+++ pkg/trunk/controllers/pr2_mechanism_controllers/include/pr2_mechanism_controllers/laser_scanner_traj_controller.h 2009-03-03 22:40:37 UTC (rev 12062)
@@ -84,7 +84,7 @@
private:
- void initDErrorFilter(double f) ; // Initializes d_error_filter using a smoothing factor
+ //void initDErrorFilter(double f) ; // Initializes d_error_filter using a smoothing factor
mechanism::RobotState *robot_ ;
mechanism::JointState *joint_state_ ; // Need this to check the calibrated flag on the joint
@@ -111,7 +111,7 @@
// Control loop state
control_toolbox::Pid pid_controller_ ; // Position PID Controller
- filters::TransferFunctionFilter<double >* d_error_filter ; // Filter on derivative term of error
+ filters::TransferFunctionFilter<double> d_error_filter ; // Filter on derivative term of error
double last_time_ ; // The previous time at which the control loop was run
double last_error_ ; // Error for the previous time at which the control loop was run
double tracking_offset_ ; // Position cmd generated by the track_link code
Modified: pkg/trunk/controllers/pr2_mechanism_controllers/src/laser_scanner_traj_controller.cpp
===================================================================
--- pkg/trunk/controllers/pr2_mechanism_controllers/src/laser_scanner_traj_controller.cpp 2009-03-03 22:39:59 UTC (rev 12061)
+++ pkg/trunk/controllers/pr2_mechanism_controllers/src/laser_scanner_traj_controller.cpp 2009-03-03 22:40:37 UTC (rev 12062)
@@ -47,13 +47,11 @@
{
tracking_offset_ = 0 ;
track_link_enabled_ = false ;
- d_error_filter = NULL ;
}
LaserScannerTrajController::~LaserScannerTrajController()
{
- if (d_error_filter != NULL)
- delete d_error_filter ;
+
}
bool LaserScannerTrajController::initXml(mechanism::RobotState *robot, TiXmlElement *config)
@@ -109,21 +107,15 @@
last_time_ = robot->hw_->current_time_ ;
last_error_ = 0.0 ;
- // ***** Derivate Error Filter Element *****
- TiXmlElement *filter_elem = config->FirstChildElement("d_error_filter");
+ // ***** Derivative Error Filter Element *****
+ TiXmlElement *filter_elem = config->FirstChildElement("filter");
if(!filter_elem)
{
- ROS_ERROR("%s:: d_error_filter element not defined inside controller", name_.c_str()) ;
+ ROS_ERROR("%s:: filter element not defined inside controller", name_.c_str()) ;
return false ;
}
- double smoothing_factor ;
- if(filter_elem->QueryDoubleAttribute("smoothing_factor", & smoothing_factor)!=TIXML_SUCCESS)
- {
- ROS_ERROR("%s:: Error reading \"smoothing_factor\" element in d_error_filter element", name_.c_str()) ;
- return false ;
- }
- initDErrorFilter(smoothing_factor) ;
+ d_error_filter.FilterBase<double>::configure((unsigned int)1, filter_elem) ;
// ***** Max Rate and Acceleration Elements *****
TiXmlElement *max_rate_elem = config->FirstChildElement("max_rate") ;
@@ -141,21 +133,6 @@
return true ;
}
-void LaserScannerTrajController::initDErrorFilter(double f)
-{
- vector<double> a ;
- vector<double> b ;
- a.resize(2) ;
- b.resize(1) ;
- a[0] = 1.0 ;
- a[1] = - (1.0 - f) ;
- b[0] = 1.0 ;
-
- if(d_error_filter == NULL)
- delete d_error_filter ;
- d_error_filter = new TransferFunctionFilter<double>(b,a,1) ;
-}
-
void LaserScannerTrajController::update()
{
if (!joint_state_->calibrated_)
@@ -215,16 +192,13 @@
error) ;
double dt = time - last_time_ ;
double d_error = (error-last_error_)/dt ;
- vector<double> filtered_d_error ;
- filtered_d_error.resize(1) ;
+ double filtered_d_error ;
- vector<double> d_error_vec(1,d_error) ;
+ d_error_filter.update(d_error, filtered_d_error) ;
- d_error_filter->update(&d_error_vec, &filtered_d_error) ;
-
// Add filtering step
// Update pid with d_error added
- joint_state_->commanded_effort_ = pid_controller_.updatePid(error, filtered_d_error[0], dt) ;
+ joint_state_->commanded_effort_ = pid_controller_.updatePid(error, filtered_d_error, dt) ;
last_time_ = time ;
last_error_ = error ;
}
@@ -417,6 +391,8 @@
prev_profile_time_ = 0.0 ;
+ ROS_INFO("Successfully spawned %s", service_prefix_.c_str()) ;
+
return true ;
}
Modified: pkg/trunk/robot_descriptions/pr2/pr2_experimental_controllers/laser_tilt/laser_tilt_controller.xml
===================================================================
--- pkg/trunk/robot_descriptions/pr2/pr2_experimental_controllers/laser_tilt/laser_tilt_controller.xml 2009-03-03 22:39:59 UTC (rev 12061)
+++ pkg/trunk/robot_descriptions/pr2/pr2_experimental_controllers/laser_tilt/laser_tilt_controller.xml 2009-03-03 22:40:37 UTC (rev 12062)
@@ -2,7 +2,9 @@
<controller name="laser_tilt_controller" topic="laser_controller" type="LaserScannerTrajControllerNode">
<max_acc value="1.0" />
<max_rate value="100.0" />
- <d_error_filter smoothing_factor=".05" />
+ <filter name="d_error_filter" type="TransferFunctionFilter">
+ <params a="1.0 -.1" b=".9" />
+ </filter>
<joint name="laser_tilt_mount_joint">
<pid p="8" i=".1" d="0.2" iClamp="0.5" />
</joint>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-04 00:08:43
|
Revision: 12077
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12077&view=rev
Author: tfoote
Date: 2009-03-04 00:08:41 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
moving teleop_base_keyboard into teleop_base package
Modified Paths:
--------------
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-amcl.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-fake_localization.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-amcl.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-fake_localization.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl-no_x.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization-no_x.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-amcl.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization-no_x.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl-no_x.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization-no_x.xml
pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization.xml
pkg/trunk/demos/2dnav_gazebo/doc.dox
pkg/trunk/demos/2dnav_gazebo/manifest.xml
pkg/trunk/demos/examples_gazebo/manifest.xml
pkg/trunk/demos/pr2_prototype1_gazebo/manifest.xml
pkg/trunk/demos/test_2dnav_gazebo/manifest.xml
pkg/trunk/nav/teleop_base/CMakeLists.txt
pkg/trunk/nav/teleop_base/manifest.xml
Added Paths:
-----------
pkg/trunk/nav/teleop_base/src/
pkg/trunk/nav/teleop_base/src/teleop_base_keyboard.cpp
Removed Paths:
-------------
pkg/trunk/nav/teleop_base_keyboard/
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-amcl.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-amcl.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-amcl.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-fake_localization.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-fake_localization.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-empty-fake_localization.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -23,7 +23,7 @@
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-amcl.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-amcl.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-amcl.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-fake_localization.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-fake_localization.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-simple-fake_localization.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl-no_x.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl-no_x.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl-no_x.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<!--node pkg="nav_view" type="nav_view" respawn="false" output="screen" /-->
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-amcl.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization-no_x.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization-no_x.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization-no_x.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<!--node pkg="nav_view" type="nav_view" respawn="false" output="screen" /-->
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-prototype1-wg-fake_localization.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -16,7 +16,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-amcl.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-amcl.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-amcl.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization-no_x.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization-no_x.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization-no_x.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -20,7 +20,7 @@
<node pkg="rviz" type="rviz" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-simple-fake_localization.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl-no_x.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl-no_x.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl-no_x.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<!--node pkg="nav_view" type="nav_view" respawn="false" output="screen" /-->
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-amcl.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization-no_x.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization-no_x.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization-no_x.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<!--node pkg="nav_view" type="nav_view" respawn="false" output="screen" /-->
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/2dnav-gazebo-wg-fake_localization.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -19,7 +19,7 @@
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</group>
Modified: pkg/trunk/demos/2dnav_gazebo/doc.dox
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/doc.dox 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/doc.dox 2009-03-04 00:08:41 UTC (rev 12077)
@@ -35,7 +35,7 @@
<!--node pkg="rviz" type="rviz" respawn="false" output="screen" /-->
<node pkg="nav_view" type="nav_view" respawn="false" output="screen" />
<!-- for manual control -->
- <!--node pkg="teleop_base_keyboard" type="teleop_base_keyboard" respawn="false" output="screen" /-->
+ <!--node pkg="teleop_base" type="teleop_base_keyboard" respawn="false" output="screen" /-->
<!--node pkg="teleop_arm_keyboard" type="teleop_arm_keyboard" respawn="false" output="screen" /-->
</launch>
@endverbatim
Modified: pkg/trunk/demos/2dnav_gazebo/manifest.xml
===================================================================
--- pkg/trunk/demos/2dnav_gazebo/manifest.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/2dnav_gazebo/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -12,7 +12,7 @@
<depend package="amcl_player"/>
<depend package="fake_localization"/>
<depend package="wavefront_player"/>
- <depend package="teleop_base_keyboard"/>
+ <depend package="teleop_base"/>
<depend package="teleop_arm_keyboard"/>
<depend package="laser_view"/>
<depend package="pr2_gui"/>
Modified: pkg/trunk/demos/examples_gazebo/manifest.xml
===================================================================
--- pkg/trunk/demos/examples_gazebo/manifest.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/examples_gazebo/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -5,7 +5,6 @@
<review status="na" notes=""/>
<url>http://pr.willowgarage.com/wiki/Simulator</url>
<depend package="gazebo_plugin"/>
- <depend package="teleop_base_keyboard"/>
<depend package="teleop_arm_keyboard"/>
<depend package="laser_view"/>
<depend package="pr2_gui"/>
Modified: pkg/trunk/demos/pr2_prototype1_gazebo/manifest.xml
===================================================================
--- pkg/trunk/demos/pr2_prototype1_gazebo/manifest.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/pr2_prototype1_gazebo/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -5,7 +5,6 @@
<review status="na" notes="demo scripts"/>
<url>http://pr.willowgarage.com/wiki/Simulator</url>
<depend package="gazebo_plugin"/>
- <depend package="teleop_base_keyboard"/>
<depend package="teleop_arm_keyboard"/>
<depend package="laser_view"/>
<depend package="pr2_gui"/>
Modified: pkg/trunk/demos/test_2dnav_gazebo/manifest.xml
===================================================================
--- pkg/trunk/demos/test_2dnav_gazebo/manifest.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/demos/test_2dnav_gazebo/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -10,7 +10,6 @@
<depend package="amcl_player"/>
<depend package="fake_localization"/>
<depend package="wavefront_player"/>
- <depend package="teleop_base_keyboard"/>
<depend package="teleop_arm_keyboard"/>
<depend package="laser_view"/>
<depend package="pr2_gui"/>
Modified: pkg/trunk/nav/teleop_base/CMakeLists.txt
===================================================================
--- pkg/trunk/nav/teleop_base/CMakeLists.txt 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/nav/teleop_base/CMakeLists.txt 2009-03-04 00:08:41 UTC (rev 12077)
@@ -3,3 +3,4 @@
rospack(teleop_base)
rospack_add_executable(teleop_base teleop_base.cpp)
rospack_add_executable(teleop_head teleop_head.cpp)
+rospack_add_executable(teleop_base_keyboard src/teleop_base_keyboard.cpp)
\ No newline at end of file
Modified: pkg/trunk/nav/teleop_base/manifest.xml
===================================================================
--- pkg/trunk/nav/teleop_base/manifest.xml 2009-03-04 00:05:52 UTC (rev 12076)
+++ pkg/trunk/nav/teleop_base/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
@@ -3,6 +3,7 @@
<license>BSD</license>
<review status="unreviewed" notes=""/>
<depend package="joy"/>
+ <depend package="roscpp"/>
<depend package="std_msgs"/>
<depend package="robot_srvs"/>
</package>
Copied: pkg/trunk/nav/teleop_base/src/teleop_base_keyboard.cpp (from rev 10961, pkg/trunk/nav/teleop_base_keyboard/teleop_base_keyboard.cpp)
===================================================================
--- pkg/trunk/nav/teleop_base/src/teleop_base_keyboard.cpp (rev 0)
+++ pkg/trunk/nav/teleop_base/src/teleop_base_keyboard.cpp 2009-03-04 00:08:41 UTC (rev 12077)
@@ -0,0 +1,286 @@
+/*
+ * teleop_base_keyboard
+ * 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 <ORGANIZATION> 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.
+ */
+
+/**
+
+@mainpage
+
+@htmlinclude manifest.html
+
+@b teleop_base_keyboard teleoperates a differential-drive robot by mapping
+key presses into velocity commands. Consider it a poor man's joystick.
+
+<hr>
+
+@section usage Usage
+@verbatim
+$ teleop_base_keyboard [standard ROS args]
+@endverbatim
+
+Key mappings are printed to screen on startup. Press any unmapped key to
+stop the robot.
+
+<hr>
+
+@section topic ROS topics
+
+Subscribes to (name/type):
+- None
+
+Publishes to (name / type):
+- @b "cmd_vel"/PoseDot : velocity to the robot; sent on every keypress.
+
+<hr>
+
+@section parameters ROS parameters
+
+- None
+
+ **/
+
+#include <termios.h>
+#include <signal.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include <ros/node.h>
+#include <robot_msgs/PoseDot.h>
+
+#define KEYCODE_I 0x69
+#define KEYCODE_J 0x6a
+#define KEYCODE_K 0x6b
+#define KEYCODE_L 0x6c
+#define KEYCODE_Q 0x71
+#define KEYCODE_Z 0x7a
+#define KEYCODE_W 0x77
+#define KEYCODE_X 0x78
+#define KEYCODE_E 0x65
+#define KEYCODE_C 0x63
+#define KEYCODE_U 0x75
+#define KEYCODE_O 0x6F
+#define KEYCODE_M 0x6d
+#define KEYCODE_R 0x72
+#define KEYCODE_V 0x76
+#define KEYCODE_T 0x74
+#define KEYCODE_B 0x62
+
+#define KEYCODE_COMMA 0x2c
+#define KEYCODE_PERIOD 0x2e
+
+#define COMMAND_TIMEOUT_SEC 0.2
+
+// at full joystick depression you'll go this fast
+double max_speed = 0.500; // m/second
+double max_turn = 60.0*M_PI/180.0; // rad/second
+// should we continuously send commands?
+bool always_command = false;
+
+
+class TBK_Node : public ros::Node
+{
+ private:
+ robot_msgs::PoseDot cmdvel;
+
+ public:
+ TBK_Node() : ros::Node("tbk")
+ {
+ advertise<robot_msgs::PoseDot>("cmd_vel",1);
+ }
+ ~TBK_Node() { }
+ void keyboardLoop();
+ void stopRobot()
+ {
+ cmdvel.vel.vx = cmdvel.ang_vel.vz = 0.0;
+ publish("cmd_vel", cmdvel);
+ }
+};
+
+TBK_Node* tbk;
+int kfd = 0;
+struct termios cooked, raw;
+
+void
+quit(int sig)
+{
+ tbk->stopRobot();
+
+ tcsetattr(kfd, TCSANOW, &cooked);
+ exit(0);
+}
+
+int
+main(int argc, char** argv)
+{
+ ros::init(argc,argv);
+
+ tbk = new TBK_Node();
+
+ signal(SIGINT,quit);
+
+ tbk->keyboardLoop();
+
+ return(0);
+}
+
+void
+TBK_Node::keyboardLoop()
+{
+ char c;
+ double max_tv = max_speed;
+ double max_rv = max_turn;
+ bool dirty=false;
+
+ int speed=0;
+ int turn=0;
+
+ // get the console in raw mode
+ tcgetattr(kfd, &cooked);
+ memcpy(&raw, &cooked, sizeof(struct termios));
+ raw.c_lflag &=~ (ICANON | ECHO);
+ raw.c_cc[VEOL] = 1;
+ raw.c_cc[VEOF] = 2;
+ tcsetattr(kfd, TCSANOW, &raw);
+
+ puts("Reading from keyboard");
+ puts("---------------------------");
+ puts("Moving around:");
+ puts(" u i o");
+ puts(" j k l");
+ puts(" m , .");
+ puts("");
+ puts("q/z : increase/decrease max speeds by 10%");
+ puts("w/x : increase/decrease only linear speed by 10%");
+ puts("e/c : increase/decrease only angular speed by 10%");
+ puts("");
+ puts("anything else : stop");
+ puts("---------------------------");
+
+ for(;;)
+ {
+ // get the next event from the keyboard
+ if(read(kfd, &c, 1) < 0)
+ {
+ perror("read():");
+ exit(-1);
+ }
+
+ switch(c)
+ {
+ case KEYCODE_I:
+ speed = 1;
+ turn = 0;
+ dirty = true;
+ break;
+ case KEYCODE_K:
+ speed = 0;
+ turn = 0;
+ dirty = true;
+ break;
+ case KEYCODE_O:
+ speed = 1;
+ turn = -1;
+ dirty = true;
+ break;
+ case KEYCODE_J:
+ speed = 0;
+ turn = 1;
+ dirty = true;
+ break;
+ case KEYCODE_L:
+ speed = 0;
+ turn = -1;
+ dirty = true;
+ break;
+ case KEYCODE_U:
+ turn = 1;
+ speed = 1;
+ dirty = true;
+ break;
+ case KEYCODE_COMMA:
+ turn = 0;
+ speed = -1;
+ dirty = true;
+ break;
+ case KEYCODE_PERIOD:
+ turn = 1;
+ speed = -1;
+ dirty = true;
+ break;
+ case KEYCODE_M:
+ turn = -1;
+ speed = -1;
+ dirty = true;
+ break;
+ case KEYCODE_Q:
+ max_tv += max_tv / 10.0;
+ max_rv += max_rv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ case KEYCODE_Z:
+ max_tv -= max_tv / 10.0;
+ max_rv -= max_rv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ case KEYCODE_W:
+ max_tv += max_tv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ case KEYCODE_X:
+ max_tv -= max_tv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ case KEYCODE_E:
+ max_rv += max_rv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ case KEYCODE_C:
+ max_rv -= max_rv / 10.0;
+ if(always_command)
+ dirty = true;
+ break;
+ default:
+ speed = 0;
+ turn = 0;
+ dirty = true;
+ }
+ if (dirty == true)
+ {
+ cmdvel.vel.vx = speed * max_tv;
+ cmdvel.ang_vel.vz = turn * max_rv;
+
+ publish("cmd_vel",cmdvel);
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-04 00:15:53
|
Revision: 12078
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12078&view=rev
Author: tfoote
Date: 2009-03-04 00:15:52 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
teleop_base_pedals is now inside teleop_base package too
Modified Paths:
--------------
pkg/trunk/nav/teleop_base/manifest.xml
pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/manifest.xml
pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/master_teleop.launch
Added Paths:
-----------
pkg/trunk/nav/teleop_base/scripts/
pkg/trunk/nav/teleop_base/scripts/teleop_base_pedals
pkg/trunk/nav/teleop_base/teleop_base_pedals.launch
Removed Paths:
-------------
pkg/trunk/manip/teleop_base_pedals/
Modified: pkg/trunk/nav/teleop_base/manifest.xml
===================================================================
--- pkg/trunk/nav/teleop_base/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
+++ pkg/trunk/nav/teleop_base/manifest.xml 2009-03-04 00:15:52 UTC (rev 12078)
@@ -4,6 +4,7 @@
<review status="unreviewed" notes=""/>
<depend package="joy"/>
<depend package="roscpp"/>
+ <depend package="rospy"/>
<depend package="std_msgs"/>
<depend package="robot_srvs"/>
</package>
Copied: pkg/trunk/nav/teleop_base/scripts/teleop_base_pedals (from rev 11502, pkg/trunk/manip/teleop_base_pedals/src/teleop_base_pedals)
===================================================================
--- pkg/trunk/nav/teleop_base/scripts/teleop_base_pedals (rev 0)
+++ pkg/trunk/nav/teleop_base/scripts/teleop_base_pedals 2009-03-04 00:15:52 UTC (rev 12078)
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+PKG = 'teleop_base'
+import roslib; roslib.load_manifest(PKG)
+
+import rospy
+
+from joy.msg import Joy
+from robot_msgs.msg import PoseDot
+
+r_pedal_state = 0
+l_pedal_state = 0
+
+def l_pedal_callback(data):
+ global l_pedal_state
+ l_pedal_state = data
+
+def r_pedal_callback(data):
+ global r_pedal_state
+ r_pedal_state = data
+
+def valid_pedals(data):
+ if(data == 0):
+ return False
+ if(len(data.axes) != 3):
+ return False
+ return True
+
+def teleop_base_pedals():
+ rospy.init_node('teleop_base_pedals')
+ pub = rospy.Publisher('cmd_vel', PoseDot)
+ rospy.Subscriber("l_pedals", Joy, l_pedal_callback)
+ rospy.Subscriber("r_pedals", Joy, r_pedal_callback)
+
+ cmd_vel = PoseDot()
+ max_rot_vel = 3
+ max_y_vel = 0.3
+ max_x_vel = 1
+
+ while not rospy.is_shutdown():
+ if(valid_pedals(l_pedal_state) & valid_pedals(r_pedal_state)):
+ cmd_vel.vel.vx = (r_pedal_state.axes[2] - l_pedal_state.axes[2]) * 0.5 * max_x_vel
+ cmd_vel.vel.vy = (r_pedal_state.axes[0] - l_pedal_state.axes[1]) * 0.5 * max_y_vel
+ cmd_vel.vel.vz = 0
+ cmd_vel.ang_vel.vx = 0
+ cmd_vel.ang_vel.vy = 0
+ cmd_vel.ang_vel.vz = (r_pedal_state.axes[2] + l_pedal_state.axes[2]) * 0.5 * max_rot_vel
+ pub.publish(cmd_vel)
+ rospy.sleep(0.05)
+
+if __name__ == '__main__':
+ teleop_base_pedals()
Copied: pkg/trunk/nav/teleop_base/teleop_base_pedals.launch (from rev 11167, pkg/trunk/manip/teleop_base_pedals/teleop_base_pedals.launch)
===================================================================
--- pkg/trunk/nav/teleop_base/teleop_base_pedals.launch (rev 0)
+++ pkg/trunk/nav/teleop_base/teleop_base_pedals.launch 2009-03-04 00:15:52 UTC (rev 12078)
@@ -0,0 +1,13 @@
+<launch>
+ <node pkg="joy" type="joy" name="r_pedals">
+ <remap from="joy" to="r_pedals"/>
+ <param name="dev" value="/dev/input/js0"/>
+ <param name="deadzone" value="0"/>
+ </node>
+ <node pkg="joy" type="joy" name="l_pedals">
+ <remap from="joy" to="l_pedals"/>
+ <param name="dev" value="/dev/input/js1"/>
+ <param name="deadzone" value="0"/>
+ </node>
+ <node pkg="teleop_base" type="teleop_base_pedals" output="screen"/>
+</launch>
Modified: pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/manifest.xml
===================================================================
--- pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/manifest.xml 2009-03-04 00:08:41 UTC (rev 12077)
+++ pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/manifest.xml 2009-03-04 00:15:52 UTC (rev 12078)
@@ -8,7 +8,7 @@
<review status="na" notes=""/>
<depend package="pr2_phase_space" />
- <depend package="teleop_base_pedals" />
+ <depend package="teleop_base" />
<depend package="teleop_joint_effort" />
</package>
Modified: pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/master_teleop.launch
===================================================================
--- pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/master_teleop.launch 2009-03-04 00:08:41 UTC (rev 12077)
+++ pkg/trunk/robot_descriptions/pr2/pr2_configurations/pr2_teleop/master_teleop.launch 2009-03-04 00:15:52 UTC (rev 12078)
@@ -1,7 +1,7 @@
<launch>
<!-- Base Pedals -->
- <include file="$(find teleop_base_pedals)/teleop_base_pedals.launch" />
+ <include file="$(find teleop_base)/teleop_base_pedals.launch" />
<!-- Phase Space -->
<node pkg="phase_space" type="phase_space_node" output="log" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <is...@us...> - 2009-03-04 02:51:09
|
Revision: 12092
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12092&view=rev
Author: isucan
Date: 2009-03-04 02:51:07 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
support for meshes
Modified Paths:
--------------
pkg/trunk/motion_planning/planning_models/CMakeLists.txt
pkg/trunk/motion_planning/planning_models/src/kinematic.cpp
pkg/trunk/motion_planning/planning_models/src/load_mesh.cpp
pkg/trunk/motion_planning/planning_models/test/test_kinematic.cpp
pkg/trunk/world_models/collision_space/CMakeLists.txt
pkg/trunk/world_models/collision_space/include/collision_space/point_inclusion.h
pkg/trunk/world_models/collision_space/src/collision_space/point_inclusion.cpp
Modified: pkg/trunk/motion_planning/planning_models/CMakeLists.txt
===================================================================
--- pkg/trunk/motion_planning/planning_models/CMakeLists.txt 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/motion_planning/planning_models/CMakeLists.txt 2009-03-04 02:51:07 UTC (rev 12092)
@@ -3,7 +3,7 @@
rospack(planning_models)
rospack_add_boost_directories()
-set(CMAKE_BUILD_TYPE Release)
+#set(CMAKE_BUILD_TYPE Release)
rospack_add_library(planning_models src/kinematic.cpp
src/load_mesh.cpp)
Modified: pkg/trunk/motion_planning/planning_models/src/kinematic.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/src/kinematic.cpp 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/motion_planning/planning_models/src/kinematic.cpp 2009-03-04 02:51:07 UTC (rev 12092)
@@ -52,7 +52,7 @@
};
// load a mesh
- shapes::Mesh* load_binary_stl(const char *filename);
+ shapes::Mesh* create_mesh_from_binary_stl(const char *filename);
}
const std::string& planning_models::KinematicModel::getModelName(void) const
Modified: pkg/trunk/motion_planning/planning_models/src/load_mesh.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/src/load_mesh.cpp 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/motion_planning/planning_models/src/load_mesh.cpp 2009-03-04 02:51:07 UTC (rev 12092)
@@ -34,7 +34,6 @@
#include <cstdio>
#include <cmath>
-#include <cassert>
#include <LinearMath/btVector3.h>
#include <algorithm>
#include <vector>
@@ -80,9 +79,90 @@
}
};
- shapes::Mesh* load_binary_stl(const char *filename)
+ shapes::Mesh* create_mesh_from_vertices(const std::vector<btVector3> &source)
{
+ if (source.size() < 3)
+ return NULL;
+
+ std::set<myVertex, ltVertexValue> vertices;
+ std::vector<unsigned int> triangles;
+
+ for (unsigned int i = 0 ; i < source.size() / 3 ; ++i)
+ {
+ // check if we have new vertices
+ myVertex vt;
+
+ vt.point = source[3 * i];
+ std::set<myVertex, ltVertexValue>::iterator p1 = vertices.find(vt);
+ if (p1 == vertices.end())
+ {
+ vt.index = vertices.size();
+ vertices.insert(vt);
+ }
+ else
+ vt.index = p1->index;
+ triangles.push_back(vt.index);
+
+ vt.point = source[3 * i + 1];
+ std::set<myVertex, ltVertexValue>::iterator p2 = vertices.find(vt);
+ if (p2 == vertices.end())
+ {
+ vt.index = vertices.size();
+ vertices.insert(vt);
+ }
+ else
+ vt.index = p2->index;
+ triangles.push_back(vt.index);
+
+ vt.point = source[3 * i + 2];
+ std::set<myVertex, ltVertexValue>::iterator p3 = vertices.find(vt);
+ if (p3 == vertices.end())
+ {
+ vt.index = vertices.size();
+ vertices.insert(vt);
+ }
+ else
+ vt.index = p3->index;
+ triangles.push_back(vt.index);
+ }
+
+ // sort our vertices
+ std::vector<myVertex> vt;
+ vt.insert(vt.begin(), vertices.begin(), vertices.end());
+ std::sort(vt.begin(), vt.end(), ltVertexIndex());
+
+ // copy the data to a mesh structure
+ unsigned int nt = triangles.size() / 3;
+
+ shapes::Mesh *mesh = new shapes::Mesh(vt.size(), nt);
+ for (unsigned int i = 0 ; i < vt.size() ; ++i)
+ {
+ mesh->vertices[3 * i ] = vt[i].point.getX();
+ mesh->vertices[3 * i + 1] = vt[i].point.getY();
+ mesh->vertices[3 * i + 2] = vt[i].point.getZ();
+ }
+
+ std::copy(triangles.begin(), triangles.end(), mesh->triangles);
+
+ // compute normals
+ for (unsigned int i = 0 ; i < nt ; ++i)
+ {
+ btVector3 s1 = vt[triangles[i * 3 ]].point - vt[triangles[i * 3 + 1]].point;
+ btVector3 s2 = vt[triangles[i * 3 + 1]].point - vt[triangles[i * 3 + 2]].point;
+ btVector3 normal = s1.cross(s2);
+ normal.normalize();
+ mesh->normals[3 * i ] = normal.getX();
+ mesh->normals[3 * i + 1] = normal.getY();
+ mesh->normals[3 * i + 2] = normal.getZ();
+ }
+
+ return mesh;
+ }
+
+ shapes::Mesh* create_mesh_from_binary_stl(const char *filename)
+ {
+
FILE* input = fopen(filename, "r");
if (!input)
return NULL;
@@ -107,10 +187,8 @@
// make sure we have read enough data
if (50 * numTriangles + 84 <= fileSize)
{
+ std::vector<btVector3> vertices;
- std::set<myVertex, ltVertexValue> vertices;
- std::vector<unsigned int> triangles;
-
for (unsigned int currentTriangle = 0 ; currentTriangle < numTriangles ; ++currentTriangle)
{
// skip the normal
@@ -145,77 +223,14 @@
// skip attribute
pos += 2;
- // check if we have new vertices
- myVertex vt;
-
- vt.point = v1;
- std::set<myVertex, ltVertexValue>::iterator p1 = vertices.find(vt);
- if (p1 == vertices.end())
- {
- vt.index = vertices.size();
- vertices.insert(vt);
- }
- else
- vt.index = p1->index;
- triangles.push_back(vt.index);
-
- vt.point = v2;
- std::set<myVertex, ltVertexValue>::iterator p2 = vertices.find(vt);
- if (p2 == vertices.end())
- {
- vt.index = vertices.size();
- vertices.insert(vt);
- }
- else
- vt.index = p2->index;
- triangles.push_back(vt.index);
-
- vt.point = v3;
- std::set<myVertex, ltVertexValue>::iterator p3 = vertices.find(vt);
- if (p3 == vertices.end())
- {
- vt.index = vertices.size();
- vertices.insert(vt);
- }
- else
- vt.index = p3->index;
- triangles.push_back(vt.index);
+ vertices.push_back(v1);
+ vertices.push_back(v2);
+ vertices.push_back(v3);
}
delete[] buffer;
- // sort our vertices
- std::vector<myVertex> vt;
- vt.insert(vt.begin(), vertices.begin(), vertices.end());
- std::sort(vt.begin(), vt.end(), ltVertexIndex());
-
-
- // copy the data to a mesh structure
- unsigned int nt = triangles.size() / 3;
-
- shapes::Mesh *mesh = new shapes::Mesh(vt.size(), nt);
- for (unsigned int i = 0 ; i < vt.size() ; ++i)
- {
- mesh->vertices[3 * i ] = vt[i].point.getX();
- mesh->vertices[3 * i + 1] = vt[i].point.getY();
- mesh->vertices[3 * i + 2] = vt[i].point.getZ();
- }
-
- std::copy(triangles.begin(), triangles.end(), mesh->triangles);
-
- // compute normals
- for (unsigned int i = 0 ; i < nt ; ++i)
- {
- btVector3 s1 = vt[triangles[i * 3 ]].point - vt[triangles[i * 3 + 1]].point;
- btVector3 s2 = vt[triangles[i * 3 + 1]].point - vt[triangles[i * 3 + 2]].point;
- btVector3 normal = s1.cross(s2);
- normal.normalize();
- mesh->normals[3 * i ] = normal.getX();
- mesh->normals[3 * i + 1] = normal.getY();
- mesh->normals[3 * i + 2] = normal.getZ();
- }
-
- return mesh;
+ return create_mesh_from_vertices(vertices);
}
}
Modified: pkg/trunk/motion_planning/planning_models/test/test_kinematic.cpp
===================================================================
--- pkg/trunk/motion_planning/planning_models/test/test_kinematic.cpp 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/motion_planning/planning_models/test/test_kinematic.cpp 2009-03-04 02:51:07 UTC (rev 12092)
@@ -822,6 +822,18 @@
delete model;
}
+namespace planning_models
+{
+ shapes::Mesh* create_mesh_from_binary_stl(const char *filename);
+}
+
+TEST(Loading, Mesh)
+{
+ planning_models::shapes::Mesh *m = planning_models::create_mesh_from_binary_stl("/home/isucan/base.stl");
+ EXPECT_TRUE(m != NULL);
+ delete m;
+}
+
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
Modified: pkg/trunk/world_models/collision_space/CMakeLists.txt
===================================================================
--- pkg/trunk/world_models/collision_space/CMakeLists.txt 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/world_models/collision_space/CMakeLists.txt 2009-03-04 02:51:07 UTC (rev 12092)
@@ -15,4 +15,5 @@
# Unit tests
rospack_add_gtest(test_point_inclusion test/test_point_inclusion.cpp)
+rospack_link_boost(test_point_inclusion thread)
target_link_libraries(test_point_inclusion collision_space)
Modified: pkg/trunk/world_models/collision_space/include/collision_space/point_inclusion.h
===================================================================
--- pkg/trunk/world_models/collision_space/include/collision_space/point_inclusion.h 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/world_models/collision_space/include/collision_space/point_inclusion.h 2009-03-04 02:51:07 UTC (rev 12092)
@@ -39,8 +39,10 @@
#include <planning_models/shapes.h>
#include <LinearMath/btTransform.h>
-#include <cmath>
+#include <LinearMath/btAlignedObjectArray.h>
+#include <cstdlib>
+
/**
This set of classes allows quickly detecting whether a given point
is inside an object or not. Only basic (simple) types of objects
@@ -142,25 +144,13 @@
{
}
- virtual bool containsPoint(const btVector3 &p) const
- {
- return (m_center - p).length2() < m_radius2;
- }
+ virtual bool containsPoint(const btVector3 &p) const;
protected:
- virtual void useDimensions(const planning_models::shapes::Shape *shape) // radius
- {
- m_radius = static_cast<const planning_models::shapes::Sphere*>(shape)->radius;
- }
+ virtual void useDimensions(const planning_models::shapes::Shape *shape);
+ virtual void updateInternalData(void);
- virtual void updateInternalData(void)
- {
- m_radius2 = m_radius * m_scale + m_padding;
- m_radius2 = m_radius2 * m_radius2;
- m_center = m_pose.getOrigin();
- }
-
btVector3 m_center;
double m_radius;
double m_radius2;
@@ -183,47 +173,13 @@
{
}
- virtual bool containsPoint(const btVector3 &p) const
- {
- btVector3 v = p - m_center;
- double pH = v.dot(m_normalH);
-
- if (fabs(pH) > m_length2)
- return false;
-
- double pB1 = v.dot(m_normalB1);
- double remaining = m_radius2 - pB1 * pB1;
-
- if (remaining < 0.0)
- return false;
- else
- {
- double pB2 = v.dot(m_normalB2);
- return pB2 * pB2 < remaining;
- }
- }
+ virtual bool containsPoint(const btVector3 &p) const;
protected:
- virtual void useDimensions(const planning_models::shapes::Shape *shape) // (length, radius)
- {
- m_length = static_cast<const planning_models::shapes::Cylinder*>(shape)->length;
- m_radius = static_cast<const planning_models::shapes::Cylinder*>(shape)->radius;
- }
-
- virtual void updateInternalData(void)
- {
- m_radius2 = m_radius * m_scale + m_padding;
- m_radius2 = m_radius2 * m_radius2;
- m_length2 = (m_scale * m_length + m_padding) / 2.0;
- m_center = m_pose.getOrigin();
+ virtual void useDimensions(const planning_models::shapes::Shape *shape);
+ virtual void updateInternalData(void);
- const btMatrix3x3& basis = m_pose.getBasis();
- m_normalB1 = basis.getColumn(0);
- m_normalB2 = basis.getColumn(1);
- m_normalH = basis.getColumn(2);
- }
-
btVector3 m_center;
btVector3 m_normalH;
btVector3 m_normalB1;
@@ -253,53 +209,13 @@
{
}
- virtual bool containsPoint(const btVector3 &p) const
- {
- btVector3 v = p - m_center;
- double pL = v.dot(m_normalL);
-
- if (fabs(pL) > m_length2)
- return false;
-
- double pW = v.dot(m_normalW);
-
- if (fabs(pW) > m_width2)
- return false;
-
- double pH = v.dot(m_normalH);
-
- if (fabs(pH) > m_height2)
- return false;
-
- return true;
- }
+ virtual bool containsPoint(const btVector3 &p) const;
protected:
- virtual void useDimensions(const planning_models::shapes::Shape *shape) // (x, y, z) = (length, width, height)
- {
- const double *size = static_cast<const planning_models::shapes::Box*>(shape)->size;
- m_length = size[0];
- m_width = size[1];
- m_height = size[2];
- }
+ virtual void useDimensions(const planning_models::shapes::Shape *shape); // (x, y, z) = (length, width, height)
+ virtual void updateInternalData(void);
- virtual void updateInternalData(void)
- {
- double s2 = m_scale / 2.0;
- double p2 = m_padding / 2.0;
- m_length2 = m_length * s2 + p2;
- m_width2 = m_width * s2 + p2;
- m_height2 = m_height * s2 + p2;
-
- m_center = m_pose.getOrigin();
-
- const btMatrix3x3& basis = m_pose.getBasis();
- m_normalL = basis.getColumn(0);
- m_normalW = basis.getColumn(1);
- m_normalH = basis.getColumn(2);
- }
-
btVector3 m_center;
btVector3 m_normalL;
btVector3 m_normalW;
@@ -313,6 +229,36 @@
double m_height2;
};
+
+ class ConvexMesh : public Body
+ {
+ public:
+
+ ConvexMesh(void) : Body()
+ {
+ }
+
+ ConvexMesh(const planning_models::shapes::Shape *shape) : Body()
+ {
+ setDimensions(shape);
+ }
+
+ virtual ~ConvexMesh(void)
+ {
+ }
+
+ virtual bool containsPoint(const btVector3 &p) const;
+
+ protected:
+
+ virtual void useDimensions(const planning_models::shapes::Shape *shape);
+ virtual void updateInternalData(void);
+
+ btAlignedObjectArray<btVector3> m_planes;
+ btTransform m_iPose;
+ };
+
+
Body* createBodyFromShape(const planning_models::shapes::Shape *shape);
}
Modified: pkg/trunk/world_models/collision_space/src/collision_space/point_inclusion.cpp
===================================================================
--- pkg/trunk/world_models/collision_space/src/collision_space/point_inclusion.cpp 2009-03-04 02:42:07 UTC (rev 12091)
+++ pkg/trunk/world_models/collision_space/src/collision_space/point_inclusion.cpp 2009-03-04 02:51:07 UTC (rev 12092)
@@ -36,7 +36,11 @@
#include "collision_space/point_inclusion.h"
#include "collision_space/output.h"
+#include <LinearMath/btConvexHull.h>
+#include <LinearMath/btGeometryUtil.h>
+#include <cmath>
+
static collision_space::msg::Interface MSG;
collision_space::bodies::Body* collision_space::bodies::createBodyFromShape(const planning_models::shapes::Shape *shape)
@@ -54,6 +58,9 @@
case planning_models::shapes::Shape::CYLINDER:
body = new collision_space::bodies::Cylinder(shape);
break;
+ case planning_models::shapes::Shape::MESH:
+ body = new collision_space::bodies::ConvexMesh(shape);
+ break;
default:
MSG.error("Creating body from shape: Unknown shape type %d", shape->type);
break;
@@ -61,3 +68,140 @@
return body;
}
+
+bool collision_space::bodies::Sphere::containsPoint(const btVector3 &p) const
+{
+ return (m_center - p).length2() < m_radius2;
+}
+
+void collision_space::bodies::Sphere::useDimensions(const planning_models::shapes::Shape *shape) // radius
+{
+ m_radius = static_cast<const planning_models::shapes::Sphere*>(shape)->radius;
+}
+
+void collision_space::bodies::Sphere::updateInternalData(void)
+{
+ m_radius2 = m_radius * m_scale + m_padding;
+ m_radius2 = m_radius2 * m_radius2;
+ m_center = m_pose.getOrigin();
+}
+
+bool collision_space::bodies::Cylinder::containsPoint(const btVector3 &p) const
+{
+ btVector3 v = p - m_center;
+ double pH = v.dot(m_normalH);
+
+ if (fabs(pH) > m_length2)
+ return false;
+
+ double pB1 = v.dot(m_normalB1);
+ double remaining = m_radius2 - pB1 * pB1;
+
+ if (remaining < 0.0)
+ return false;
+ else
+ {
+ double pB2 = v.dot(m_normalB2);
+ return pB2 * pB2 < remaining;
+ }
+}
+
+void collision_space::bodies::Cylinder::useDimensions(const planning_models::shapes::Shape *shape) // (length, radius)
+{
+ m_length = static_cast<const planning_models::shapes::Cylinder*>(shape)->length;
+ m_radius = static_cast<const planning_models::shapes::Cylinder*>(shape)->radius;
+}
+
+void collision_space::bodies::Cylinder::updateInternalData(void)
+{
+ m_radius2 = m_radius * m_scale + m_padding;
+ m_radius2 = m_radius2 * m_radius2;
+ m_length2 = (m_scale * m_length + m_padding) / 2.0;
+ m_center = m_pose.getOrigin();
+
+ const btMatrix3x3& basis = m_pose.getBasis();
+ m_normalB1 = basis.getColumn(0);
+ m_normalB2 = basis.getColumn(1);
+ m_normalH = basis.getColumn(2);
+}
+
+bool collision_space::bodies::Box::containsPoint(const btVector3 &p) const
+{
+ btVector3 v = p - m_center;
+ double pL = v.dot(m_normalL);
+
+ if (fabs(pL) > m_length2)
+ return false;
+
+ double pW = v.dot(m_normalW);
+
+ if (fabs(pW) > m_width2)
+ return false;
+
+ double pH = v.dot(m_normalH);
+
+ if (fabs(pH) > m_height2)
+ return false;
+
+ return true;
+}
+
+void collision_space::bodies::Box::useDimensions(const planning_models::shapes::Shape *shape) // (x, y, z) = (length, width, height)
+{
+ const double *size = static_cast<const planning_models::shapes::Box*>(shape)->size;
+ m_length = size[0];
+ m_width = size[1];
+ m_height = size[2];
+}
+
+void collision_space::bodies::Box::updateInternalData(void)
+{
+ double s2 = m_scale / 2.0;
+ double p2 = m_padding / 2.0;
+ m_length2 = m_length * s2 + p2;
+ m_width2 = m_width * s2 + p2;
+ m_height2 = m_height * s2 + p2;
+
+ m_center = m_pose.getOrigin();
+
+ const btMatrix3x3& basis = m_pose.getBasis();
+ m_normalL = basis.getColumn(0);
+ m_normalW = basis.getColumn(1);
+ m_normalH = basis.getColumn(2);
+}
+
+bool collision_space::bodies::ConvexMesh::containsPoint(const btVector3 &p) const
+{
+ btVector3 ip = (m_iPose * p) * m_scale;
+ return btGeometryUtil::isPointInsidePlanes(m_planes, ip, btScalar(m_padding));
+}
+
+void collision_space::bodies::ConvexMesh::useDimensions(const planning_models::shapes::Shape *shape)
+{
+ const planning_models::shapes::Mesh *mesh = static_cast<const planning_models::shapes::Mesh*>(shape);
+ m_planes.clear();
+
+ btVector3 *vertices = new btVector3[mesh->vertexCount];
+ for(unsigned int i = 0; i < mesh->vertexCount ; ++i)
+ {
+ vertices[i].setX(mesh->vertices[3 * i ]);
+ vertices[i].setY(mesh->vertices[3 * i + 1]);
+ vertices[i].setZ(mesh->vertices[3 * i + 2]);
+ }
+
+ HullDesc hd(QF_TRIANGLES, mesh->vertexCount, vertices);
+ HullResult hr;
+ HullLibrary hl;
+ if (hl.CreateConvexHull(hd, hr) == QE_OK)
+ btGeometryUtil::getPlaneEquationsFromVertices(hr.m_OutputVertices, m_planes);
+ else
+ MSG.error("Unable to compute convex hull");
+
+ hl.ReleaseResult(hr);
+ delete[] vertices;
+}
+
+void collision_space::bodies::ConvexMesh::updateInternalData(void)
+{
+ m_iPose = m_pose.inverse();
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <is...@us...> - 2009-03-04 03:30:46
|
Revision: 12096
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12096&view=rev
Author: isucan
Date: 2009-03-04 03:30:44 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
moving test_collision_space and added a test for meshes
Added Paths:
-----------
pkg/trunk/world_models/test_collision_space/
pkg/trunk/world_models/test_collision_space/CMakeLists.txt
pkg/trunk/world_models/test_collision_space/Makefile
pkg/trunk/world_models/test_collision_space/manifest.xml
pkg/trunk/world_models/test_collision_space/src/
pkg/trunk/world_models/test_collision_space/src/test_cs_point_inclusion.cpp
Removed Paths:
-------------
pkg/trunk/motion_planning/test_collision_space/
Added: pkg/trunk/world_models/test_collision_space/CMakeLists.txt
===================================================================
--- pkg/trunk/world_models/test_collision_space/CMakeLists.txt (rev 0)
+++ pkg/trunk/world_models/test_collision_space/CMakeLists.txt 2009-03-04 03:30:44 UTC (rev 12096)
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.4.6)
+include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
+rospack(test_collision_space)
+
+rospack_add_executable(test_cs_point_inclusion src/test_cs_point_inclusion.cpp)
Added: pkg/trunk/world_models/test_collision_space/Makefile
===================================================================
--- pkg/trunk/world_models/test_collision_space/Makefile (rev 0)
+++ pkg/trunk/world_models/test_collision_space/Makefile 2009-03-04 03:30:44 UTC (rev 12096)
@@ -0,0 +1 @@
+include $(shell rospack find mk)/cmake.mk
Added: pkg/trunk/world_models/test_collision_space/manifest.xml
===================================================================
--- pkg/trunk/world_models/test_collision_space/manifest.xml (rev 0)
+++ pkg/trunk/world_models/test_collision_space/manifest.xml 2009-03-04 03:30:44 UTC (rev 12096)
@@ -0,0 +1,18 @@
+<package>
+ <description brief="Test collision spaces">
+ A visualization tool to check whether collision space code is
+ working appropriately
+ </description>
+
+ <author>Ioan Sucan/is...@wi...</author>
+ <license>BSD</license>
+ <review status="unreviewed" notes=""/>
+
+ <depend package="roscpp"/>
+ <depend package="roslib"/>
+
+ <depend package="robot_msgs"/>
+ <depend package="planning_models"/>
+ <depend package="collision_space"/>
+
+</package>
Added: pkg/trunk/world_models/test_collision_space/src/test_cs_point_inclusion.cpp
===================================================================
--- pkg/trunk/world_models/test_collision_space/src/test_cs_point_inclusion.cpp (rev 0)
+++ pkg/trunk/world_models/test_collision_space/src/test_cs_point_inclusion.cpp 2009-03-04 03:30:44 UTC (rev 12096)
@@ -0,0 +1,282 @@
+/*********************************************************************
+* 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 <cstdlib>
+#include <ros/node.h>
+#include <ros/publisher.h>
+#include <ros/time.h>
+#include <collision_space/environmentODE.h>
+#include <algorithm>
+#include <robot_msgs/VisualizationMarker.h>
+#include <roslib/Time.h>
+#include <collision_space/point_inclusion.h>
+using namespace collision_space;
+
+const int TEST_TIMES = 3;
+const int TEST_POINTS = 50000;
+
+namespace planning_models
+{
+ shapes::Mesh* create_mesh_from_vertices(const std::vector<btVector3> &source);
+}
+
+class TestVM
+{
+public:
+
+ TestVM(void) : m_node("TVM")
+ {
+ m_node.advertise<robot_msgs::VisualizationMarker>("visualizationMarker", 10240);
+ m_id = 1;
+ }
+
+ virtual ~TestVM(void)
+ {
+ }
+
+ void sendPoint(double x, double y, double z)
+ {
+ robot_msgs::VisualizationMarker mk;
+
+ mk.header.stamp = m_tm;
+
+ mk.header.frame_id = "base_link";
+
+ mk.id = m_id++;
+ mk.type = robot_msgs::VisualizationMarker::SPHERE;
+ mk.action = robot_msgs::VisualizationMarker::ADD;
+ mk.x = x;
+ mk.y = y;
+ mk.z = z;
+
+ mk.roll = 0;
+ mk.pitch = 0;
+ mk.yaw = 0;
+
+ mk.xScale = 0.2;
+ mk.yScale = 0.2;
+ mk.zScale = 0.2;
+
+ mk.alpha = 255;
+ mk.r = 255;
+ mk.g = 10;
+ mk.b = 10;
+
+ m_node.publish("visualizationMarker", mk);
+ }
+
+ void testShape(collision_space::bodies::Body *s)
+ {
+ for (int i = 0 ; i < TEST_POINTS ; ++i)
+ {
+ double x = uniform(5.0);
+ double y = uniform(5.0);
+ double z = uniform(5.0);
+ if (!s->containsPoint(x, y, z))
+ continue;
+ sendPoint(x, y, z);
+ }
+ }
+
+ void setShapeTransformAndMarker(collision_space::bodies::Body *s,
+ robot_msgs::VisualizationMarker &mk)
+ {
+ btTransform t;
+
+ double yaw = uniform(M_PI);
+ double pitch = uniform(M_PI);
+ double roll = uniform(M_PI);
+
+ double x = uniform(3.0);
+ double y = uniform(3.0);
+ double z = uniform(3.0);
+
+ t.setRotation(btQuaternion(yaw, pitch, roll));
+ t.setOrigin(btVector3(btScalar(x), btScalar(y), btScalar(z)));
+
+ s->setPose(t);
+ s->setScale(0.99);
+
+ mk.header.stamp = m_tm;
+ mk.header.frame_id = "base_link";
+ mk.id = m_id++;
+
+ mk.action = robot_msgs::VisualizationMarker::ADD;
+
+ mk.x = x;
+ mk.y = y;
+ mk.z = z;
+
+ mk.roll = roll;
+ mk.pitch = pitch;
+ mk.yaw = yaw;
+
+ mk.alpha = 150;
+ mk.r = 0;
+ mk.g = 100;
+ mk.b = 255;
+ }
+
+ void testSphere(void)
+ {
+ planning_models::shapes::Sphere shape(2.0);
+ collision_space::bodies::Body *s = new collision_space::bodies::Sphere(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::SPHERE;
+ mk.xScale = shape.radius*2.0;
+ mk.yScale = shape.radius*2.0;
+ mk.zScale = shape.radius*2.0;
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void testBox(void)
+ {
+ planning_models::shapes::Box shape(2.0, 1.33, 1.5);
+ collision_space::bodies::Body *s = new collision_space::bodies::Box(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::CUBE;
+ mk.xScale = shape.size[0]; // length
+ mk.yScale = shape.size[1]; // width
+ mk.zScale = shape.size[2]; // height
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void testCylinder(void)
+ {
+ planning_models::shapes::Cylinder shape(0.5, 2.5);
+ collision_space::bodies::Body *s = new collision_space::bodies::Cylinder(&shape);
+
+ for (int i = 0 ; i < TEST_TIMES ; ++i)
+ {
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+
+ mk.type = robot_msgs::VisualizationMarker::CUBE;
+ mk.xScale = shape.radius * 2.0; // radius
+ mk.yScale = shape.radius * 2.0; // radius
+ mk.zScale = shape.length; //length
+
+ m_node.publish("visualizationMarker", mk);
+
+ testShape(s);
+ }
+
+ delete s;
+ }
+
+ void testConvexMesh(void)
+ {
+ std::vector<btVector3> pts(4);
+ pts[0] = btVector3(0,0,1);
+ pts[1] = btVector3(1,0,-0.3);
+ pts[2] = btVector3(-0.5,0.8,-0.3);
+ pts[3] = btVector3(-0.5,-0.8,-0.3);
+
+ planning_models::shapes::Mesh *shape = planning_models::create_mesh_from_vertices(pts);
+ collision_space::bodies::Body *s = new collision_space::bodies::ConvexMesh(shape);
+
+ robot_msgs::VisualizationMarker mk;
+ setShapeTransformAndMarker(s, mk);
+ testShape(s);
+
+ delete s;
+ delete shape;
+ }
+
+ void run()
+ {
+ ros::Duration d;
+ d.fromSec(2);
+ d.sleep();
+
+ m_tm = ros::Time::now();
+
+ testSphere();
+ testBox();
+ testCylinder();
+
+ m_node.spin();
+ m_node.shutdown();
+
+ }
+
+protected:
+
+ // return a random number (uniform distribution)
+ // between -magnitude and magnitude
+ double uniform(double magnitude)
+ {
+ return (2.0 * drand48() - 1.0) * magnitude;
+ }
+
+ ros::Node m_node;
+ ros::Time m_tm;
+ int m_id;
+
+};
+
+
+int main(int argc, char **argv)
+{
+ ros::init(argc, argv);
+
+ TestVM tvm;
+ tvm.run();
+
+ return 0;
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mc...@us...> - 2009-03-04 14:43:47
|
Revision: 12107
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12107&view=rev
Author: mcgann
Date: 2009-03-04 14:43:36 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
Updates for new Highlevel Controller Message
Modified Paths:
--------------
pkg/trunk/highlevel/executive_trex/executive_trex_pr2/include/ROSControllerAdapter.hh
pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/ROSAdapter.cc
pkg/trunk/highlevel/highlevel_controllers/include/highlevel_controllers/highlevel_controller.hh
pkg/trunk/highlevel/highlevel_controllers/msg/RechargeState.msg
pkg/trunk/highlevel/highlevel_controllers/src/move_arm.cpp
pkg/trunk/highlevel/highlevel_controllers/src/recharge_controller.cpp
pkg/trunk/mapping/door_handle_detector/test/open_door_executive_test.cpp
pkg/trunk/nav/wavefront_player/cli.cpp
pkg/trunk/nav/wavefront_player/wavefront_player.cc
pkg/trunk/pr2_msgs/msg/MoveArmState.msg
pkg/trunk/pr2_msgs/msg/MoveEndEffectorState.msg
pkg/trunk/prcore/robot_msgs/msg/Planner2DState.msg
Added Paths:
-----------
pkg/trunk/prcore/robot_msgs/msg/ControllerStatus.msg
Modified: pkg/trunk/highlevel/executive_trex/executive_trex_pr2/include/ROSControllerAdapter.hh
===================================================================
--- pkg/trunk/highlevel/executive_trex/executive_trex_pr2/include/ROSControllerAdapter.hh 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/executive_trex/executive_trex_pr2/include/ROSControllerAdapter.hh 2009-03-04 14:43:36 UTC (rev 12107)
@@ -4,25 +4,16 @@
#include "ROSAdapter.hh"
#include "Token.hh"
#include "TokenVariable.hh"
-#include "BoolDomain.hh"
+#include "SymbolDomain.hh"
namespace TREX {
- /**
- * @brief The last reported state of the controller
- */
- enum ControllerState {
- UNDEFINED = 0,
- INACTIVE,
- ACTIVE
- };
-
template <class S, class G> class ROSControllerAdapter: public ROSAdapter {
public:
ROSControllerAdapter(const LabelStr& agentName, const TiXmlElement& configData)
: ROSAdapter(agentName, configData, 1), inactivePredicate(timelineType + ".Inactive"), activePredicate(timelineType + ".Active"),
- state(UNDEFINED), lastPublished(-1), lastUpdated(0), goalTopic(extractData(configData, "goalTopic").toString()) {}
+ is_active(false), lastPublished(-1), lastUpdated(0), goalTopic(extractData(configData, "goalTopic").toString()) {}
virtual ~ROSControllerAdapter(){}
@@ -39,28 +30,31 @@
// If we have already changed the state in this tick, we do not want to over-ride that. This will ensure we do not miss a state change
// where the goal to move is accompished almost instantly, for example if the robot is already at the goal.
- if(lastUpdated == getCurrentTick() && state != UNDEFINED)
+ if(lastUpdated == getCurrentTick())
return;
- if(stateMsg.status == stateMsg.ACTIVE && state != ACTIVE){
- state = ACTIVE;
- lastUpdated = getCurrentTick();
- ROS_DEBUG("Received transition to ACTIVE");
+ if( (stateMsg.status.value == stateMsg.status.ACTIVE) && !is_active){
+ ROS_DEBUG("[%s][%d]Received transition to ACTIVE %d",
+ nameString().c_str(), getCurrentTick(), stateMsg.status.value);
}
- else if(stateMsg.status != stateMsg.ACTIVE && state != INACTIVE){
- state = INACTIVE;
- lastUpdated = getCurrentTick();
- ROS_DEBUG("Received transition to INACTIVE");
+ else if((stateMsg.status.value != stateMsg.status.ACTIVE) && is_active){
+ ROS_DEBUG("[%s][%d]Received transition to INACTIVE", nameString().c_str(), getCurrentTick());
}
+
+ lastUpdated = getCurrentTick();
}
void registerSubscribers() {
- debugMsg("ROS:", "Registering subscriber for " << timelineName << " on topic:" << stateTopic);
+ ROS_INFO("[%s][%d]Registering subscriber for %s on topic: %s",
+ nameString().c_str(), getCurrentTick(), timelineName.c_str(), stateTopic.c_str());
+
m_node->registerSubscriber(stateTopic, stateMsg, &TREX::ROSControllerAdapter<S, G>::handleCallback, this, QUEUE_MAX());
}
void registerPublishers(){
- debugMsg("ROS:", "Registering publisher for " << timelineName << " on topic:" << goalTopic);
+ ROS_INFO("[%s][%d]Registering publisher for %s on topic: %s",
+ nameString().c_str(), getCurrentTick(), timelineName.c_str(), goalTopic.c_str());
+
m_node->registerPublisher<G>(goalTopic, QUEUE_MAX());
}
@@ -69,26 +63,27 @@
if(((int) lastUpdated) == lastPublished)
return NULL;
- // We shuold never be getting an observation when in an undefined state. If we are, it means we failed to
- // initialize, which will likely be a message subscription error or an absence of an expected publisher
- // to initialize state.
- if(state == UNDEFINED){
- ROS_DEBUG("ROSControllerAdapter <%s> failed to get an observation with no initial state set yet", timelineName.c_str());
- throw "ROSControllerAdapter: Tried to get an observation on with no initial state set yet.";
- }
-
ObservationByValue* obs = NULL;
stateMsg.lock();
- if(state == INACTIVE){
+
+ ROS_DEBUG("[%s][%d]Checking for new observations. Currently we are %s. Latest observation is %s (%d)",
+ nameString().c_str(),
+ getCurrentTick(),
+ (is_active ? "ACTIVE" : "INACTIVE"),
+ (stateMsg.status.value == stateMsg.status.ACTIVE ? "ACTIVE" : "INACTIVE"),
+ stateMsg.status.value);
+
+ if(stateMsg.status.value != stateMsg.status.ACTIVE && (is_active || (getCurrentTick() == 0))){
obs = new ObservationByValue(timelineName, inactivePredicate);
fillInactiveObservationParameters(obs);
- obs->push_back("aborted", new BoolDomain(stateMsg.status == stateMsg.ABORTED));
- obs->push_back("preempted", new BoolDomain(stateMsg.status == stateMsg.PREEMPTED));
+ obs->push_back("status", getResultStatus(stateMsg).copy());
+ is_active = false;
}
- else {
+ else if(stateMsg.status.value == stateMsg.status.ACTIVE && !is_active){
obs = new ObservationByValue(timelineName, activePredicate);
fillActiveObservationParameters(obs);
+ is_active = true;
}
stateMsg.unlock();
@@ -96,12 +91,26 @@
return obs;
}
+ const SymbolDomain& getResultStatus(const S& stateMsg){
+ static std::vector<EUROPA::SymbolDomain> RESULT_STATES;
+ if(RESULT_STATES.empty()){
+ RESULT_STATES.push_back(SymbolDomain(LabelStr("UNDEFINED"), "ResultStatus"));
+ RESULT_STATES.push_back(SymbolDomain(LabelStr("SUCCESS"), "ResultStatus"));
+ RESULT_STATES.push_back(SymbolDomain(LabelStr("ABORTED"), "ResultStatus"));
+ RESULT_STATES.push_back(SymbolDomain(LabelStr("PREEMPTED"), "ResultStatus"));
+ RESULT_STATES.push_back(SymbolDomain(LabelStr("ACTIVE"), "ResultStatus"));
+ }
+
+ return RESULT_STATES[stateMsg.status.value];
+ }
+
/**
* The goal can be enabled or disabled.
* The predicate can be active or inactive
*/
bool dispatchRequest(const TokenId& goal, bool enabled){
- ROS_DEBUG("Received dispatch request for %s",goal->toString().c_str());
+ ROS_DEBUG("[%s][%d]Received dispatch request for %s",
+ nameString().c_str(), getCurrentTick(), goal->toString().c_str());
bool enableController = enabled;
@@ -124,7 +133,10 @@
goalMsg.timeout = dom.getSingletonValue();
}
}
- ROS_DEBUG("[%d}Dispatching %s", getCurrentTick(), goal->toString().c_str());
+
+ ROS_DEBUG("[%s][%d]%s goal %s",
+ nameString().c_str(), getCurrentTick(), (enableController ? "Dispatching" : "Recalling"), goal->toString().c_str());
+
m_node->publishMsg<G>(goalTopic, goalMsg);
// Ensure pre-emption is controllable. We do not want to rely on the asynchronous
@@ -132,7 +144,7 @@
// synchronizing
if(!enableController){
stateMsg.lock();
- stateMsg.status = stateMsg.PREEMPTED;
+ stateMsg.status.value = stateMsg.status.PREEMPTED;
handleCallback();
stateMsg.unlock();
}
@@ -149,7 +161,7 @@
private:
const LabelStr inactivePredicate;
const LabelStr activePredicate;
- ControllerState state;
+ bool is_active;
int lastPublished;
TICK lastUpdated;
const std::string goalTopic;
Modified: pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/ROSAdapter.cc
===================================================================
--- pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/ROSAdapter.cc 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/ROSAdapter.cc 2009-03-04 14:43:36 UTC (rev 12107)
@@ -40,13 +40,13 @@
registerSubscribers();
- // Wait till we get a message before starting the agent
+ // Wait till we are initialized before moving ahead
while(!isInitialized() && ros::Node::instance()->ok()){
- std::cout << "Waiting to connect for " << timelineName << ". If this is taking too long then the expected message is not being published." << std::endl;
+ ROS_INFO("Waiting to connect for %s. If this is taking too long then the expected message is not being published.", timelineName.c_str());
sleep(1);
}
- std::cout << "Connection established for " << timelineName << std::endl;
+ ROS_INFO("Connection established for %s", timelineName.c_str());
}
ROSAdapter::~ROSAdapter() {
Modified: pkg/trunk/highlevel/highlevel_controllers/include/highlevel_controllers/highlevel_controller.hh
===================================================================
--- pkg/trunk/highlevel/highlevel_controllers/include/highlevel_controllers/highlevel_controller.hh 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/highlevel_controllers/include/highlevel_controllers/highlevel_controller.hh 2009-03-04 14:43:36 UTC (rev 12107)
@@ -48,14 +48,10 @@
* @brief Abstract base class for a high level controller node which is parameterized by the state update
* and goal messages exchanged with a client. The controller utilizes a pattern where the controller is tasked with
* goals, and can transition between an active state (when pursuing a goal), and an inactive state when is its effectively
- * idle and should not be imposing any control. A high level control must also handle goal recalls.
+ * idle and should not be imposing any control. A high level control must also handle goal recalls, which is termed 'preemption'
*/
template <class S, class G> class HighlevelController {
public:
- enum State {
- INACTIVE = 0,
- ACTIVE
- };
/**
* @brief Used to set queue max parameter for subscribe and advertise of ROS topics
@@ -71,7 +67,7 @@
HighlevelController(const std::string& nodeName, const std::string& _stateTopic, const std::string& _goalTopic):
initialized(false), terminated(false), stateTopic(_stateTopic),
goalTopic(_goalTopic), controllerCycleTime_(0.1), plannerCycleTime_(0.0), plannerThread_(NULL),
- timeout(0, 0), done_(false), valid_(false) {
+ timeout(0, 0), valid_(false) {
// Obtain the control frequency for this node
double controller_frequency(10);
@@ -99,6 +95,8 @@
ros::Node::instance()->subscribe("highlevel_controllers/shutdown", shutdownMsg_, &HighlevelController<S, G>::shutdownCallback, this, 1);
// Initially inactive
+ this->stateMsg.status.value = this->stateMsg.status.UNDEFINED;
+
deactivate();
// Start planner loop on a separate thread
@@ -110,21 +108,7 @@
delete plannerThread_;
}
- /**
- * @brief Test if the node has received required inputs allowing it to commence business as usual.
- * @see initialize()
- */
- bool isInitialized() const {
- return initialized;
- }
- void terminate() {
- terminated = true;
- }
-
- bool isTerminated() const {
- return terminated;
- }
/**
* @brief The main run loop of the controller
*/
@@ -144,53 +128,25 @@
}
/**
- * @brief Runs the planning loop. If the node is not initialized or if inactive, then it will do nothing. Otherwise
- * it will call the planner with the given timeout.
+ * @brief Test if the HLC has received required inputs allowing it to commence business as usual.
+ * @see initialize()
*/
- void plannerLoop(){
- ros::Time lastPlan = ros::Time::now();
+ bool isInitialized() const {
+ return initialized;
+ }
- while(ros::Node::instance()->ok() && !isTerminated()){
- ros::Time curr = ros::Time::now();
+ /**
+ * @brief Call this to permanently decommision the controller
+ */
+ void terminate() {
+ terminated = true;
+ }
- // Check for bogus time value and update to correct. This can happen for example where the node starts up
- // and uses system time but then switches to listen to a time message based on simulated time. Just makes the code robust
- // to such startup errors. If we do find some other timing anomaly it will correct by recomputing the last planning time.
- // This has the effect of resetting the timeout monotor but that should only introduce a minor delay
- if(curr < lastPlan)
- lastPlan = curr;
-
- if(isInitialized() && isActive()){
-
- // If the plannerCycleTime is 0 then we only call the planner when we need to
- if(plannerCycleTime_ != 0 || !isValid()){
- setValid(makePlan());
- if(!isValid()){
- // Could use a refined locking scheme but for now do not want to delegate that to a derived class
- lock();
-
- ros::Duration elapsed_time = ros::Time::now() - lastPlan;
- ROS_DEBUG("Last current value at %f seconds:", curr.toSec());
- ROS_DEBUG("Last plan at %f seconds:", lastPlan.toSec());
- ROS_DEBUG("Elapsed time is %f seconds:", elapsed_time.toSec());
- if ((elapsed_time > timeout) && timeout.toSec() != 0.0) {
- this->stateMsg.status = this->stateMsg.ABORTED;
- ROS_INFO("Controller timed out.");
- deactivate();
- }
- handlePlanningFailure();
- unlock();
- } else {
- lastPlan = ros::Time::now();
- }
- }
- }
-
- if(plannerCycleTime_ >= 0)
- sleep(curr, std::max(plannerCycleTime_, controllerCycleTime_));
- else
- sleep(curr, curr.toSec() + 0.001);
- }
+ /**
+ * @brief Test if the HLC has been terminated (decommissioned permanently)
+ */
+ bool isTerminated() const {
+ return terminated;
}
protected:
@@ -199,7 +155,7 @@
* @brief Accessor for state of the controller
*/
bool isActive() {
- return this->state == ACTIVE;
+ return this->stateMsg.status.value == this->stateMsg.status.ACTIVE;
}
/**
@@ -212,46 +168,27 @@
* @brief Access aborted state of the planner.
*/
bool isAborted() {
- return this->stateMsg.status == this->stateMsg.ABORTED;
+ return this->stateMsg.status.value == this->stateMsg.status.ABORTED;
}
/**
* @brief Access preempted state of the planner.
*/
bool isPreempted() {
- return this->stateMsg.status == this->stateMsg.PREEMPTED;
+ return this->stateMsg.status.value == this->stateMsg.status.PREEMPTED;
}
/**
- * @brief Activation of the controller will set the state, the stateMsg but indicate that the
- * goal has not yet been accomplished and that no plan has been constructed yet.
+ * @brief Abort the controller. This is the only state transition that can be explicitly initiated
+ * by a derived class. Otherwise the state transitions are governed by implementations of methods
+ * for planning and dispatching commands, and checking of a goal has been reached.
*/
- void activate(){
- ROS_INFO("Activating controller with timeout of %f seconds\n", this->goalMsg.timeout);
-
- this->state = ACTIVE;
- this->stateMsg.status = this->stateMsg.ACTIVE;
- done_ = 0;
-
- handleActivation();
+ void abort(){
+ ROS_INFO("Aborting controller\n");
+ this->stateMsg.status.value = this->stateMsg.status.ABORTED;
}
/**
- * @brief Deactivation of the controller will set the state to inactive, and clear the valid flag.
- */
- void deactivate(){
- ROS_INFO("Deactivating controller\n");
-
- this->state = INACTIVE;
- if (this->stateMsg.status == this->stateMsg.ACTIVE) {
- this->stateMsg.status = this->stateMsg.INACTIVE;
- }
- valid_ = 0;
-
- handleDeactivation();
- }
-
- /**
* @brief Marks the node as initialized. Shoud be called by subclass when expected inbound messages
* are received to make sure it only publishes meaningful states
*/
@@ -259,7 +196,6 @@
initialized = true;
}
-
/**
* @brief Subclass will implement this method to update goal data based on new values in goalMsg. Derived class should
* be sure to lock and unlock when accessing member variables
@@ -345,18 +281,56 @@
G goalMsg; /*!< Message populated by callback */
S stateMsg; /*!< Message published. Will be populated in the control loop */
- /**
- * @brief Setter for state msg done flag
- */
- void setDone(bool isDone){
- done_ = isDone;
- }
+private:
+
/**
- * @brief Get the done flag
+ * @brief Runs the planning loop. If the node is not initialized or if inactive, then it will do nothing. Otherwise
+ * it will call the planner with the given timeout.
*/
- bool getDone() {
- return done_;
+ void plannerLoop(){
+ ros::Time lastPlan = ros::Time::now();
+
+ while(ros::Node::instance()->ok() && !isTerminated()){
+ ros::Time curr = ros::Time::now();
+
+ // Check for bogus time value and update to correct. This can happen for example where the node starts up
+ // and uses system time but then switches to listen to a time message based on simulated time. Just makes the code robust
+ // to such startup errors. If we do find some other timing anomaly it will correct by recomputing the last planning time.
+ // This has the effect of resetting the timeout monotor but that should only introduce a minor delay
+ if(curr < lastPlan)
+ lastPlan = curr;
+
+ if(isInitialized() && isActive()){
+
+ // If the plannerCycleTime is 0 then we only call the planner when we need to
+ if(plannerCycleTime_ != 0 || !isValid()){
+ setValid(makePlan());
+ if(!isValid()){
+ // Could use a refined locking scheme but for now do not want to delegate that to a derived class
+ lock();
+
+ ros::Duration elapsed_time = ros::Time::now() - lastPlan;
+ ROS_DEBUG("Last current value at %f seconds:", curr.toSec());
+ ROS_DEBUG("Last plan at %f seconds:", lastPlan.toSec());
+ ROS_DEBUG("Elapsed time is %f seconds:", elapsed_time.toSec());
+
+ if ((elapsed_time > timeout) && timeout.toSec() != 0.0)
+ abort();
+
+ handlePlanningFailure();
+ unlock();
+ } else {
+ lastPlan = ros::Time::now();
+ }
+ }
+ }
+
+ if(plannerCycleTime_ >= 0)
+ sleep(curr, std::max(plannerCycleTime_, controllerCycleTime_));
+ else
+ sleep(curr, curr.toSec() + 0.001);
+ }
}
/**
@@ -366,9 +340,33 @@
valid_ = isValid;
}
+ /**
+ * @brief Activation of the controller will set the state, the stateMsg but indicate that the
+ * goal has not yet been accomplished and that no plan has been constructed yet.
+ */
+ void activate(){
+ ROS_INFO("Activating controller with timeout of %f seconds\n", this->goalMsg.timeout);
-private:
+ valid_ = 0;
+ this->stateMsg.status.value = this->stateMsg.status.ACTIVE;
+ handleActivation();
+ }
+
+ void preempt(){
+ ROS_INFO("Controller preempted.");
+ this->stateMsg.status.value = this->stateMsg.status.PREEMPTED;
+ deactivate();
+ }
+
+ /**
+ * @brief Deactivation of the controller will set the state to inactive, and clear the valid flag.
+ */
+ void deactivate(){
+ ROS_INFO("Deactivating controller");
+ handleDeactivation();
+ }
+
void goalCallback(){
if (goalMsg.timeout < 0) {
ROS_ERROR("Controller was given negative timeout, setting to zero.");
@@ -383,17 +381,16 @@
lock();
- if(state == INACTIVE && goalMsg.enable){
+ if(!isActive() && goalMsg.enable){
activate();
}
- else if(state == ACTIVE){
- ROS_INFO("Controller preempted.");
- this->stateMsg.status = this->stateMsg.PREEMPTED;
- deactivate();
+ else if(isActive()){
+ preempt();
// If we are active, and this is a goal, publish the state message and activate. This allows us
// to over-ride a new goal, but still forces the transition between active and inactive states
if(goalMsg.enable){
+ ROS_DEBUG("Publishing state %d", stateMsg.status.value);
ros::Node::instance()->publish(stateTopic, stateMsg);
activate();
}
@@ -402,7 +399,6 @@
// Call to allow derived class to update goal member variables
updateGoalMsg();
-
unlock();
}
@@ -454,14 +450,15 @@
// when the planner invalidates the plan, which can happen since planning is interleaved.
if(isActive()){
if(isValid() && goalReached()){
- setDone(true);
- deactivate();
- }
- else {
- // Dispatch plans to accomplish goal, according to the plan. If there is a failure in
- // dispatching, it should return false, which will force re-planning
- setValid(dispatchCommands());
- }
+ ROS_INFO("Success! Goal achieved :)\n");
+ this->stateMsg.status.value = this->stateMsg.status.SUCCESS;
+ deactivate();
+ }
+ else {
+ // Dispatch plans to accomplish goal, according to the plan. If there is a failure in
+ // dispatching, it should return false, which will force re-planning
+ setValid(dispatchCommands());
+ }
}
unlock();
@@ -472,14 +469,12 @@
bool terminated; /*!< Marks if the node has been terminated. */
const std::string stateTopic; /*!< The topic on which state updates are published */
const std::string goalTopic; /*!< The topic on which it subscribes for goal requests and recalls */
- State state; /*!< Tracks the overall state of the controller */
double controllerCycleTime_; /*!< The duration for each control cycle */
double plannerCycleTime_; /*!< The duration for each planner cycle. */
boost::recursive_mutex lock_; /*!< Lock for access to class members in callbacks */
boost::thread* plannerThread_; /*!< Thread running the planner loop */
highlevel_controllers::Ping shutdownMsg_; /*!< For receiving shutdown from executive */
ros::Duration timeout; /*< The time limit for planning failure. */
- bool done_; /*< True if the action is done */
bool valid_; /*< True if it is valid */
};
Modified: pkg/trunk/highlevel/highlevel_controllers/msg/RechargeState.msg
===================================================================
--- pkg/trunk/highlevel/highlevel_controllers/msg/RechargeState.msg 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/highlevel_controllers/msg/RechargeState.msg 2009-03-04 14:43:36 UTC (rev 12107)
@@ -1,20 +1,6 @@
Header header
+robot_msgs/ControllerStatus status
-#Status options
-byte INACTIVE=0
-byte ACTIVE=1
-byte ABORTED=2
-byte PREEMPTED=3
-
-# Status of the controller = {INACTIVE, ACTIVE, ABORTED, PREEMPTED}
-byte status
-
-#Id of the goal
-int32 goal_id
-
-#Comment for debug
-string comment
-
# Actual recharge level
float32 recharge_level
Modified: pkg/trunk/highlevel/highlevel_controllers/src/move_arm.cpp
===================================================================
--- pkg/trunk/highlevel/highlevel_controllers/src/move_arm.cpp 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/highlevel_controllers/src/move_arm.cpp 2009-03-04 14:43:36 UTC (rev 12107)
@@ -133,9 +133,7 @@
int plan_id_;
int traj_id_;
- bool new_goal_;
bool new_trajectory_;
- bool plan_valid_;
robot_msgs::KinematicPath current_trajectory_;
double angle_tolerance_;
@@ -175,8 +173,7 @@
controller_topic_(side + "_arm_trajectory_command"),
controller_name_(side + "_arm_trajectory_controller"),
robot_model_(NULL), plan_id_(-1), traj_id_(-1),
- new_goal_(false), new_trajectory_(false),
- plan_valid_(false)
+ new_trajectory_(false)
{
// Adjust logging level
log4cxx::LoggerPtr my_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
@@ -255,7 +252,6 @@
lock();
stateMsg.goal = goalMsg.goal_configuration;
ROS_DEBUG("Received new goal");
- new_goal_ = true;
unlock();
}
@@ -333,13 +329,15 @@
bool MoveArm::makePlan()
{
- if(!new_goal_)
+ // Only want to re-plan if we have not successfully obtained a plan already. Note that this is actually covered in
+ // how the node is configured since it is defined by the timiong of the plan update loop. This node conflates global planning and incremental
+ // replanning.
+ if(isValid())
return true;
- new_goal_ = false;
-
ROS_DEBUG("Starting to plan...");
+ // CMG: Does this really need to be locked throughout? Just wondering.
goalMsg.lock();
robot_srvs::KinematicReplanState::Request req;
@@ -429,28 +427,33 @@
//req.params.volume* are left empty, because we're not planning for the base.
- bool ret = ros::service::call("replan_kinematic_path_state", req, res);
- if (!ret)
- {
- ROS_ERROR("Service call on plan_kinematic_path_state failed");
- plan_id_ = -1;
- }
- else
- {
+ if(ros::service::call("replan_kinematic_path_state", req, res)){
plan_id_ = res.id;
ROS_DEBUG("Requested plan, got id %d\n", plan_id_);
plan_status_.lock();
plan_status_.unlock();
}
+ else {
+ ROS_ERROR("Service call on plan_kinematic_path_state failed");
+ plan_id_ = -1;
+ }
goalMsg.unlock();
- return true;
+ return plan_id_ != -1;
}
bool MoveArm::goalReached()
{
- return getDone();
+ plan_status_.lock();
+ // Should never get to call this method if the plan is invalid. See HighlevelController::doOneCycle() for details
+ ROS_ASSERT(plan_status_.id != -1);
+ bool result = plan_status_.done || (!new_trajectory_ && traj_id_ >= 0 && isTrajectoryDone());
+ ROS_DEBUG("Execution is complete");
+ plan_id_ = -1;
+ traj_id_ = -1;
+ plan_status_.unlock();
+ return result;
}
bool MoveArm::isTrajectoryDone()
@@ -508,36 +511,27 @@
return done;
}
+/**
+ * @note This method will not be called if we are done.
+ */
bool MoveArm::dispatchCommands()
{
- // Force replanning if we have a new goal
- if(new_goal_)
- return false;
+ bool ok(true);
plan_status_.lock();
// HACK: sometimes we get the status for the new plan before we receive
// the response to the service call that gives us the new plan id. It
// happens that the planner increments the id by 1 with each request.
+ // CMG: Since this cannot be called unless we completed the service call - do we need this?
if(((plan_status_.id != plan_id_) &&
(plan_status_.id != plan_id_ + 1)) ||
(traj_id_ < 0 && !new_trajectory_))
{
// NOOP
+ // CMG: Is this a NOOP? We are basically continuing our prior command - no?
ROS_DEBUG("Idle");
}
- else if(plan_status_.done || (traj_id_ >= 0 && !new_trajectory_))
- {
- if(isTrajectoryDone())
- {
- ROS_DEBUG("Plan completed.");
- plan_id_ = -1;
- traj_id_ = -1;
- ROS_DEBUG("Execution is complete");
- stateMsg.status = pr2_msgs::MoveArmState::INACTIVE;
- plan_valid_ = true;
- }
- }
else if(plan_status_.valid &&
!plan_status_.unsafe &&
(plan_status_.distance < 0.1) &&
@@ -545,18 +539,18 @@
{
ROS_DEBUG("sending new trajectory");
sendArmCommand(current_trajectory_, kinematic_model_);
- plan_valid_ = true;
new_trajectory_ = false;
}
else
{
ROS_DEBUG("Plan invalid or unsafe");
stopArm();
- plan_valid_ = false;
+ ok = false;
}
+
plan_status_.unlock();
- return plan_valid_;
+ return ok;
}
void MoveArm::printKinematicPath(robot_msgs::KinematicPath &path)
Modified: pkg/trunk/highlevel/highlevel_controllers/src/recharge_controller.cpp
===================================================================
--- pkg/trunk/highlevel/highlevel_controllers/src/recharge_controller.cpp 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/highlevel/highlevel_controllers/src/recharge_controller.cpp 2009-03-04 14:43:36 UTC (rev 12107)
@@ -164,9 +164,9 @@
// Set to initalized (benign if already true)
initialize();
- // If the power consumption is positive, then energy is flowing into the battery, so it must be plugged in.
- if(connected() && !isActive())
- activate();
+ // If not activated, do nothing
+ if(!isActive())
+ return;
// If connected, we can reset notification to plug in. We also clear it to be releasable, meaning
if(connected()){
Modified: pkg/trunk/mapping/door_handle_detector/test/open_door_executive_test.cpp
===================================================================
--- pkg/trunk/mapping/door_handle_detector/test/open_door_executive_test.cpp 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/mapping/door_handle_detector/test/open_door_executive_test.cpp 2009-03-04 14:43:36 UTC (rev 12107)
@@ -455,10 +455,10 @@
void plannerCallback()
{
- if (planner_state_.status == planner_state_.ACTIVE)
+ if (planner_state_.status.value == planner_state_.status.ACTIVE)
planner_running_ = true;
- if (planner_running_ && planner_state_.status == planner_state_.INACTIVE){
+ if (planner_running_ && planner_state_.status.value != planner_state_.status.ACTIVE){
planner_running_ = false;
planner_finished_ = true;
}
Modified: pkg/trunk/nav/wavefront_player/cli.cpp
===================================================================
--- pkg/trunk/nav/wavefront_player/cli.cpp 2009-03-04 12:37:20 UTC (rev 12106)
+++ pkg/trunk/nav/wavefront_player/cli.cpp 2009-03-04 14:43:36 UTC (rev 12107)
@@ -24,9 +24,9 @@
}
void state_cb()
{
- if (state == WF_IDLE && wf_state.status == wf_state.ACTIVE)
+ if (state == WF_IDLE && wf_state.status.value == wf_state.status.ACTIVE)
state = WF_SEEKING_GOAL;
- else if (state == WF_SEEKING_GOAL && wf_state.status != wf_state.ACTIVE)
+ else if (state == WF_SEEKING_GOAL && wf_state.status.value != wf_state.status.ACTIVE)
state = WF_DONE;
}
void d...
[truncated message content] |
|
From: <mc...@us...> - 2009-03-04 14:46:23
|
Revision: 12108
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12108&view=rev
Author: mcgann
Date: 2009-03-04 14:46:15 +0000 (Wed, 04 Mar 2009)
Log Message:
-----------
Renamed clock to avoid collission with EUROPA.
Modified Paths:
--------------
pkg/trunk/3rdparty/trex/Makefile
pkg/trunk/3rdparty/trex/manifest.xml
pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.cc
pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.hh
Modified: pkg/trunk/3rdparty/trex/Makefile
===================================================================
--- pkg/trunk/3rdparty/trex/Makefile 2009-03-04 14:43:36 UTC (rev 12107)
+++ pkg/trunk/3rdparty/trex/Makefile 2009-03-04 14:46:15 UTC (rev 12108)
@@ -19,9 +19,6 @@
installed: Makefile
make trex planworks plasma
./copyIncludes.sh
- # Super-hack to get around one header name collision
- cp TREX/agent/base/Clock.hh include
- touch installed
includes: trex PlanWorks PLASMA
./copyIncludes.sh
@@ -49,9 +46,9 @@
# Get TREX
trex: plasma
- @if [ ! -d TREX ]; then $(SVN_CMDLINE) co -r 76 http://trex-autonomy.googlecode.com/svn/trunk TREX; fi ;
- -if test "-r 76" != "-r `svn info TREX | grep Revision | cut -d " " -f 2,2`"; then \
- cd TREX && $(SVN_CMDLINE) up -r 76 ; \
+ @if [ ! -d TREX ]; then $(SVN_CMDLINE) co -r 79 http://trex-autonomy.googlecode.com/svn/trunk TREX; fi ;
+ -if test "-r 79" != "-r `svn info TREX | grep Revision | cut -d " " -f 2,2`"; then \
+ cd TREX && $(SVN_CMDLINE) up -r 79 ; \
fi
@if [ ! -d logs ]; then mkdir logs; fi
@if [ -z `which jam` ]; then echo "You don't appear to have jam installed.\nPlease install it (e.g., sudo apt-get install jam)"; else ./make_trex; fi
Modified: pkg/trunk/3rdparty/trex/manifest.xml
===================================================================
--- pkg/trunk/3rdparty/trex/manifest.xml 2009-03-04 14:43:36 UTC (rev 12107)
+++ pkg/trunk/3rdparty/trex/manifest.xml 2009-03-04 14:46:15 UTC (rev 12108)
@@ -1,7 +1,7 @@
<package>
<description brief="TREX">
-This package contains TREX (from the Monterey Bay Aquarium Research Institute),
+This package contains TREX (initially developed at the Monterey Bay Aquarium Research Institute),
and EUROPA from the NASA Ames Research Center. This package does not modify these
3rd party libraries in any way; it simply provides a convenient way to download and build the
headers and libraries in a way that can be managed by the ROS dependency
Modified: pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.cc
===================================================================
--- pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.cc 2009-03-04 14:43:36 UTC (rev 12107)
+++ pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.cc 2009-03-04 14:46:15 UTC (rev 12108)
@@ -1,4 +1,3 @@
-#include "Clock.hh"
#include "LogClock.hh"
#include "Agent.hh"
#include "LogManager.hh"
Modified: pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.hh
===================================================================
--- pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.hh 2009-03-04 14:43:36 UTC (rev 12107)
+++ pkg/trunk/highlevel/executive_trex/executive_trex_pr2/src/LogClock.hh 2009-03-04 14:46:15 UTC (rev 12108)
@@ -1,7 +1,7 @@
#ifndef H_LogClock
#define H_LogClock
-#include "Clock.hh"
+#include "AgentClock.hh"
#include "XMLUtils.hh"
#include <pthread.h>
#include <fstream>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-05 00:00:54
|
Revision: 12140
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12140&view=rev
Author: tfoote
Date: 2009-03-05 00:00:43 +0000 (Thu, 05 Mar 2009)
Log Message:
-----------
switching loki to be a sysdep. #1026
Modified Paths:
--------------
pkg/trunk/drivers/motor/ethercat_hardware/CMakeLists.txt
pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml
pkg/trunk/mechanism/mechanism_model/CMakeLists.txt
pkg/trunk/mechanism/mechanism_model/manifest.xml
pkg/trunk/prcore/filters/CMakeLists.txt
pkg/trunk/prcore/filters/manifest.xml
Removed Paths:
-------------
pkg/trunk/3rdparty/loki/
Modified: pkg/trunk/drivers/motor/ethercat_hardware/CMakeLists.txt
===================================================================
--- pkg/trunk/drivers/motor/ethercat_hardware/CMakeLists.txt 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/drivers/motor/ethercat_hardware/CMakeLists.txt 2009-03-05 00:00:43 UTC (rev 12140)
@@ -9,3 +9,4 @@
add_definitions(-Wall)
rospack_add_library(ethercat_hardware src/ethercat_hardware.cpp src/wg0x.cpp src/ek1122.cpp src/wg014.cpp)
rospack_add_executable(motorconf src/motorconf.cpp src/ethercat_hardware.cpp src/wg0x.cpp src/ek1122.cpp src/wg014.cpp)
+target_link_libraries(motorconf loki)
Modified: pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml
===================================================================
--- pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml 2009-03-05 00:00:43 UTC (rev 12140)
@@ -10,11 +10,11 @@
<depend package='eml'/>
<depend package='tinyxml'/>
<depend package='roscpp' />
-<depend package='loki' />
<depend package='realtime_tools' />
<depend package='robot_msgs' />
<export>
- <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lethercat_hardware -Wl,-rpath,${prefix}/lib"/>
+ <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lethercat_hardware -Wl,-rpath,${prefix}/lib -lloki"/>
</export>
<repository>http://pr.willowgarage.com/repos</repository>
+<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
Modified: pkg/trunk/mechanism/mechanism_model/CMakeLists.txt
===================================================================
--- pkg/trunk/mechanism/mechanism_model/CMakeLists.txt 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/mechanism/mechanism_model/CMakeLists.txt 2009-03-05 00:00:43 UTC (rev 12140)
@@ -11,10 +11,10 @@
src/wrist_transmission.cpp)
rospack_add_gtest(test/test_FK test/test_FK.cpp)
-target_link_libraries(test/test_FK mechanism_model)
+target_link_libraries(test/test_FK mechanism_model loki)
rospack_add_gtest(test/test_chain test/test_chain.cpp)
-target_link_libraries(test/test_chain mechanism_model)
+target_link_libraries(test/test_chain mechanism_model loki)
rospack_add_gtest_future(test/test_tree test/test_tree.cpp)
-target_link_libraries(test/test_tree mechanism_model)
+target_link_libraries(test/test_tree mechanism_model loki)
Modified: pkg/trunk/mechanism/mechanism_model/manifest.xml
===================================================================
--- pkg/trunk/mechanism/mechanism_model/manifest.xml 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/mechanism/mechanism_model/manifest.xml 2009-03-05 00:00:43 UTC (rev 12140)
@@ -6,7 +6,6 @@
<review status="unreviewed" notes="API review in progress (Eric)"/>
<depend package="roscpp" />
<depend package="hardware_interface" />
-<depend package="loki" />
<depend package="tinyxml" />
<depend package="wg_robot_description_parser" />
<depend package="tf" />
@@ -15,6 +14,7 @@
<depend package="bullet" />
<url>http://pr.willowgarage.com</url>
<export>
- <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lmechanism_model -Wl,-rpath,${prefix}/lib"/>
+ <cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lmechanism_model -Wl,-rpath,${prefix}/lib -lloki"/>
</export>
+<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
Modified: pkg/trunk/prcore/filters/CMakeLists.txt
===================================================================
--- pkg/trunk/prcore/filters/CMakeLists.txt 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/prcore/filters/CMakeLists.txt 2009-03-05 00:00:43 UTC (rev 12140)
@@ -4,14 +4,23 @@
rospack_add_boost_directories()
+
rospack_add_gtest(median_test test/test_median.cpp)
+target_link_libraries(median_test loki)
# broken, needs to go to the new form factor
rospack_add_gtest(transfer_function_test test/test_transfer_function.cpp)
+rospack_add_link_flags(transfer_function_test "-lloki")
rospack_add_gtest(mean_test test/test_mean.cpp)
+target_link_libraries(mean_test loki)
rospack_add_gtest(factory_test test/test_factory.cpp)
+target_link_libraries(factory_test loki)
+
rospack_add_gtest(chain_test test/test_chain.cpp)
+target_link_libraries(chain_test loki)
+
rospack_add_gtest(realtime_buffer_test test/test_realtime_circular_buffer.cpp)
+target_link_libraries(realtime_buffer_test loki)
\ No newline at end of file
Modified: pkg/trunk/prcore/filters/manifest.xml
===================================================================
--- pkg/trunk/prcore/filters/manifest.xml 2009-03-04 23:50:32 UTC (rev 12139)
+++ pkg/trunk/prcore/filters/manifest.xml 2009-03-05 00:00:43 UTC (rev 12140)
@@ -10,9 +10,9 @@
<review status="API conditionally cleared" notes=""/>
<url>http://pr.willowgarage.com</url>
<depend package="tinyxml"/>
-<depend package="loki" />
<depend package="rosconsole" />
<export>
-<cpp cflags="-I${prefix}/include `rosboost-cfg --cflags`"/> <!-- lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -lfilter"/-->
+<cpp cflags="-I${prefix}/include `rosboost-cfg --cflags`" lflags="-lloki"/> <!--lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -lfilter"/-->
</export>
+<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-06 01:08:54
|
Revision: 12220
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12220&view=rev
Author: tfoote
Date: 2009-03-06 01:08:50 +0000 (Fri, 06 Mar 2009)
Log Message:
-----------
readding loki, this time as a tar ball and not extracting or building tests or doc
Modified Paths:
--------------
pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml
pkg/trunk/mechanism/mechanism_model/manifest.xml
pkg/trunk/prcore/filters/manifest.xml
Added Paths:
-----------
pkg/trunk/3rdparty/loki/
pkg/trunk/3rdparty/loki/Makefile
pkg/trunk/3rdparty/loki/Makefile.common
pkg/trunk/3rdparty/loki/manifest.xml
Added: pkg/trunk/3rdparty/loki/Makefile
===================================================================
--- pkg/trunk/3rdparty/loki/Makefile (rev 0)
+++ pkg/trunk/3rdparty/loki/Makefile 2009-03-06 01:08:50 UTC (rev 12220)
@@ -0,0 +1,30 @@
+all: installed
+
+TARBALL = build/loki-0.1.7.tar.bz2
+TARBALL_URL = http://downloads.sourceforge.net/loki-lib/loki-0.1.7.tar.bz2
+UNPACK_CMD = tar xj --exclude=doc --exclude=test -f
+SOURCE_DIR = build/loki-0.1.7
+
+include $(shell rospack find mk)/download_unpack_build.mk
+
+
+installed: wiped $(SOURCE_DIR)/unpacked
+ cp Makefile.common $(SOURCE_DIR)
+ cd $(SOURCE_DIR)/src && make install
+ touch installed
+
+wiped: Makefile
+ make wipe
+ touch wiped
+
+clean:
+ -rm -rf $(SOURCE_DIR) lib
+ rm -f *~ installed
+
+.PHONY : clean wipe
+
+wipe: clean
+ rm -f $(TARBALL)
+ rm -rf lib build
+
+
Added: pkg/trunk/3rdparty/loki/Makefile.common
===================================================================
--- pkg/trunk/3rdparty/loki/Makefile.common (rev 0)
+++ pkg/trunk/3rdparty/loki/Makefile.common 2009-03-06 01:08:50 UTC (rev 12220)
@@ -0,0 +1,7 @@
+VERSION := 0.1.7
+OS ?= $(shell uname -s)
+
+CXXWARNFLAGS := -Wall -Wold-style-cast -Wundef -Wsign-compare -Wconversion -Wpointer-arith -pedantic
+CXXFLAGS := $(CXXWARNFLAGS) -g -O2
+
+prefix := $(shell rospack find loki)/build
Added: pkg/trunk/3rdparty/loki/manifest.xml
===================================================================
--- pkg/trunk/3rdparty/loki/manifest.xml (rev 0)
+++ pkg/trunk/3rdparty/loki/manifest.xml 2009-03-06 01:08:50 UTC (rev 12220)
@@ -0,0 +1,18 @@
+<package>
+<description brief="loki">
+
+Loki is a C++ library of designs, containing flexible implementations of common design patterns and idioms.
+
+</description>
+<author>Andrei Alexandrescu</author>
+<license>MIT</license>
+<review status="3rdparty" notes=""/>
+<url>http://loki-lib.sourceforge.net/</url>
+<export>
+ <cpp lflags="-Wl,-rpath,${prefix}/loki-svn/lib -L${prefix}/build/lib -lloki" cflags="-I${prefix}/build/loki-0.1.7/include"/>
+ <doxymaker external="http://loki-lib.sourceforge.net/html/modules.html"/>
+ <status api="10-9-2008" code="10-9-2008" cleared="11-10-2008"/>
+</export>
+</package>
+
+
Modified: pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml
===================================================================
--- pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml 2009-03-06 00:56:03 UTC (rev 12219)
+++ pkg/trunk/drivers/motor/ethercat_hardware/manifest.xml 2009-03-06 01:08:50 UTC (rev 12220)
@@ -9,6 +9,7 @@
<depend package='hardware_interface'/>
<depend package='eml'/>
<depend package='tinyxml'/>
+<depend package='loki'/>
<depend package='roscpp' />
<depend package='realtime_tools' />
<depend package='robot_msgs' />
@@ -16,5 +17,4 @@
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lethercat_hardware -Wl,-rpath,${prefix}/lib -lloki"/>
</export>
<repository>http://pr.willowgarage.com/repos</repository>
-<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
Modified: pkg/trunk/mechanism/mechanism_model/manifest.xml
===================================================================
--- pkg/trunk/mechanism/mechanism_model/manifest.xml 2009-03-06 00:56:03 UTC (rev 12219)
+++ pkg/trunk/mechanism/mechanism_model/manifest.xml 2009-03-06 01:08:50 UTC (rev 12220)
@@ -12,9 +12,9 @@
<depend package="std_srvs" />
<depend package="control_toolbox" />
<depend package="bullet" />
+<depend package="loki" />
<url>http://pr.willowgarage.com</url>
<export>
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lmechanism_model -Wl,-rpath,${prefix}/lib -lloki"/>
</export>
-<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
Modified: pkg/trunk/prcore/filters/manifest.xml
===================================================================
--- pkg/trunk/prcore/filters/manifest.xml 2009-03-06 00:56:03 UTC (rev 12219)
+++ pkg/trunk/prcore/filters/manifest.xml 2009-03-06 01:08:50 UTC (rev 12220)
@@ -11,8 +11,8 @@
<url>http://pr.willowgarage.com</url>
<depend package="tinyxml"/>
<depend package="rosconsole" />
+<depend package="loki" />
<export>
<cpp cflags="-I${prefix}/include `rosboost-cfg --cflags`" lflags="-lloki"/> <!--lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -lfilter"/-->
</export>
-<sysdepend os="ubuntu" version="8.04-hardy" package="libloki-dev"/>
</package>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-06 01:55:09
|
Revision: 12224
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12224&view=rev
Author: tfoote
Date: 2009-03-06 01:40:58 +0000 (Fri, 06 Mar 2009)
Log Message:
-----------
moving loki to prcore for it is necessary for filters package in prcore
Added Paths:
-----------
pkg/trunk/prcore/loki/
Removed Paths:
-------------
pkg/trunk/3rdparty/loki/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-06 02:16:36
|
Revision: 12226
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12226&view=rev
Author: tfoote
Date: 2009-03-06 02:16:26 +0000 (Fri, 06 Mar 2009)
Log Message:
-----------
absorbing laser_processor into laser_scan
Modified Paths:
--------------
pkg/trunk/util/laser_scan/CMakeLists.txt
pkg/trunk/util/laser_scan/manifest.xml
pkg/trunk/vision/people/manifest.xml
pkg/trunk/vision/people/src/calc_leg_features.cpp
pkg/trunk/vision/people/src/calc_leg_features.h
pkg/trunk/vision/people/src/leg_detector.cpp
pkg/trunk/vision/people/src/train_leg_detector.cpp
Added Paths:
-----------
pkg/trunk/util/laser_scan/include/laser_scan/laser_processor.h
pkg/trunk/util/laser_scan/src/laser_processor.cpp
Removed Paths:
-------------
pkg/trunk/vision/laser_processor/
Modified: pkg/trunk/util/laser_scan/CMakeLists.txt
===================================================================
--- pkg/trunk/util/laser_scan/CMakeLists.txt 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/util/laser_scan/CMakeLists.txt 2009-03-06 02:16:26 UTC (rev 12226)
@@ -6,6 +6,9 @@
rospack_add_boost_directories()
+#todo integrate this
+rospack_add_library(laser_processor src/laser_processor.cpp)
+
rospack_add_library(laser_scan src/laser_scan.cc )
rospack_link_boost(laser_scan thread)
Copied: pkg/trunk/util/laser_scan/include/laser_scan/laser_processor.h (from rev 10961, pkg/trunk/vision/laser_processor/laser_processor.h)
===================================================================
--- pkg/trunk/util/laser_scan/include/laser_scan/laser_processor.h (rev 0)
+++ pkg/trunk/util/laser_scan/include/laser_scan/laser_processor.h 2009-03-06 02:16:26 UTC (rev 12226)
@@ -0,0 +1,145 @@
+/*********************************************************************
+* 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.
+*********************************************************************/
+
+/*! \mainpage
+ * \htmlinclude manifest.html
+ */
+
+//! A namespace containing the laser processor helper classes
+
+
+#ifndef LASER_SCAN_LASERPROCESSOR_HH
+#define LASER_SCAN_LASERPROCESSOR_HH
+
+#include <unistd.h>
+#include <math.h>
+#include "ros/node.h"
+#include "laser_scan/LaserScan.h"
+#include "robot_msgs/PointCloud.h"
+#include "robot_msgs/Point.h"
+
+#include <list>
+#include <set>
+#include <vector>
+#include <map>
+#include <utility>
+#include <algorithm>
+
+#include "tf/transform_datatypes.h"
+
+namespace laser_scan
+{
+ //! A struct representing a single sample from the laser.
+ class Sample
+ {
+ public:
+ int index;
+ float range;
+ float intensity;
+ float x;
+ float y;
+
+ static Sample* Extract(int ind, laser_scan::LaserScan& scan);
+
+ private:
+ Sample() {};
+ };
+
+ //! The comparator allowing the creation of an ordered "SampleSet"
+ struct CompareSample
+ {
+ inline bool operator() (const Sample* a, const Sample* b)
+ {
+ return (a->index < b->index);
+ }
+ };
+
+
+ //! An ordered set of Samples
+ class SampleSet : public std::set<Sample*, CompareSample>
+ {
+ public:
+
+ ~SampleSet() { clear(); }
+
+ void clear();
+
+ void appendToCloud(robot_msgs::PointCloud& cloud, int r = 0, int g = 0, int b = 0);
+
+ tf::Point center();
+ };
+
+ //! A mask for filtering out Samples based on range
+ class ScanMask
+ {
+ SampleSet mask_;
+
+ bool filled;
+ float angle_min;
+ float angle_max;
+ uint32_t size;
+
+ public:
+
+ ScanMask() : filled(false), angle_min(0), angle_max(0), size(0) { }
+
+ inline void clear() { mask_.clear(); filled = false; }
+
+ void addScan(laser_scan::LaserScan& scan);
+
+ bool hasSample(Sample* s, float thresh);
+ };
+
+
+
+ class ScanProcessor
+ {
+ std::list<SampleSet*> clusters_;
+ laser_scan::LaserScan scan_;
+
+ public:
+
+ std::list<SampleSet*>& getClusters() { return clusters_; }
+
+ ScanProcessor(laser_scan::LaserScan& scan, ScanMask& mask_, float mask_threshold = 0.03);
+
+ ~ScanProcessor();
+
+ void removeLessThan(uint32_t num);
+
+ void splitConnected(float thresh);
+ };
+};
+
+#endif
Modified: pkg/trunk/util/laser_scan/manifest.xml
===================================================================
--- pkg/trunk/util/laser_scan/manifest.xml 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/util/laser_scan/manifest.xml 2009-03-06 02:16:26 UTC (rev 12226)
@@ -13,6 +13,6 @@
<depend package="tf"/>
<depend package="filters"/>
<export>
-<cpp cflags="-I${prefix}/include -I${prefix}/msg/cpp" lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -llaser_scan"/>
+<cpp cflags="-I${prefix}/include -I${prefix}/msg/cpp" lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib -llaser_scan -llaser_processor"/>
</export>
</package>
Copied: pkg/trunk/util/laser_scan/src/laser_processor.cpp (from rev 10961, pkg/trunk/vision/laser_processor/laser_processor.cpp)
===================================================================
--- pkg/trunk/util/laser_scan/src/laser_processor.cpp (rev 0)
+++ pkg/trunk/util/laser_scan/src/laser_processor.cpp 2009-03-06 02:16:26 UTC (rev 12226)
@@ -0,0 +1,288 @@
+/*********************************************************************
+* 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.
+*********************************************************************/
+
+#include "laser_scan/laser_processor.h"
+
+#include <stdexcept>
+
+using namespace ros;
+using namespace std;
+using namespace laser_scan;
+
+Sample* Sample::Extract(int ind, laser_scan::LaserScan& scan)
+{
+ Sample* s = new Sample;
+
+ s->index = ind;
+ s->range = scan.ranges[ind];
+ s->intensity = scan.intensities[ind];
+ s->x = cos( scan.angle_min + ind*scan.angle_increment ) * s->range;
+ s->y = sin( scan.angle_min + ind*scan.angle_increment ) * s->range;
+ if (s->range > scan.range_min && s->range < scan.range_max)
+ return s;
+ else
+ {
+ delete s;
+ return NULL;
+ }
+}
+
+void SampleSet::clear()
+{
+ for (SampleSet::iterator i = begin();
+ i != end();
+ i++)
+ {
+ delete (*i);
+ }
+ set<Sample*, CompareSample>::clear();
+}
+
+void SampleSet::appendToCloud(robot_msgs::PointCloud& cloud, int r, int g, int b)
+{
+ float color_val = 0;
+
+ int rgb = (r << 16) | (g << 8) | b;
+ color_val = *(float*)&(rgb);
+
+ for (iterator sample_iter = begin();
+ sample_iter != end();
+ sample_iter++)
+ {
+ robot_msgs::Point32 point;
+ point.x = (*sample_iter)->x;
+ point.y = (*sample_iter)->y;
+ point.z = 0;
+
+ cloud.pts.push_back(point);
+
+ if (cloud.chan[0].name == "rgb")
+ cloud.chan[0].vals.push_back(color_val);
+
+ if (cloud.chan[0].name == "intensity")
+ cloud.chan[0].vals.push_back((*sample_iter)->intensity);
+ }
+}
+
+tf::Point SampleSet::center()
+{
+ float x_mean = 0.0;
+ float y_mean = 0.0;
+ for (iterator i = begin();
+ i != end();
+ i++)
+
+ {
+ x_mean += ((*i)->x)/size();
+ y_mean += ((*i)->y)/size();
+ }
+
+ return tf::Point (x_mean, y_mean, 0.0);
+}
+
+
+void ScanMask::addScan(laser_scan::LaserScan& scan)
+{
+ if (!filled)
+ {
+ angle_min = scan.angle_min;
+ angle_max = scan.angle_max;
+ size = scan.ranges.size();
+ filled = true;
+ } else if (angle_min != scan.angle_min ||
+ angle_max != scan.angle_max ||
+ size != scan.ranges.size())
+ {
+ throw std::runtime_error("laser_scan::ScanMask::addScan: inconsistantly sized scans added to mask");
+ }
+
+ for (uint32_t i = 0; i < scan.ranges.size(); i++)
+ {
+ Sample* s = Sample::Extract(i, scan);
+
+ if (s != NULL)
+ {
+ SampleSet::iterator m = mask_.find(s);
+
+ if (m != mask_.end())
+ {
+ if ((*m)->range > s->range)
+ {
+ delete (*m);
+ mask_.erase(m);
+ mask_.insert(s);
+ } else {
+ delete s;
+ }
+ }
+ else
+ {
+ mask_.insert(s);
+ }
+ }
+ }
+}
+
+
+bool ScanMask::hasSample(Sample* s, float thresh)
+{
+ if (s != NULL)
+ {
+ SampleSet::iterator m = mask_.find(s);
+ if ( m != mask_.end())
+ if (((*m)->range - thresh) < s->range)
+ return true;
+ }
+ return false;
+}
+
+
+
+ScanProcessor::ScanProcessor(laser_scan::LaserScan& scan, ScanMask& mask_, float mask_threshold)
+{
+ scan_ = scan;
+
+ SampleSet* cluster = new SampleSet;
+
+ for (uint32_t i = 0; i < scan.ranges.size(); i++)
+ {
+ Sample* s = Sample::Extract(i, scan);
+
+ if (s != NULL)
+ {
+ if (!mask_.hasSample(s, mask_threshold))
+ {
+ cluster->insert(s);
+ } else {
+ delete s;
+ }
+ }
+ }
+
+ clusters_.push_back(cluster);
+
+}
+
+ScanProcessor::~ScanProcessor()
+{
+ for ( list<SampleSet*>::iterator c = clusters_.begin();
+ c != clusters_.end();
+ c++)
+ delete (*c);
+}
+
+void
+ScanProcessor::removeLessThan(uint32_t num)
+{
+ list<SampleSet*>::iterator c_iter = clusters_.begin();
+ while (c_iter != clusters_.end())
+ {
+ if ( (*c_iter)->size() < num )
+ {
+ delete (*c_iter);
+ clusters_.erase(c_iter++);
+ } else {
+ ++c_iter;
+ }
+ }
+}
+
+
+void
+ScanProcessor::splitConnected(float thresh)
+{
+ list<SampleSet*> tmp_clusters;
+
+ list<SampleSet*>::iterator c_iter = clusters_.begin();
+
+ // For each cluster
+ while (c_iter != clusters_.end())
+ {
+ // Go through the entire list
+ while ((*c_iter)->size() > 0 )
+ {
+ // Take the first element
+ SampleSet::iterator s_first = (*c_iter)->begin();
+
+ // Start a new queue
+ list<Sample*> sample_queue;
+ sample_queue.push_back(*s_first);
+
+ (*c_iter)->erase(s_first);
+
+ // Grow until we get to the end of the queue
+ list<Sample*>::iterator s_q = sample_queue.begin();
+ while (s_q != sample_queue.end())
+ {
+ int expand = (int)(asin( thresh / (*s_q)->range ) / scan_.angle_increment);
+
+ SampleSet::iterator s_rest = (*c_iter)->begin();
+
+ while ( (s_rest != (*c_iter)->end() &&
+ (*s_rest)->index < (*s_q)->index + expand ) )
+ {
+ if ( (*s_rest)->range - (*s_q)->range > thresh)
+ {
+ break;
+ }
+ else if (sqrt( pow( (*s_q)->x - (*s_rest)->x, 2.0f) + pow( (*s_q)->y - (*s_rest)->y, 2.0f)) < thresh)
+ {
+ sample_queue.push_back(*s_rest);
+ (*c_iter)->erase(s_rest++);
+ break;
+ } else {
+ ++s_rest;
+ }
+ }
+ s_q++;
+ }
+
+ // Move all the samples into the new cluster
+ SampleSet* c = new SampleSet;
+ for (s_q = sample_queue.begin(); s_q != sample_queue.end(); s_q++)
+ c->insert(*s_q);
+
+ // Store the temporary clusters
+ tmp_clusters.push_back(c);
+ }
+
+ //Now that c_iter is empty, we can delete
+ delete (*c_iter);
+
+ //And remove from the map
+ clusters_.erase(c_iter++);
+ }
+
+ clusters_.insert(clusters_.begin(), tmp_clusters.begin(), tmp_clusters.end());
+}
Modified: pkg/trunk/vision/people/manifest.xml
===================================================================
--- pkg/trunk/vision/people/manifest.xml 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/vision/people/manifest.xml 2009-03-06 02:16:26 UTC (rev 12226)
@@ -19,7 +19,7 @@
<depend package="rospy"/>
<depend package="image_msgs"/>
<depend package="topic_synchronizer"/>
-<depend package="laser_processor"/>
+<depend package="laser_scan"/>
<depend package="tf"/>
<depend package="color_calib"/>
<depend package="bfl"/>
Modified: pkg/trunk/vision/people/src/calc_leg_features.cpp
===================================================================
--- pkg/trunk/vision/people/src/calc_leg_features.cpp 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/vision/people/src/calc_leg_features.cpp 2009-03-06 02:16:26 UTC (rev 12226)
@@ -37,7 +37,7 @@
#include "opencv/cxcore.h"
#include "opencv/cv.h"
-using namespace laser_processor;
+using namespace laser_scan;
using namespace std;
vector<float> calcLegFeatures(SampleSet* cluster, laser_scan::LaserScan& scan)
Modified: pkg/trunk/vision/people/src/calc_leg_features.h
===================================================================
--- pkg/trunk/vision/people/src/calc_leg_features.h 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/vision/people/src/calc_leg_features.h 2009-03-06 02:16:26 UTC (rev 12226)
@@ -35,11 +35,11 @@
#ifndef CALCLEGFEATURES_HH
#define CALCLEGFEATURES_HH
-#include "laser_processor.h"
+#include "laser_scan/laser_processor.h"
#include "laser_scan/LaserScan.h"
// TODO: Should remove scan dependency from here.
// Only used for jump distance
-std::vector<float> calcLegFeatures(laser_processor::SampleSet* cluster, laser_scan::LaserScan& scan);
+std::vector<float> calcLegFeatures(laser_scan::SampleSet* cluster, laser_scan::LaserScan& scan);
#endif
Modified: pkg/trunk/vision/people/src/leg_detector.cpp
===================================================================
--- pkg/trunk/vision/people/src/leg_detector.cpp 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/vision/people/src/leg_detector.cpp 2009-03-06 02:16:26 UTC (rev 12226)
@@ -37,7 +37,7 @@
-#include "laser_processor.h"
+#include "laser_scan/laser_processor.h"
#include "calc_leg_features.h"
#include "opencv/cxcore.h"
@@ -60,7 +60,7 @@
#include <algorithm>
using namespace std;
-using namespace laser_processor;
+using namespace laser_scan;
using namespace ros;
using namespace tf;
using namespace estimation;
Modified: pkg/trunk/vision/people/src/train_leg_detector.cpp
===================================================================
--- pkg/trunk/vision/people/src/train_leg_detector.cpp 2009-03-06 01:52:19 UTC (rev 12225)
+++ pkg/trunk/vision/people/src/train_leg_detector.cpp 2009-03-06 02:16:26 UTC (rev 12226)
@@ -32,7 +32,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
-#include "laser_processor.h"
+#include "laser_scan/laser_processor.h"
#include "calc_leg_features.h"
#include "opencv/cxcore.h"
@@ -45,7 +45,7 @@
#include "laser_scan/LaserScan.h"
using namespace std;
-using namespace laser_processor;
+using namespace laser_scan;
using namespace ros;
enum LoadType {LOADING_NONE, LOADING_POS, LOADING_NEG, LOADING_TEST};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <tf...@us...> - 2009-03-06 02:38:15
|
Revision: 12227
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12227&view=rev
Author: tfoote
Date: 2009-03-06 02:38:06 +0000 (Fri, 06 Mar 2009)
Log Message:
-----------
moving tinyxml into prcore in anticipation of the release
Added Paths:
-----------
pkg/trunk/prcore/tinyxml/
Removed Paths:
-------------
pkg/trunk/3rdparty/tinyxml/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <stu...@us...> - 2009-03-07 01:13:58
|
Revision: 12267
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12267&view=rev
Author: stuglaser
Date: 2009-03-07 01:13:47 +0000 (Sat, 07 Mar 2009)
Log Message:
-----------
During calibration, the joints move over the optical flag in one direction only.
Modified Paths:
--------------
pkg/trunk/controllers/robot_mechanism_controllers/CMakeLists.txt
pkg/trunk/mechanism/mechanism_bringup/scripts/calibrate_arm.py
pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/arm_defs.xml
pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/head_defs.xml
Added Paths:
-----------
pkg/trunk/controllers/robot_mechanism_controllers/include/robot_mechanism_controllers/joint_ud_calibration_controller.h
pkg/trunk/controllers/robot_mechanism_controllers/src/joint_ud_calibration_controller.cpp
Modified: pkg/trunk/controllers/robot_mechanism_controllers/CMakeLists.txt
===================================================================
--- pkg/trunk/controllers/robot_mechanism_controllers/CMakeLists.txt 2009-03-07 01:03:07 UTC (rev 12266)
+++ pkg/trunk/controllers/robot_mechanism_controllers/CMakeLists.txt 2009-03-07 01:13:47 UTC (rev 12267)
@@ -3,7 +3,7 @@
rospack(robot_mechanism_controllers)
genmsg()
gensrv()
-set(_srcs
+set(_srcs
src/plug_controller.cpp
src/cartesian_tff_controller.cpp
src/cartesian_trajectory_controller.cpp
@@ -23,6 +23,7 @@
src/joint_autotuner.cpp
src/joint_pd_controller.cpp
src/joint_calibration_controller.cpp
+ src/joint_ud_calibration_controller.cpp
src/joint_limit_calibration_controller.cpp
src/joint_blind_calibration_controller.cpp
src/lqr_controller.cpp
Added: pkg/trunk/controllers/robot_mechanism_controllers/include/robot_mechanism_controllers/joint_ud_calibration_controller.h
===================================================================
--- pkg/trunk/controllers/robot_mechanism_controllers/include/robot_mechanism_controllers/joint_ud_calibration_controller.h (rev 0)
+++ pkg/trunk/controllers/robot_mechanism_controllers/include/robot_mechanism_controllers/joint_ud_calibration_controller.h 2009-03-07 01:13:47 UTC (rev 12267)
@@ -0,0 +1,100 @@
+/*********************************************************************
+ * 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.
+ *********************************************************************/
+
+#pragma once
+
+#include "mechanism_model/robot.h"
+#include "robot_mechanism_controllers/joint_velocity_controller.h"
+#include "realtime_tools/realtime_publisher.h"
+#include "std_msgs/Empty.h"
+
+
+namespace controller
+{
+
+class JointUDCalibrationController : public controller::Controller
+{
+public:
+ JointUDCalibrationController();
+ virtual ~JointUDCalibrationController();
+
+ virtual bool initXml(mechanism::RobotState *robot, TiXmlElement *config);
+
+ virtual void update();
+
+ bool calibrated() { return state_ == CALIBRATED; }
+ void beginCalibration()
+ {
+ if (state_ == INITIALIZED)
+ state_ = BEGINNING;
+ }
+
+protected:
+
+ enum { INITIALIZED, BEGINNING, MOVING_TO_LOW, MOVING_TO_HIGH, CALIBRATED };
+ int state_;
+ int countdown_;
+
+ double search_velocity_;
+ bool original_switch_state_;
+
+ Actuator *actuator_;
+ mechanism::JointState *joint_;
+ mechanism::Transmission *transmission_;
+
+ controller::JointVelocityController vc_;
+};
+
+
+class JointUDCalibrationControllerNode : public Controller
+{
+public:
+ JointUDCalibrationControllerNode();
+ ~JointUDCalibrationControllerNode();
+
+ void update();
+
+ bool initXml(mechanism::RobotState *robot, TiXmlElement *config);
+
+private:
+ mechanism::RobotState* robot_;
+ JointUDCalibrationController c_;
+
+ double last_publish_time_;
+ realtime_tools::RealtimePublisher<std_msgs::Empty> *pub_calibrated_;
+};
+
+}
+
+
Added: pkg/trunk/controllers/robot_mechanism_controllers/src/joint_ud_calibration_controller.cpp
===================================================================
--- pkg/trunk/controllers/robot_mechanism_controllers/src/joint_ud_calibration_controller.cpp (rev 0)
+++ pkg/trunk/controllers/robot_mechanism_controllers/src/joint_ud_calibration_controller.cpp 2009-03-07 01:13:47 UTC (rev 12267)
@@ -0,0 +1,237 @@
+/*********************************************************************
+ * 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.
+ *********************************************************************/
+
+#include <robot_mechanism_controllers/joint_ud_calibration_controller.h>
+#include <ros/time.h>
+
+using namespace std;
+using namespace controller;
+
+//ROS_REGISTER_CONTROLLER(JointUDCalibrationController)
+
+JointUDCalibrationController::JointUDCalibrationController()
+ : state_(INITIALIZED), actuator_(NULL), joint_(NULL), transmission_(NULL)
+{
+}
+
+JointUDCalibrationController::~JointUDCalibrationController()
+{
+}
+
+bool JointUDCalibrationController::initXml(mechanism::RobotState *robot, TiXmlElement *config)
+{
+ assert(robot);
+ assert(config);
+
+ TiXmlElement *cal = config->FirstChildElement("calibrate");
+ if (!cal)
+ {
+ std::cerr<<"JointUDCalibrationController was not given calibration parameters"<<std::endl;
+ return false;
+ }
+
+ if(cal->QueryDoubleAttribute("velocity", &search_velocity_) != TIXML_SUCCESS)
+ {
+ std::cerr<<"Velocity value was not specified\n";
+ return false;
+ }
+
+ const char *joint_name = cal->Attribute("joint");
+ joint_ = joint_name ? robot->getJointState(joint_name) : NULL;
+ if (!joint_)
+ {
+ fprintf(stderr, "Error: JointUDCalibrationController could not find joint \"%s\"\n",
+ joint_name);
+ return false;
+ }
+
+ const char *actuator_name = cal->Attribute("actuator");
+ actuator_ = actuator_name ? robot->model_->getActuator(actuator_name) : NULL;
+ if (!actuator_)
+ {
+ fprintf(stderr, "Error: JointUDCalibrationController could not find actuator \"%s\"\n",
+ actuator_name);
+ return false;
+ }
+
+ const char *transmission_name = cal->Attribute("transmission");
+ transmission_ = transmission_name ? robot->model_->getTransmission(transmission_name) : NULL;
+ if (!transmission_)
+ {
+ fprintf(stderr, "Error: JointUDCalibrationController could not find transmission \"%s\"\n",
+ transmission_name);
+ return false;
+ }
+
+ control_toolbox::Pid pid;
+ TiXmlElement *pid_el = config->FirstChildElement("pid");
+ if (!pid_el)
+ {
+ fprintf(stderr, "Error: JointUDCalibrationController was not given a pid element.\n");
+ return false;
+ }
+ if (!pid.initXml(pid_el))
+ return false;
+
+ if (!vc_.init(robot, joint_name, pid))
+ return false;
+
+ return true;
+}
+
+void JointUDCalibrationController::update()
+{
+ assert(joint_);
+ assert(actuator_);
+
+ switch(state_)
+ {
+ case INITIALIZED:
+ vc_.setCommand(0.0);
+ state_ = BEGINNING;
+ break;
+ case BEGINNING:
+ if (actuator_->state_.calibration_reading_)
+ state_ = MOVING_TO_LOW;
+ else
+ state_ = MOVING_TO_HIGH;
+ break;
+ case MOVING_TO_LOW:
+ vc_.setCommand(-search_velocity_);
+ if (!actuator_->state_.calibration_reading_)
+ {
+ if (--countdown_ <= 0)
+ state_ = MOVING_TO_HIGH;
+ }
+ else
+ countdown_ = 200;
+ break;
+ case MOVING_TO_HIGH: {
+ vc_.setCommand(search_velocity_);
+
+ if (actuator_->state_.calibration_reading_)
+ {
+ Actuator a;
+ mechanism::JointState j;
+ std::vector<Actuator*> fake_a;
+ std::vector<mechanism::JointState*> fake_j;
+ fake_a.push_back(&a);
+ fake_j.push_back(&j);
+
+ fake_a[0]->state_.position_ = actuator_->state_.last_calibration_rising_edge_;
+ transmission_->propagatePosition(fake_a, fake_j);
+
+
+
+ // Where was the joint when the optical switch triggered?
+ fake_a[0]->state_.position_ = actuator_->state_.last_calibration_rising_edge_;
+ transmission_->propagatePosition(fake_a, fake_j);
+
+ // What is the actuator position at the joint's zero?
+ fake_j[0]->position_ = fake_j[0]->position_ - joint_->joint_->reference_position_;
+ transmission_->propagatePositionBackwards(fake_j, fake_a);
+
+ actuator_->state_.zero_offset_ = fake_a[0]->state_.position_;
+ joint_->calibrated_ = true;
+
+ state_ = CALIBRATED;
+ vc_.setCommand(0.0);
+ }
+ break;
+ }
+ case CALIBRATED:
+ break;
+ }
+
+ if (state_ != CALIBRATED)
+ vc_.update();
+}
+
+
+ROS_REGISTER_CONTROLLER(JointUDCalibrationControllerNode)
+
+JointUDCalibrationControllerNode::JointUDCalibrationControllerNode()
+: robot_(NULL), last_publish_time_(0), pub_calibrated_(NULL)
+{
+}
+
+JointUDCalibrationControllerNode::~JointUDCalibrationControllerNode()
+{
+ if (pub_calibrated_)
+ {
+ std::string topic = pub_calibrated_->topic_;
+ delete pub_calibrated_;
+
+ // I think we're all tired of having the "cal" topics cluttering
+ // up rostopic and rosgraphviz.
+ ros::Node::instance()->unadvertise(topic);
+ }
+}
+
+void JointUDCalibrationControllerNode::update()
+{
+ c_.update();
+
+ if (c_.calibrated())
+ {
+ if (last_publish_time_ + 0.5 < robot_->hw_->current_time_)
+ {
+ assert(pub_calibrated_);
+ if (pub_calibrated_->trylock())
+ {
+ last_publish_time_ = robot_->hw_->current_time_;
+ pub_calibrated_->unlockAndPublish();
+ }
+ }
+ }
+}
+
+bool JointUDCalibrationControllerNode::initXml(mechanism::RobotState *robot, TiXmlElement *config)
+{
+ assert(robot);
+ robot_ = robot;
+
+ std::string topic = config->Attribute("name") ? config->Attribute("name") : "";
+ if (topic == "")
+ {
+ fprintf(stderr, "No name given to JointUDCalibrationController\n");
+ return false;
+ }
+ if (!c_.initXml(robot, config))
+ return false;
+
+ pub_calibrated_ = new realtime_tools::RealtimePublisher<std_msgs::Empty>(topic + "/calibrated", 1);
+
+ return true;
+}
Modified: pkg/trunk/mechanism/mechanism_bringup/scripts/calibrate_arm.py
===================================================================
--- pkg/trunk/mechanism/mechanism_bringup/scripts/calibrate_arm.py 2009-03-07 01:03:07 UTC (rev 12266)
+++ pkg/trunk/mechanism/mechanism_bringup/scripts/calibrate_arm.py 2009-03-07 01:13:47 UTC (rev 12267)
@@ -111,7 +111,7 @@
def xml_for_cal(name, velocity, p, i, d, iClamp):
return '''\
<controller name=\"cal_%s" topic="cal_%s"\
-type="JointCalibrationControllerNode">\
+type="JointUDCalibrationControllerNode">\
<calibrate joint="%s_joint"\
actuator="%s_motor"\
transmission="%s_trans"\
Modified: pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/arm_defs.xml
===================================================================
--- pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/arm_defs.xml 2009-03-07 01:03:07 UTC (rev 12266)
+++ pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/arm_defs.xml 2009-03-07 01:13:47 UTC (rev 12267)
@@ -706,7 +706,7 @@
<macro name="upper_arm_calibrator" params="side">
<controller name="${side}_cal_shoulder_pan" topic="${side}_cal_shoulder_pan"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="${side}_shoulder_pan_joint"
actuator="${side}_shoulder_pan_motor"
transmission="${side}_shoulder_pan_trans"
@@ -715,7 +715,7 @@
</controller>
<controller name="cal_shoulder_lift_${side}" topic="cal_shoulder_lift_${side}"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="${side}_shoulder_lift_joint"
actuator="${side}_shoulder_lift_motor"
transmission="${side}_shoulder_lift_trans"
@@ -724,7 +724,7 @@
</controller>
<controller name="cal_${side}_upper_arm_roll" topic="cal_${side}_upper_arm_roll"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="${side}_upper_arm_roll_joint"
actuator="${side}_upper_arm_roll_motor"
transmission="${side}_upper_arm_roll_trans"
@@ -733,7 +733,7 @@
</controller>
<controller name="cal_${side}_elbow_flex" topic="cal_${side}_elbow_flex"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="${side}_elbow_flex_joint"
actuator="${side}_elbow_flex_motor"
transmission="${side}_elbow_flex_trans"
@@ -744,7 +744,7 @@
<macro name="forearm_calibrator" params="side">
- <controller name="cal_${side}_forearm_roll" type="JointCalibrationControllerNode">
+ <controller name="cal_${side}_forearm_roll" type="JointUDCalibrationControllerNode">
<calibrate joint="${side}_forearm_roll_joint"
actuator="${side}_forearm_roll_motor"
transmission="${side}_forearm_roll_trans"
Modified: pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/head_defs.xml
===================================================================
--- pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/head_defs.xml 2009-03-07 01:03:07 UTC (rev 12266)
+++ pkg/trunk/robot_descriptions/pr2/pr2_defs/defs/head_defs.xml 2009-03-07 01:13:47 UTC (rev 12267)
@@ -391,7 +391,7 @@
<macro name="head_calibrator">
<controller name="cal_head_pan" topic="cal_head_pan"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="head_pan_joint"
actuator="head_pan_motor"
transmission="head_pan_trans"
@@ -400,7 +400,7 @@
</controller>
<controller name="cal_head_tilt" topic="cal_head_tilt"
- type="JointCalibrationControllerNode">
+ type="JointUDCalibrationControllerNode">
<calibrate joint="head_tilt_joint"
actuator="head_tilt_motor"
transmission="head_tilt_trans"
@@ -410,7 +410,7 @@
</macro>
<macro name="tilting_laser_calibrator" params="name">
- <controller name="cal_${name}" topic="cal_${name}" type="JointCalibrationControllerNode">
+ <controller name="cal_${name}" topic="cal_${name}" type="JointUDCalibrationControllerNode">
<calibrate joint="${name}_mount_joint"
actuator="${name}_mount_motor"
transmission="${name}_mount_trans"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-03-09 19:51:32
|
Revision: 12301
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12301&view=rev
Author: rob_wheeler
Date: 2009-03-09 19:50:56 +0000 (Mon, 09 Mar 2009)
Log Message:
-----------
Report the ethercat device position in the mechanism state message
Modified Paths:
--------------
pkg/trunk/drivers/motor/ethercat_hardware/src/wg0x.cpp
pkg/trunk/mechanism/hardware_interface/include/hardware_interface/hardware_interface.h
pkg/trunk/mechanism/mechanism_control/scripts/detect.py
pkg/trunk/mechanism/mechanism_control/src/mechanism_control.cpp
pkg/trunk/prcore/robot_msgs/msg/ActuatorState.msg
Modified: pkg/trunk/drivers/motor/ethercat_hardware/src/wg0x.cpp
===================================================================
--- pkg/trunk/drivers/motor/ethercat_hardware/src/wg0x.cpp 2009-03-09 19:40:22 UTC (rev 12300)
+++ pkg/trunk/drivers/motor/ethercat_hardware/src/wg0x.cpp 2009-03-09 19:50:56 UTC (rev 12301)
@@ -361,6 +361,7 @@
prev_status = (WG0XStatus *)prev_buffer;
state.timestamp_ = this_status->timestamp_ / 1e+6;
+ state.device_id_ = sh_->get_ring_position();
state.encoder_count_ = this_status->encoder_count_;
state.position_ = double(this_status->encoder_count_) / actuator_info_.pulses_per_revolution_ * 2 * M_PI - state.zero_offset_;
state.encoder_velocity_ = double(int(this_status->encoder_count_ - prev_status->encoder_count_))
Modified: pkg/trunk/mechanism/hardware_interface/include/hardware_interface/hardware_interface.h
===================================================================
--- pkg/trunk/mechanism/hardware_interface/include/hardware_interface/hardware_interface.h 2009-03-09 19:40:22 UTC (rev 12300)
+++ pkg/trunk/mechanism/hardware_interface/include/hardware_interface/hardware_interface.h 2009-03-09 19:50:56 UTC (rev 12301)
@@ -58,6 +58,7 @@
public:
ActuatorState() :
timestamp_(0),
+ device_id_(0),
encoder_count_(0),
position_(0),
encoder_velocity_(0),
@@ -81,6 +82,8 @@
{}
double timestamp_;
+ int device_id_;
+
int encoder_count_;
double position_;
double encoder_velocity_;
Modified: pkg/trunk/mechanism/mechanism_control/scripts/detect.py
===================================================================
--- pkg/trunk/mechanism/mechanism_control/scripts/detect.py 2009-03-09 19:40:22 UTC (rev 12300)
+++ pkg/trunk/mechanism/mechanism_control/scripts/detect.py 2009-03-09 19:50:56 UTC (rev 12301)
@@ -17,7 +17,7 @@
def callback(data):
#stdscr.clear()
- l = [(x, data.actuator_states[x].encoder_count, data.actuator_states[x].encoder_velocity, data.actuator_states[x].name) for x in xrange(len(data.actuator_states))]
+ l = [(data.actuator_states[x].device_id, data.actuator_states[x].encoder_count, data.actuator_states[x].encoder_velocity, data.actuator_states[x].name) for x in xrange(len(data.actuator_states))]
m = list(l)
m.sort(mycmp)
row = 0
Modified: pkg/trunk/mechanism/mechanism_control/src/mechanism_control.cpp
===================================================================
--- pkg/trunk/mechanism/mechanism_control/src/mechanism_control.cpp 2009-03-09 19:40:22 UTC (rev 12300)
+++ pkg/trunk/mechanism/mechanism_control/src/mechanism_control.cpp 2009-03-09 19:50:56 UTC (rev 12301)
@@ -507,6 +507,7 @@
out->encoder_count = in->encoder_count_;
out->position = in->position_;
out->timestamp = in->timestamp_;
+ out->device_id = in->device_id_;
out->encoder_velocity = in->encoder_velocity_;
out->velocity = in->velocity_;
out->calibration_reading = in->calibration_reading_;
Modified: pkg/trunk/prcore/robot_msgs/msg/ActuatorState.msg
===================================================================
--- pkg/trunk/prcore/robot_msgs/msg/ActuatorState.msg 2009-03-09 19:40:22 UTC (rev 12300)
+++ pkg/trunk/prcore/robot_msgs/msg/ActuatorState.msg 2009-03-09 19:50:56 UTC (rev 12301)
@@ -1,4 +1,5 @@
string name
+int32 device_id
int32 encoder_count
float64 position
float64 timestamp
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wa...@us...> - 2009-03-10 05:38:25
|
Revision: 12332
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12332&view=rev
Author: wattsk
Date: 2009-03-10 04:36:01 +0000 (Tue, 10 Mar 2009)
Log Message:
-----------
Head and hokuyo impact tests updates
Modified Paths:
--------------
pkg/trunk/hardware_test/self_test/src/selftest_example.cpp
pkg/trunk/prcore/robot_msgs/msg/TestData.msg
Added Paths:
-----------
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/cal.xml
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head.xml
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head_defs_without_limits.xml
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/impact_head_test.py
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.launch
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.machine
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/manifest.xml
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/run_test.launch
pkg/trunk/hardware_test/life_test/head_test/head_impact_test/send_description.launch
pkg/trunk/hardware_test/life_test/hokuyo_test/
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head.xml
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head_defs_without_limits.xml
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/impact_hokuyo_test.py
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/init.launch
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/init.machine
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/manifest.xml
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/run_test.launch
pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/send_description.launch
Removed Paths:
-------------
pkg/trunk/controllers/qualification_controllers/dynamic_verification_controllers/.build_version
pkg/trunk/hardware_test/dynamic_verification/.build_version
pkg/trunk/hardware_test/life_test/head_test/impact_test/
Deleted: pkg/trunk/controllers/qualification_controllers/dynamic_verification_controllers/.build_version
===================================================================
--- pkg/trunk/controllers/qualification_controllers/dynamic_verification_controllers/.build_version 2009-03-10 04:33:58 UTC (rev 12331)
+++ pkg/trunk/controllers/qualification_controllers/dynamic_verification_controllers/.build_version 2009-03-10 04:36:01 UTC (rev 12332)
@@ -1 +0,0 @@
-https://personalrobots.svn.sourceforge.net/svnroot/personalrobots/pkg/trunk/controllers/qualification_controllers/dynamic_verification_controllers:12201
Deleted: pkg/trunk/hardware_test/dynamic_verification/.build_version
===================================================================
--- pkg/trunk/hardware_test/dynamic_verification/.build_version 2009-03-10 04:33:58 UTC (rev 12331)
+++ pkg/trunk/hardware_test/dynamic_verification/.build_version 2009-03-10 04:36:01 UTC (rev 12332)
@@ -1 +0,0 @@
-:
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/cal.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/cal.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/cal.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,5 @@
+<controllers>
+ <include filename="$(find head_impact_test)/head_defs_without_limits.xml" />
+ <head_calibrator />
+ <tilting_laser_calibrator name="laser_tilt" />
+</controllers>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<robot name="test_head">
+ <include filename="head_defs_without_limits.xml" />
+
+<pr2_head_pan name="head_pan" parent="world">
+ <origin xyz="0 0 0.3815" rpy="0 0 0" />
+</pr2_head_pan>
+
+<pr2_head_tilt name="head_tilt" parent="head_pan">
+ <origin xyz="0.058 0 0" rpy="0 0 0" />
+</pr2_head_tilt>
+
+<pr2_tilting_laser name="laser_tilt" parent="world">
+ <origin xyz="0 0 0.03" rpy="0 0 0" />
+</pr2_tilting_laser>
+
+</robot>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head_defs_without_limits.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head_defs_without_limits.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/head_defs_without_limits.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,361 @@
+<?xml version="1.0"?>
+
+<robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
+ xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
+ xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface">
+
+ <property name="M_PI" value="3.1415926535897931" />
+
+ <macro name="pr2_tilting_laser" params="name parent *origin">
+
+ <joint name="${name}_mount_joint" type="revolute">
+ <axis xyz="0 1 0" />
+ <anchor xyz="0 0 0" />
+ <!-- Removed max, min limits -->
+ <limit effort="0.5292" velocity="100"
+ k_position="100" k_velocity="0.05"
+ safety_length_min="0.15" safety_length_max="0.15" />
+ <calibration reference_position="-0.35" values="0 0" />
+ <joint_properties damping="1.0" />
+ </joint>
+
+ <link name="${name}_mount_link">
+ <parent name="${parent}" />
+ <insert_block name="origin" />
+ <joint name="${name}_mount_joint" />
+ <inertial>
+ <mass value="0.1" />
+ <com xyz="0 0 0" />
+ <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <map name="gazebo_material" flag="gazebo">
+ <elem key="material">Gazebo/PioneerBody</elem>
+ </map>
+ <geometry name="${name}_mount_visual">
+ <mesh filename="hok_tilt" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_mount_collision" >
+ <box size=".001 .001 .001" />
+ </geometry>
+ </collision>
+ </link>
+
+ <transmission type="SimpleTransmission" name="${name}_mount_trans">
+ <actuator name="${name}_mount_motor" />
+ <joint name="${name}_mount_joint" />
+ <mechanicalReduction>6.0</mechanicalReduction>
+ </transmission>
+
+ <joint name="${name}_joint" type="fixed">
+ <axis xyz="0 1 0" />
+ <anchor xyz="0 0 0" />
+ </joint>
+
+ <sensor name="${name}_link" type="laser">
+ <parent name="${name}_mount_link" />
+ <origin xyz="0 0 0.03" rpy="0 0 0" />
+ <joint name="${name}_joint" />
+ <inertial>
+ <mass value="0.1" />
+ <com xyz="0 0 0" />
+ <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_visual">
+ <mesh scale="0.001 0.001 0.001" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_collision" >
+ <box size=".001 .001 .001" />
+ </geometry>
+ </collision>
+
+ <map name="sensor" flag="gazebo">
+ <verbatim key="sensor_${name}_ray">
+ <sensor:ray name="${name}">
+ <rayCount>640</rayCount>
+ <rangeCount>640</rangeCount>
+ <laserCount>1</laserCount>
+
+ <origin>0.0 0.0 0.0</origin>
+ <displayRays>false</displayRays>
+
+ <minAngle>-80</minAngle>
+ <maxAngle> 80</maxAngle>
+
+ <minRange>0.05</minRange>
+ <maxRange>10.0</maxRange>
+ <updateRate>20.0</updateRate>
+ <controller:ros_laser name="ros_${name}_controller" plugin="libros_laser.so">
+ <gaussianNoise>0.005</gaussianNoise>
+ <alwaysOn>true</alwaysOn>
+ <updateRate>20.0</updateRate>
+ <topicName>tilt_scan</topicName>
+ <frameName>${name}_link</frameName>
+ <interface:laser name="ros_${name}_iface" />
+ </controller:ros_laser>
+ </sensor:ray>
+ </verbatim>
+ </map>
+
+ </sensor>
+
+ </macro>
+
+
+ <property name="stereo_size_x" value="0.005" />
+ <property name="stereo_size_y" value="0.010" />
+ <property name="stereo_size_z" value="0.005" />
+ <property name="stereo_center_box_center_offset_x" value="0.00" />
+ <property name="stereo_center_box_center_offset_z" value="0.05" />
+
+ <macro name="stereo_camera" params="name parent *origin">
+ <joint name="${name}_joint" type="fixed" />
+
+ <sensor name="${name}_link" type="camera">
+ <parent name="${parent}" />
+ <insert_block name="origin" />
+ <joint name="${name}_joint" />
+
+ <inertial>
+ <mass value="0.1" />
+ <com xyz="0 0 0" />
+ <inertia ixx="0.00482611007" ixy="-0.000144683999" ixz="0.000110076136"
+ iyy="0.005218991412" iyz="-0.000314239509" izz="0.008618784925" />
+ </inertial>
+
+ <visual>
+ <origin xyz="${stereo_center_box_center_offset_x} 0 ${stereo_center_box_center_offset_z}" rpy="0 0 0" />
+ <map name="gazebo_material" flag="gazebo">
+ <elem key="material">Gazebo/Blue</elem>
+ </map>
+ <geometry name="${name}_visual">
+ <mesh scale="${stereo_size_x} ${stereo_size_y} ${stereo_size_z}" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="${stereo_center_box_center_offset_x} 0 ${stereo_center_box_center_offset_z}" rpy="0 0 0" />
+ <geometry name="${name}_collision">
+ <box size="${stereo_size_x} ${stereo_size_y} ${stereo_size_z}" />
+ </geometry>
+ </collision>
+
+
+ <map name="sensor" flag="gazebo">
+ <verbatim key="sensor_${name}_camera">
+ <sensor:camera name="${name}_l_sensor">
+ <imageWidth>640</imageWidth>
+ <imageHeight>480</imageHeight>
+ <hfov>60</hfov>
+ <nearClip>0.1</nearClip>
+ <farClip>100</farClip>
+ <updateRate>20.0</updateRate>
+ <controller:ros_camera name="${name}_l_controller" plugin="libros_camera.so">
+ <alwaysOn>true</alwaysOn>
+ <updateRate>20.0</updateRate>
+ <topicName>${name}_l/image</topicName>
+ <frameName>${name}_link</frameName>
+ <interface:camera name="${name}_l_iface" />
+ </controller:ros_camera>
+ </sensor:camera>
+ </verbatim>
+ </map>
+ <map name="sensor" flag="gazebo">
+ <verbatim key="sensor_${name}_ray">
+ <sensor:ray name="${name}_laser">
+ <rayCount>10</rayCount>
+ <rangeCount>10</rangeCount>
+ <laserCount>1</laserCount>
+
+ <origin>0.0 0.0 0.05</origin>
+ <displayRays>false</displayRays>
+
+ <minAngle>-15</minAngle>
+ <maxAngle> 15</maxAngle>
+
+ <minRange>0.05</minRange>
+ <maxRange>100.0</maxRange>
+ <updateRate>10.0</updateRate>
+
+ <verticalRayCount>10</verticalRayCount>
+ <verticalRangeCount>10</verticalRangeCount>
+ <verticalMinAngle>-20</verticalMinAngle>
+ <verticalMaxAngle> 0</verticalMaxAngle>
+
+ <controller:ros_block_laser name="${name}_laser_controller" plugin="libros_block_laser.so">
+ <gaussianNoise>0.005</gaussianNoise>
+ <alwaysOn>true</alwaysOn>
+ <updateRate>10.0</updateRate>
+ <topicName>full_cloud</topicName>
+ <frameName>${name}_link</frameName>
+ <interface:laser name="${name}_laser_iface" />
+ </controller:ros_block_laser>
+ </sensor:ray>
+ </verbatim>
+ </map>
+ </sensor>
+ </macro>
+
+
+ <macro name="pr2_head_pan" params="name parent *origin">
+
+ <joint name="${name}_joint" type="revolute">
+ <axis xyz="0 0 1" />
+ <!-- Removed max, min limits -->
+ <limit effort="2.645"
+ velocity="100" k_velocity="1.5"
+ safety_length_min="0.15" safety_length_max="0.15" k_position="100" />
+ <calibration reference_position="-2.79" values="0 0" />
+ <joint_properties damping="1.0" />
+ </joint>
+
+ <transmission type="SimpleTransmission" name="${name}_trans">
+ <actuator name="${name}_motor" />
+ <joint name="${name}_joint" />
+ <mechanicalReduction>6.0</mechanicalReduction>
+ </transmission>
+
+ <link name="${name}_link">
+ <parent name="${parent}" />
+ <insert_block name="origin" />
+ <joint name="${name}_joint" />
+
+ <inertial>
+ <mass value="1.611118" />
+ <com xyz=" -0.005717 0.010312 -0.029649 " />
+ <inertia ixx="0.00482611007" ixy="-0.000144683999" ixz="0.000110076136"
+ iyy="0.005218991412" iyz="-0.000314239509" izz="0.008618784925" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0.0" rpy="0 0 0 " />
+ <map name="gazebo_material" flag="gazebo">
+ <elem key="material">Gazebo/Blue</elem>
+ </map>
+ <geometry name="${name}_visual">
+ <mesh filename="head_pan" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz=" 0 0 0" rpy="0.0 0.0 0.0 " />
+ <geometry name="${name}_collision">
+ <box size="0.188 0.219 0.137" />
+ </geometry>
+ </collision>
+
+ </link>
+ </macro>
+
+
+ <macro name="pr2_head_tilt" params="name parent *origin">
+
+ <joint name="${name}_joint" type="revolute">
+ <axis xyz="0 1 0" />
+ <!-- Safety limits on max, min removed -->
+ <limit effort="12.21"
+ velocity="100" k_velocity="1.5"
+ safety_length_min="0.1" safety_length_max="0.1" k_position="100" />
+ <calibration reference_position="-0.195" values="0 0" />
+ <joint_properties damping="1.0" />
+ </joint>
+
+ <transmission type="SimpleTransmission" name="${name}_trans">
+ <actuator name="${name}_motor" />
+ <joint name="${name}_joint" />
+ <mechanicalReduction>6.0</mechanicalReduction>
+ </transmission>
+
+ <link name="${name}_link">
+ <parent name="${parent}" />
+ <insert_block name="origin" />
+ <joint name="${name}_joint" />
+
+ <inertial>
+ <mass value="1.749727" />
+ <com xyz="0.041935 0.003569 0.028143" />
+ <inertia ixx="0.010602303435" ixy="-0.000408814235" ixz="0.00198303894" iyy="0.011874383747" iyz="0.000197908779" izz="0.005516790626" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0" rpy="0.0 0.0 0.0 " />
+ <map name="gazebo_material" flag="gazebo">
+ <elem key="material">Gazebo/Green</elem>
+ </map>
+ <geometry name="${name}_visual">
+ <mesh filename="head_tilt" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="0 0 0 " rpy="0 0 0" />
+ <geometry name="${name}_collision">
+ <box size="0.164 0.253 0.181" />
+ </geometry>
+ </collision>
+ </link>
+ </macro>
+
+
+ <macro name="pr2_head" params="name parent *origin">
+ <pr2_head_pan name="${name}_pan" parent="${parent}">
+ <insert_block name="origin" />
+ </pr2_head_pan>
+
+ <pr2_head_tilt name="${name}_tilt" parent="${name}_pan_link">
+ <origin xyz="0.058 0 0" rpy="0 0 0" />
+ </pr2_head_tilt>
+
+ <stereo_camera name="stereo" parent="${name}_tilt_link">
+ <origin xyz="0.0232 0 0.0645" rpy="0 0 0" />
+ </stereo_camera>
+ </macro>
+
+
+
+ <!-- Calibration -->
+
+ <macro name="head_calibrator">
+ <controller name="cal_head_pan" topic="cal_head_pan"
+ type="JointCalibrationControllerNode">
+ <calibrate joint="head_pan_joint"
+ actuator="head_pan_motor"
+ transmission="head_pan_trans"
+ velocity="-1.5" />
+ <pid p="2.0" i="0.0" d="0" iClamp="1.0" />
+ </controller>
+
+ <controller name="cal_head_tilt" topic="cal_head_tilt"
+ type="JointCalibrationControllerNode">
+ <calibrate joint="head_tilt_joint"
+ actuator="head_tilt_motor"
+ transmission="head_tilt_trans"
+ velocity="-0.7" />
+ <pid p="4.0" i="0.0" d="0" iClamp="5.0" />
+ </controller>
+ </macro>
+
+ <macro name="tilting_laser_calibrator" params="name">
+ <controller name="cal_${name}" topic="cal_${name}" type="JointCalibrationControllerNode">
+ <calibrate joint="${name}_mount_joint"
+ actuator="${name}_mount_motor"
+ transmission="${name}_mount_trans"
+ velocity="-1.5" />
+ <pid p=".3" i="0.1" d="0" iClamp="1.0" />
+ </controller>
+ </macro>
+
+</robot>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/impact_head_test.py
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/impact_head_test.py (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/impact_head_test.py 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,108 @@
+#! /usr/bin/python
+# Copyright (c) 2009, 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, Inc. 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.
+
+# This script brings up an effort controller runs a 500x life test on the
+# head tilt joint, pan joint and laser tilt joint.
+#
+# Author: Kevin Watts
+
+##@package head_impact_test
+#
+# @mainpage
+# @htmlinclude manifest.xml
+#
+# @section usage Usage
+# @verbatim $ run_test.launch @endverbatim
+#
+# @par Description
+# @verbatim
+# This program runs a impact life test on the head tilt, pan and laser tilt. 500 cycles, with effort safety removed.
+# @endverbatim
+
+
+
+CONTROLLER_NAMES = ["head_tilt_effort", "head_pan_effort", "laser_tilt_effort"]
+JOINT_NAMES = ["head_tilt_joint", "head_pan_joint", "laser_tilt_mount_joint"]
+
+import sys
+
+import roslib
+roslib.load_manifest('head_impact_test') # Rename to path head_impact_test
+import rospy
+from std_msgs.msg import *
+from mechanism_control import mechanism
+from robot_srvs.srv import SpawnController, KillController
+from time import sleep
+
+## Create XML code for controller on the fly
+def xml_for(controller, joint):
+ return '''\
+<controller name=\"%s\" type=\"JointEffortControllerNode\">\
+<joint name=\"%s\" />\
+</controller>''' % (controller, joint)
+
+def main():
+ rospy.init_node('head_impact_test', anonymous=True)
+ for i in range(0,3):
+ joint = JOINT_NAMES[i]
+ controller = CONTROLLER_NAMES[i]
+ #print xml_for(controller,joint)
+
+ rospy.wait_for_service('spawn_controller')
+ spawn_controller = rospy.ServiceProxy('spawn_controller', SpawnController)
+ kill_controller = rospy.ServiceProxy('kill_controller', KillController)
+
+ resp = spawn_controller(xml_for(controller, joint))
+ if len(resp.ok) < 1 or not ord(resp.ok[0]):
+ print "Failed to spawn effort controller"
+ else:
+ print "Spawned controller %s successfully" % controller
+
+ pub = rospy.Publisher("/%s/set_command" % controller, Float64)
+
+ try:
+ for i in range(0,3):
+ if rospy.is_shutdown():
+ break
+ # Back and forth
+ sleep(1.5)
+ effort = -1000; # Min effort
+ pub.publish(Float64(effort))
+ sleep(1.5)
+ effort = 1000; # Max effort
+ pub.publish(Float64(effort))
+ finally:
+ kill_controller(controller)
+ sleep(5)
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()
+
+
+
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.launch
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.launch (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.launch 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,22 @@
+<launch>
+ <include file="$(find head_impact_test)/init.machine" />
+ <include file="$(find head_impact_test)/send_description.launch" />
+
+ <!-- pr2_etherCAT -->
+ <node machine="xenomai_root" pkg="pr2_etherCAT" type="pr2_etherCAT" args="-i eth0 -x /robotdesc/pr2"/>
+
+ <!-- Calibration -->
+ <!--node pkg="mechanism_bringup" type="calibrate.py"
+ args="$(find head_impact_test)/cal.xml"
+ output="screen" /-->
+
+ <!-- Power board -->
+ <!--node pkg="pr2_power_board" type="power_node" respawn="true"/ -->
+
+ <!-- Runtime Diagnostics Logging -->
+ <node pkg="rosrecord" type="rosrecord"
+ args="-f ~/impact_test.bag /diagnostics" />
+
+<!-- Controllers not brought up here, called in impact_head_test.py -->
+
+</launch>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.machine
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.machine (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/init.machine 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,6 @@
+<launch>
+ <machine name="xenomai_root" user="root" address="localhost"
+ ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" default="never"/>
+ <machine name="xenomai" address="localhost"
+ ros-root="$(env ROS_ROOT)" ros-package-path="$(env ROS_PACKAGE_PATH)" />
+</launch>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/manifest.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/manifest.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/manifest.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,14 @@
+<package>
+
+ <description brief="Code and configuration for performing life testing on head tilt, pan and laser tilt.">
+ </description>
+ <author>Kevin Watts</author>
+ <license>BSD</license>
+ <review status="na" notes=""/>
+
+ <depend package="pr2_etherCAT" />
+ <depend package="pr2_power_board"/>
+ <depend package="rosrecord"/>
+ <depend package="pr2_mechanism_controllers"/>
+
+</package>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/run_test.launch
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/run_test.launch (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/run_test.launch 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,4 @@
+<launch>
+ <include file="$(find head_impact_test)/init.launch" />
+ <node pkg="head_impact_test" type="impact_head_test.py" />
+</launch>
Added: pkg/trunk/hardware_test/life_test/head_test/head_impact_test/send_description.launch
===================================================================
--- pkg/trunk/hardware_test/life_test/head_test/head_impact_test/send_description.launch (rev 0)
+++ pkg/trunk/hardware_test/life_test/head_test/head_impact_test/send_description.launch 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,6 @@
+<launch>
+
+ <param name="robotdesc/pr2"
+ command="$(find xacro)/xacro.py '$(find head_impact_test)/head.xml'" />
+
+</launch>
\ No newline at end of file
Added: pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<robot name="test_head">
+ <include filename="head_defs_without_limits.xml" />
+
+<pr2_head_pan name="head_pan" parent="world">
+ <origin xyz="0 0 0.3815" rpy="0 0 0" />
+</pr2_head_pan>
+
+<pr2_head_tilt name="head_tilt" parent="head_pan">
+ <origin xyz="0.058 0 0" rpy="0 0 0" />
+</pr2_head_tilt>
+
+<pr2_tilting_laser name="laser_tilt" parent="world">
+ <origin xyz="0 0 0.03" rpy="0 0 0" />
+</pr2_tilting_laser>
+
+</robot>
Added: pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head_defs_without_limits.xml
===================================================================
--- pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head_defs_without_limits.xml (rev 0)
+++ pkg/trunk/hardware_test/life_test/hokuyo_test/hokuyo_impact_test/head_defs_without_limits.xml 2009-03-10 04:36:01 UTC (rev 12332)
@@ -0,0 +1,361 @@
+<?xml version="1.0"?>
+
+<robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
+ xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
+ xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface">
+
+ <property name="M_PI" value="3.1415926535897931" />
+
+ <macro name="pr2_tilting_laser" params="name parent *origin">
+
+ <joint name="${name}_mount_joint" type="revolute">
+ <axis xyz="0 1 0" />
+ <anchor xyz="0 0 0" />
+ <!-- Removed max, min limits -->
+ <limit effort="0.5292" velocity="100"
+ k_position="100" k_velocity="0.05"
+ safety_length_min="0.15" safety_length_max="0.15" />
+ <calibration reference_position="-0.35" values="0 0" />
+ <joint_properties damping="1.0" />
+ </joint>
+
+ <link name="${name}_mount_link">
+ <parent name="${parent}" />
+ <insert_block name="origin" />
+ <joint name="${name}_mount_joint" />
+ <inertial>
+ <mass value="0.1" />
+ <com xyz="0 0 0" />
+ <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <map name="gazebo_material" flag="gazebo">
+ <elem key="material">Gazebo/PioneerBody</elem>
+ </map>
+ <geometry name="${name}_mount_visual">
+ <mesh filename="hok_tilt" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_mount_collision" >
+ <box size=".001 .001 .001" />
+ </geometry>
+ </collision>
+ </link>
+
+ <transmission type="SimpleTransmission" name="${name}_mount_trans">
+ <actuator name="${name}_mount_motor" />
+ <joint name="${name}_mount_joint" />
+ <mechanicalReduction>6.0</mechanicalReduction>
+ </transmission>
+
+ <joint name="${name}_joint" type="fixed">
+ <axis xyz="0 1 0" />
+ <anchor xyz="0 0 0" />
+ </joint>
+
+ <sensor name="${name}_link" type="laser">
+ <parent name="${name}_mount_link" />
+ <origin xyz="0 0 0.03" rpy="0 0 0" />
+ <joint name="${name}_joint" />
+ <inertial>
+ <mass value="0.1" />
+ <com xyz="0 0 0" />
+ <inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
+ </inertial>
+
+ <visual>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_visual">
+ <mesh scale="0.001 0.001 0.001" />
+ </geometry>
+ </visual>
+
+ <collision>
+ <origin xyz="0 0 0" rpy="0 0 0" />
+ <geometry name="${name}_collision" >
+ <box size=".001 .001 .001" />
+ </geometry>
+ </collision>
+
+ <map name="sensor" flag="gazebo">
+ <verbatim key="sensor_${name}_ray">
+ <sensor:ray name="${name}">
+ <rayCount>640</rayCount>
+ <rangeCount>640</rangeCount>
+ <laserCount>1</laserCount>
+
+ <origin>0.0 0.0 0.0</origin>
+ <displayRays>false</displayRays>
+
+ ...
[truncated message content] |
|
From: <hsu...@us...> - 2009-03-12 22:40:45
|
Revision: 12474
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=12474&view=rev
Author: hsujohnhsu
Date: 2009-03-12 22:40:41 +0000 (Thu, 12 Mar 2009)
Log Message:
-----------
update slide test to graphical.
Modified Paths:
--------------
pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/CMakeLists.txt
pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.py
pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.xml
pkg/trunk/robot_descriptions/gazebo_robot_description/gazebo_worlds/test/test_slide.world
Modified: pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/CMakeLists.txt
===================================================================
--- pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/CMakeLists.txt 2009-03-12 22:36:17 UTC (rev 12473)
+++ pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/CMakeLists.txt 2009-03-12 22:40:41 UTC (rev 12474)
@@ -2,5 +2,5 @@
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
rospack(test_pr2_collision_gazebo)
-rospack_add_rostest(test_slide.xml)
+rospack_add_rostest_graphical(test_slide.xml)
Modified: pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.py
===================================================================
--- pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.py 2009-03-12 22:36:17 UTC (rev 12473)
+++ pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.py 2009-03-12 22:40:41 UTC (rev 12474)
@@ -45,11 +45,12 @@
import rospy, rostest
from robot_msgs.msg import *
-TEST_DURATION = 50.0
+TEST_DURATION = 90.0
TARGET_X = -5.4 + 25.65 #contains offset specified in P3D for base, alternatively, use the gripper roll ground truths
TARGET_Y = 0.0 + 25.65 #contains offset specified in P3D for base, alternatively, use the gripper roll ground truths
TARGET_Z = 3.8
TARGET_RAD = 4.5
+CUP_HEIGHT = 4.0
class TestSlide(unittest.TestCase):
def __init__(self, *args):
@@ -71,8 +72,8 @@
dz = p3d.pos.position.z - TARGET_Z
d = math.sqrt((dx * dx) + (dy * dy)) #+ (dz * dz))
print "Error: " + str(dx) + " " + str(dy) + " " + str(dz)
- #print "D: " + str(dx) + " " + str(dy) + " " + str(dz) + " " + str(d) + " < " + str(TARGET_RAD * TARGET_RAD)
- if (d < TARGET_RAD):
+ print "D: dx:" + str(dx) + " dy:" + str(dy) + " dz:" + str(dz) + " d:" + str(d) + " : " + str(TARGET_RAD)
+ if (d < TARGET_RAD and abs(dz) < CUP_HEIGHT):
#print "HP: " + str(dx) + " " + str(dy) + " " + str(d) + " at " + str(p3d.pos.position.x) + " " + str(p3d.pos.position.y)
#print "DONE"
self.hits = self.hits + 1
Modified: pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.xml
===================================================================
--- pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.xml 2009-03-12 22:36:17 UTC (rev 12473)
+++ pkg/trunk/drivers/simulator/test_pr2_collision_gazebo/test_slide.xml 2009-03-12 22:40:41 UTC (rev 12474)
@@ -1,7 +1,7 @@
<launch>
<master auto="start" />
- <node pkg="gazebo" type="gazebo" args="-r $(find gazebo_robot_description)/gazebo_worlds/test/test_slide.world" respawn="false" output="screen">
+ <node pkg="gazebo" type="gazebo" args="-n $(find gazebo_robot_description)/gazebo_worlds/test/test_slide.world" respawn="false" output="screen">
<env name="LD_LIBRARY_PATH" value="$(find gazebo_plugin)/lib:$(find gazebo)/gazebo/lib:$(find Cg)/Cg/lib:$(optenv LD_LIBRARY_PATH)" />
<env name="GAZEBO_RESOURCE_PATH" value="$(find gazebo_robot_description)/world" />
<env name="OGRE_RESOURCE_PATH" value="$(find ogre)/ogre/lib/OGRE" />
@@ -18,5 +18,5 @@
<include file="$(find pr2_gazebo)/pr2_default_controllers.launch" />
<!-- test -->
- <test test-name="pr2_test_slide" pkg="test_pr2_collision_gazebo" type="test_slide.py" />
+ <test test-name="pr2_test_slide" pkg="test_pr2_collision_gazebo" type="test_slide.py" time-limit="80" />
</launch>
Modified: pkg/trunk/robot_descriptions/gazebo_robot_description/gazebo_worlds/test/test_slide.world
===================================================================
--- pkg/trunk/robot_descriptions/gazebo_robot_description/gazebo_worlds/test/test_slide.world 2009-03-12 22:36:17 UTC (rev 12473)
+++ pkg/trunk/robot_descriptions/gazebo_robot_description/gazebo_worlds/test/test_slide.world 2009-03-12 22:40:41 UTC (rev 12474)
@@ -60,7 +60,7 @@
</sky>
<gazeboPath>media</gazeboPath>
<grid>false</grid>
- <maxUpdateRate>100</maxUpdateRate>
+ <maxUpdateRate>0.001</maxUpdateRate>
</rendering:ogre>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|