pxmlw6n2f/Gazebo_Distributed_MPI/gazebo/math/Pose.cc

261 lines
6.5 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/* Desc: External interfaces for Gazebo
* Author: Nate Koenig
* Date: 03 Apr 2007
*/
#include "gazebo/math/Pose.hh"
using namespace gazebo;
using namespace math;
const Pose Pose::Zero = math::Pose(0, 0, 0, 0, 0, 0);
//////////////////////////////////////////////////
Pose::Pose()
: pos(0, 0, 0), rot(1, 0, 0, 0)
{
}
//////////////////////////////////////////////////
Pose::Pose(const Vector3 &_pos, const Quaternion &_rot)
: pos(_pos), rot(_rot)
{
}
//////////////////////////////////////////////////
Pose::Pose(double _x, double _y, double _z,
double _roll, double _pitch, double _yaw)
: pos(_x, _y, _z), rot(_roll, _pitch, _yaw)
{
}
//////////////////////////////////////////////////
Pose::Pose(const Pose &_pose)
: pos(_pose.pos), rot(_pose.rot)
{
}
//////////////////////////////////////////////////
Pose::Pose(const ignition::math::Pose3d &_pose)
: pos(_pose.Pos()), rot(_pose.Rot())
{
}
//////////////////////////////////////////////////
Pose::~Pose()
{
}
//////////////////////////////////////////////////
void Pose::Set(const Vector3 &_pos, const Quaternion &_rot)
{
this->pos = _pos;
this->rot = _rot;
}
//////////////////////////////////////////////////
void Pose::Set(const Vector3 &_pos, const Vector3 &_rpy)
{
this->pos = _pos;
this->rot.SetFromEuler(_rpy);
}
//////////////////////////////////////////////////
void Pose::Set(double _x, double _y, double _z,
double _roll, double _pitch, double _yaw)
{
this->pos.Set(_x, _y, _z);
this->rot.SetFromEuler(math::Vector3(_roll, _pitch, _yaw));
}
//////////////////////////////////////////////////
bool Pose::IsFinite() const
{
return this->pos.IsFinite() && this->rot.IsFinite();
}
//////////////////////////////////////////////////
Pose Pose::GetInverse() const
{
Quaternion inv = this->rot.GetInverse();
return Pose(inv * (this->pos*-1), inv);
}
//////////////////////////////////////////////////
Pose Pose::operator+(const Pose &_obj) const
{
Pose result;
result.pos = this->CoordPositionAdd(_obj);
result.rot = this->CoordRotationAdd(_obj.rot);
return result;
}
//////////////////////////////////////////////////
const Pose &Pose::operator+=(const Pose &obj)
{
this->pos = this->CoordPositionAdd(obj);
this->rot = this->CoordRotationAdd(obj.rot);
return *this;
}
//////////////////////////////////////////////////
const Pose &Pose::operator-=(const Pose &_obj)
{
this->pos = this->CoordPositionSub(_obj);
this->rot = this->CoordRotationSub(_obj.rot);
return *this;
}
//////////////////////////////////////////////////
bool Pose::operator ==(const Pose &_pose) const
{
return this->pos == _pose.pos && this->rot == _pose.rot;
}
//////////////////////////////////////////////////
bool Pose::operator!=(const Pose &_pose) const
{
return this->pos != _pose.pos || this->rot != _pose.rot;
}
//////////////////////////////////////////////////
Pose Pose::operator*(const Pose &pose)
{
return Pose(this->CoordPositionAdd(pose), pose.rot * this->rot);
}
//////////////////////////////////////////////////
Pose &Pose::operator=(const Pose &_pose)
{
this->pos = _pose.pos;
this->rot = _pose.rot;
return *this;
}
//////////////////////////////////////////////////
Pose &Pose::operator=(const ignition::math::Pose3d &_pose)
{
this->pos = _pose.Pos();
this->rot = _pose.Rot();
return *this;
}
//////////////////////////////////////////////////
Vector3 Pose::CoordPositionAdd(const Vector3 &_pos) const
{
Quaternion tmp;
Vector3 result;
// result = pose.rot + pose.rot * this->_pos * pose.rot!
tmp.w = 0.0;
tmp.x = _pos.x;
tmp.y = _pos.y;
tmp.z = _pos.z;
tmp = this->rot * (tmp * this->rot.GetInverse());
result.x = this->pos.x + tmp.x;
result.y = this->pos.y + tmp.y;
result.z = this->pos.z + tmp.z;
return result;
}
//////////////////////////////////////////////////
Vector3 Pose::CoordPositionAdd(const Pose &_pose) const
{
Quaternion tmp;
Vector3 result;
// result = _pose.rot + _pose.rot * this->pos * _pose.rot!
tmp.w = 0.0;
tmp.x = this->pos.x;
tmp.y = this->pos.y;
tmp.z = this->pos.z;
tmp = _pose.rot * (tmp * _pose.rot.GetInverse());
result.x = _pose.pos.x + tmp.x;
result.y = _pose.pos.y + tmp.y;
result.z = _pose.pos.z + tmp.z;
return result;
}
//////////////////////////////////////////////////
Quaternion Pose::CoordRotationAdd(const Quaternion &_rot) const
{
return Quaternion(_rot * this->rot);
}
//////////////////////////////////////////////////
void Pose::Reset()
{
// set the position to zero
this->pos.Set();
this->rot.SetToIdentity();
}
//////////////////////////////////////////////////
Pose Pose::CoordPoseSolve(const Pose &_b) const
{
Quaternion q;
Pose a;
a.rot = this->rot.GetInverse() * _b.rot;
q = a.rot * Quaternion(0, this->pos.x, this->pos.y, this->pos.z);
q = q * a.rot.GetInverse();
a.pos = _b.pos - Vector3(q.x, q.y, q.z);
return a;
}
//////////////////////////////////////////////////
Pose Pose::RotatePositionAboutOrigin(const Quaternion &_rot) const
{
Pose a = *this;
a.pos.x = (1.0 - 2.0*_rot.y*_rot.y - 2.0*_rot.z*_rot.z) * this->pos.x
+(2.0*(_rot.x*_rot.y+_rot.w*_rot.z)) * this->pos.y
+(2.0*(_rot.x*_rot.z-_rot.w*_rot.y)) * this->pos.z;
a.pos.y = (2.0*(_rot.x*_rot.y-_rot.w*_rot.z)) * this->pos.x
+(1.0 - 2.0*_rot.x*_rot.x - 2.0*_rot.z*_rot.z) * this->pos.y
+(2.0*(_rot.y*_rot.z+_rot.w*_rot.x)) * this->pos.z;
a.pos.z = (2.0*(_rot.x*_rot.z+_rot.w*_rot.y)) * this->pos.x
+(2.0*(_rot.y*_rot.z-_rot.w*_rot.x)) * this->pos.y
+(1.0 - 2.0*_rot.x*_rot.x - 2.0*_rot.y*_rot.y) * this->pos.z;
return a;
}
//////////////////////////////////////////////////
void Pose::Round(int _precision)
{
this->rot.Round(_precision);
this->pos.Round(_precision);
}
//////////////////////////////////////////////////
ignition::math::Pose3d Pose::Ign() const
{
return ignition::math::Pose3d(this->pos.Ign(), this->rot.Ign());
}