<|start_filename|>src/nubot_simulation/nubot_gazebo/plugins/parabolic_transition_planning.hh<|end_filename|>
/*
 * Copyright (C) 2014-2015 NUDT
 *
 * 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.
 *
*/

#ifndef PARABOLIC_TRANSITION_PLANNING_HH
#define PARABOLIC_TRANSITION_PLANNING_HH

#include "gazebo/common/Time.hh"
#include "gazebo/util/system.hh"

namespace nubot
{
    /// \class ParaTrajPlanning
    /// \brief trajectory planning for parabolic curve transition.
    /// The trajectory consists of 3 part: two parabolic curve in the beginning and
    /// in the end; a straight line in the middle. This trajectory avoids the infinite
    /// acceleration at the beginning and at the end if just sepcify straight line trajectory
    class ParaTrajPlanning
    {
      /// \brief Constructor. Initialize para_traj_planning params
      /// \param[in] _accel     The acceleration.
      /// \param[in] _distance  The total distance to travel.
      /// \param[in] _max_vel   The maximum velocity.
      public: ParaTrajPlanning(double _accel = 0.0, double _max_vel = 0.0, double _distance = 0.0);

      /// \brief Destructor
      public: virtual ~ParaTrajPlanning();

      /// \brief Initialize para_traj_planning params
      /// \param[in] _accel     The acceleration.
      /// \param[in] _distance  The total distance to travel. If _distance is negative, it will
      ///                       changed to positive in this function.
      /// \param[in] _max_vel   The maximum velocity.
      public: void Init(double _accel = 0.0,  double _max_vel = 0.0, double _distance = 0.0);

      /// \brief Set the constant acceleration for the parabolic curve.
      /// \param[in] _accel the acceleration.
      public: void SetAccel(double _accel);

      /// \brief Set distance about to travel.
      /// \param[in] _distance the distance
      public: void SetDistance(double _distance);

      /// \brief Set the maximum velocity.
      /// \param[in] _vel the velocity
      public: void SetMaxVel(double _vel);

      /// \brief Get the constant acceleration.
      /// \return The constant acceleration
      public: double GetAccel() const;

      /// \brief Get distance about to travel.
      /// \return The distance
      public: double GetDistance() const;

      /// \brief Get the maximum velocity or the velocity of the straight line part.
      /// \return The maximum velocity
      public: double GetMaxVel() const;

      /// \brief Get velocity of the trajectory.
      /// \param[_in] _dt Change in time since last update call.
      /// \return the velocity
      public: double VelUpdate(double _dt);

      /// \brief Get displacement of the trajectory.
      /// \param[in] _dt Change in time since last update call.
      /// \return the displacemet
      public: double DispUpdate(double _dt);

      /// \brief Assignment operator
      /// \param[in] _p a reference to a para_traj_plannining to assign values from
      /// \return reference to this instance
      public: ParaTrajPlanning &operator=(const ParaTrajPlanning &_p)
              {
                if (this == &_p)
                  return *this;

                this->a_ = _p.a_;
                this->dis_ = _p.dis_;
                this->vm_ = _p.vm_;
                this->t_ = _p.t_;
                this->out_vel_ = _p.out_vel_;
                this->out_disp_ = _p.out_disp_;
                this->tb_ = _p.tb_;
                this->tf_ = _p.tf_;

                this->Reset();
                return *this;
              }

      /// \brief Reset all the params, output_vel_ and output_disp_;
      public: void Reset();

      /// \brief constant acceleration of the parabolic curve.
      private: double a_;

      /// \brief total distance to travel
      private: double dis_;

      /// \brief maximum velocity; the const velocity of the stragight line trajectory
      private: double vm_;

      /// \brief total time starting from 0
      private: double t_;

      /// \brief output velocity of the trajectory
      private: double out_vel_;

      /// \brief output displacement of the trajectory
      private: double out_disp_;

      /// \brief end time of the first parabolic curve
      private: double tb_;

      /// \brief end time of the trajectory
      private: double tf_;

      /// \brief flag to indicate if there is a straight line part
      private: bool is_straight_line_;
    };
}
#endif


<|start_filename|>doc/html/search/typedefs_9.js<|end_filename|>
var searchData=
[
  ['value_5ftype',['value_type',['../classnubot_1_1DPoint__.html#a1a546245bbee6a62f83ed6126035c61a',1,'nubot::DPoint_']]],
  ['velcmd',['VelCmd',['../namespacenubot__common.html#acc00f78d81bb67c28f6b4aaf38c2c884',1,'nubot_common']]],
  ['velcmdconstptr',['VelCmdConstPtr',['../namespacenubot__common.html#a432df2503deef33e00a5aa25b43c3d05',1,'nubot_common']]],
  ['velcmdptr',['VelCmdPtr',['../namespacenubot__common.html#a1bad07d199495dad168c627253bbf1ec',1,'nubot_common']]]
];


<|start_filename|>src/nubot_simulation/nubot_gazebo/plugins/parabolic_transition_planning.cc<|end_filename|>
/*
 * Copyright (C) 2015 NuBot team of National University of Defense Technology
 *
 * 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: Simple trajectory planning with parabolic transition of displacement.
 * Author: <NAME>
 * Date: Jun 2015
 */

#include <math.h>
#include <cmath>
#include <stdio.h>
#include <ros/ros.h>

#include "parabolic_transition_planning.hh"

using namespace nubot;

ParaTrajPlanning::ParaTrajPlanning(double _accel, double _max_vel, double _distance)
  : a_(_accel), dis_(_distance), vm_(_max_vel)
{
    this->Reset();
    dis_ = _distance>0 ? _distance : -_distance;
    if(vm_ * vm_ < a_ * dis_)
    {
        is_straight_line_ = true;
        tb_ = vm_ / a_;
        tf_ = (a_*dis_ + vm_*vm_)/(a_*vm_);
    }
    else
    {
        is_straight_line_ = false;
        tb_ = sqrt(dis_ / a_);
        tf_ = 2.0 * tb_;
    }
}

ParaTrajPlanning::~ParaTrajPlanning()
{}

void ParaTrajPlanning::Init(double _accel, double _max_vel, double _distance)
{
    this->a_ = _accel;
    this->dis_ = _distance>0 ? _distance : -_distance;
    this->vm_ = _max_vel;

    this->Reset();
    if(vm_ * vm_ < a_ * dis_)
    {
        is_straight_line_ = true;
        tb_ = vm_ / a_;
        tf_ = (a_*dis_ + vm_*vm_)/(a_*vm_);
    }
    else
    {
        is_straight_line_ = false;
        tb_ = sqrt(dis_ / a_);
        tf_ = 2.0 * tb_;
    }
    ROS_INFO("Traj Initialization!! max_vel^2=%f a(%f)*d(%f)=%f is_straight_line=%d tf:%f",
              vm_ * vm_ ,
              a_,dis_,
              a_ * dis_,
              is_straight_line_,tf_);
}

void ParaTrajPlanning::SetAccel(double _accel)
{
    this->a_ = _accel;
}


void ParaTrajPlanning::SetDistance(double _distance)
{
    this->dis_ = _distance>0 ? _distance : -_distance;
}

void ParaTrajPlanning::SetMaxVel(double _vel)
{
    this->vm_ = _vel;
}

void ParaTrajPlanning::Reset()
{
    this->t_ = 0.0;
    this->out_vel_ = 0.0;
    this->out_disp_ = 0.0;
}

double ParaTrajPlanning::VelUpdate(double _dt)
{
    if(t_ < 0.0)
    {
        ROS_FATAL("ERROR TIME!");
        Reset();
        return -1;
    }

    if(is_straight_line_)
    {
        if(t_ < tb_)                // 0 < time_ < t_b_
        {
            out_vel_ = a_ * t_;
        }
        else if(t_ < tf_ - tb_)   // t_b_ <= time_ < t_f_ - t_b_
        {
            out_vel_ = vm_;
        }
        else if(t_ < tf_)          // t_f_ - t_b_ < time_ < t_f_
        {
            out_vel_ = a_ * (tf_ - t_);
        }
        else                            // time_ > t_f_
        {
            out_vel_ = 0.0;
        }
    }
    else
    {
        if(t_ < tb_)        // 0 < time_ < t_b_
        {
            out_vel_ = a_ * t_;
        }
        else if(t_ < tf_)   // t_b_ <= time_ < t_f_
        {
            out_vel_ = a_ * (tf_ - t_);
        }
        else                    // time_ > t_f_
        {
            out_vel_ = 0.0;
        }
    }

    t_ = t_ + _dt;
    return this->out_vel_;
}


double ParaTrajPlanning::DispUpdate(double _dt)
{
    if(t_ < 0.0)
    {
        ROS_FATAL("ERROR TIME!");
        Reset();
        return -1;
    }

    if(is_straight_line_)
    {
        if(t_ < tb_)                // 0 < time_ < t_b_
        {
            out_disp_= 0.5*a_*t_*t_;
        }
        else if(t_ < tf_ - tb_)   // t_b_ <= time_ < t_f_ - t_b_
        {
            out_disp_= 0.5*a_*tb_*tb_ + vm_*(t_-tb_);
        }
        else if(t_ < tf_)          // t_f_ - t_b_ < time_ < t_f_
        {
            out_disp_= 0.5*a_*tb_*tb_ + vm_*(tf_-2*tb_)+a_*tf_*(t_-tf_+tb_)-0.5*a_*(t_+tf_-tb_)*(t_-tf_+tb_);
        }
        else                            // time_ > t_f_
        {
            out_disp_= a_*tb_*(tf_-tb_);
        }
    }
    else
    {
        if(t_ < tb_)        // 0 < time_ < t_b_
        {
            out_disp_= 0.5*a_*t_*t_;
        }
        else if(t_ < tf_)   // t_b_ <= time_ < t_f_
        {
            out_disp_= 0.5*a_*tb_*tb_ + a_*tf_*(t_-tb_) - 0.5*a_*(t_+tb_)*(t_-tb_);
        }
        else                    // time_ > t_f_
        {
            out_disp_= a_*(tb_*tb_+0.5*tf_*tf_-tf_*tb_);
        }
    }

    t_ = t_ + _dt;
    return this->out_disp_;
}


double ParaTrajPlanning::GetAccel() const
{
    return this->a_;
}


double ParaTrajPlanning::GetDistance() const
{
    return this->dis_;
}


double ParaTrajPlanning::GetMaxVel() const
{
    return this->vm_;
}


<|start_filename|>doc/html/search/files_0.js<|end_filename|>
var searchData=
[
  ['_5f_5finit_5f_5f_2epy',['__init__.py',['../nubot__common_2____init_____8py.html',1,'']]],
  ['_5f_5finit_5f_5f_2epy',['__init__.py',['../nubot__common_2msg_2____init_____8py.html',1,'']]],
  ['_5f_5finit_5f_5f_2epy',['__init__.py',['../nubot__common_2srv_2____init_____8py.html',1,'']]],
  ['_5f_5finit_5f_5f_2epy',['__init__.py',['../nubot__gazebo_2____init_____8py.html',1,'']]],
  ['_5f_5finit_5f_5f_2epy',['__init__.py',['../nubot__gazebo_2cfg_2____init_____8py.html',1,'']]],
  ['_5fballhandle_2epy',['_BallHandle.py',['../__BallHandle_8py.html',1,'']]],
  ['_5fsetup_5futil_2epy',['_setup_util.py',['../devel_2__setup__util_8py.html',1,'']]],
  ['_5fsetup_5futil_2epy',['_setup_util.py',['../build_2catkin__generated_2installspace_2__setup__util_8py.html',1,'']]],
  ['_5fshoot_2epy',['_Shoot.py',['../__Shoot_8py.html',1,'']]],
  ['_5fvelcmd_2epy',['_VelCmd.py',['../__VelCmd_8py.html',1,'']]]
];


<|start_filename|>doc/html/search/defines_1.js<|end_filename|>
var searchData=
[
  ['compiler_5fid',['COMPILER_ID',['../CMakeCCompilerId_8c.html#a81dee0709ded976b2e0319239f72d174',1,'COMPILER_ID():&#160;CMakeCCompilerId.c'],['../CMakeCXXCompilerId_8cpp.html#a81dee0709ded976b2e0319239f72d174',1,'COMPILER_ID():&#160;CMakeCXXCompilerId.cpp']]]
];


<|start_filename|>doc/html/search/typedefs_2.js<|end_filename|>
var searchData=
[
  ['ballhandlerequest',['BallHandleRequest',['../namespacenubot__common.html#a47b9531f744aace81704d183c8f37107',1,'nubot_common']]],
  ['ballhandlerequestconstptr',['BallHandleRequestConstPtr',['../namespacenubot__common.html#a13b0bac07f7e0ff274332e889c7bcc6b',1,'nubot_common']]],
  ['ballhandlerequestptr',['BallHandleRequestPtr',['../namespacenubot__common.html#ae7e699c9607faea27a823400688f92cb',1,'nubot_common']]],
  ['ballhandleresponse',['BallHandleResponse',['../namespacenubot__common.html#a794ba6eb699c7139e7256886a99845bb',1,'nubot_common']]],
  ['ballhandleresponseconstptr',['BallHandleResponseConstPtr',['../namespacenubot__common.html#aa7fc00ffdb3275b8611d9385a276bae0',1,'nubot_common']]],
  ['ballhandleresponseptr',['BallHandleResponsePtr',['../namespacenubot__common.html#a5dc998c69f3170b6a93ed0a818a74cc9',1,'nubot_common']]]
];


<|start_filename|>doc/html/search/typedefs_7.js<|end_filename|>
var searchData=
[
  ['shootrequest',['ShootRequest',['../namespacenubot__common.html#ab115c969a87ffc5940d2f26488a5baa3',1,'nubot_common']]],
  ['shootrequestconstptr',['ShootRequestConstPtr',['../namespacenubot__common.html#af6ec3e639ec8410eff9da8b559df3952',1,'nubot_common']]],
  ['shootrequestptr',['ShootRequestPtr',['../namespacenubot__common.html#aab5a1233cee5cd37a060be382351f99d',1,'nubot_common']]],
  ['shootresponse',['ShootResponse',['../namespacenubot__common.html#a7fc7346cebf4ea3bdbc7c25438d3959e',1,'nubot_common']]],
  ['shootresponseconstptr',['ShootResponseConstPtr',['../namespacenubot__common.html#aacaf2fc964aa85e0b87fd5721490e203',1,'nubot_common']]],
  ['shootresponseptr',['ShootResponsePtr',['../namespacenubot__common.html#aead2ba57f157347012f6575c18c422d2',1,'nubot_common']]]
];


<|start_filename|>src/nubot_common/core/include/nubot/core/DPoint.hpp<|end_filename|>

#ifndef __NUBOT_CORE_DPOINT_HPP__
#define __NUBOT_CORE_DPOINT_HPP__

#include "Angle.hpp"
#include <cmath>

namespace nubot
{
	
template<typename _Tp> class DPoint_
{
public:
	typedef _Tp value_type;
	// various constructors
	DPoint_();
	template<typename _Tp2> DPoint_(_Tp2 _x, _Tp2 _y);
	template<typename _Tp2> DPoint_(const DPoint_<_Tp2>& pt);

	template<typename _Tp2> DPoint_& operator = (const DPoint_<_Tp2>& pt);
	//! conversion to another data type
	template<typename _Tp2> operator DPoint_<_Tp2>() const;
	//! Polar point is converted to DPont;
	template<typename _Tp2> DPoint_(const _Tp2 & pt); 
	// 	//! Polar point is converted to DPont;
	template<typename _Tp2> DPoint_<_Tp> & operator = (const _Tp2 & pt);
	//! dot product
	_Tp dot(const DPoint_& pt) const;
	//! dot product computed in double-precision arithmetics
	double ddot(const DPoint_& pt) const;
	//! cross-product
	double cross(const DPoint_& pt) const;
	//! distance between (x_,y_) and pt
	template<typename _Tp2> double distance(const DPoint_<_Tp2>& pt) const;
	//! value of norm;
	double norm() const;
	//! angle of (y_,x_)
	Angle  angle() const;	
	//! angle of (y_-pt.y_,x_-pt.x_)
	template<typename _Tp2> Angle angle(const DPoint_<_Tp2>& pt) const; 
	//!  transfered into  (-x_,-y_)
	DPoint_<_Tp>  mirror() const;
	//!  rotate angle around original point (0,0)
	DPoint_<_Tp>  rotate (const Angle & _angle) const ;
	//!  rotate angle around pt
	template<typename _Tp2> DPoint_<_Tp> rotate(const DPoint_<_Tp2>& pt,const Angle & _angle) const;

	_Tp x_, y_; //< the point coordinates
};

typedef DPoint_<int>    DPoint2i;
typedef DPoint_<float>  DPoint2f;
typedef DPoint_<double> DPoint2d;
typedef DPoint2d DPoint;

//////////////////////////////// Cartesian  Point ////////////////////////////////
template<typename _Tp> inline DPoint_<_Tp>::DPoint_() : x_(0), y_(0) {}
template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>::DPoint_(_Tp2 _x, _Tp2 _y) : x_(_Tp(_x)), y_(_Tp(_y)) {}
template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>::DPoint_(const DPoint_<_Tp2>& pt)
	: x_(_Tp(pt.x_)), y_(_Tp(pt.y_)) {}
template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>& DPoint_<_Tp>::operator = (const DPoint_<_Tp2>& pt)
{ x_ =_Tp(pt.x_); y_ = _Tp(pt.y_); return *this; }
template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>::operator DPoint_<_Tp2>() const
{ return DPoint_<_Tp>(_Tp(x_), _Tp(y_)); }

template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>::DPoint_(const _Tp2 & pt)
	: x_(_Tp(pt.radius_*cos(pt.angle_.radian_))),y_(_Tp(pt.radius_*sin(pt.angle_.radian_))) {}

template<typename _Tp> template<typename _Tp2> inline DPoint_<_Tp>& DPoint_<_Tp>::operator = (const _Tp2 & pt)
{
	x_=_Tp(pt.radius_*cos(pt.angle_.radian_));
	y_=_Tp(pt.radius_*sin(pt.angle_.radian_));
	return *this;
}

template<typename _Tp> inline _Tp DPoint_<_Tp>::dot(const DPoint_& pt) const
{ return _Tp(x_*pt.x_ + y_*pt.y_); }
template<typename _Tp> inline double DPoint_<_Tp>::ddot(const DPoint_& pt) const
{ return (double)x_*pt.x_ + (double)y_*pt.y_; }
template<typename _Tp> inline double DPoint_<_Tp>::cross(const DPoint_& pt) const
{ return (double)x_*pt.y_ - (double)y_*pt.x_; }
template<typename _Tp> inline DPoint_<_Tp> DPoint_<_Tp>::rotate( const Angle & _angle)  const
{   return DPoint_<_Tp>(_Tp(x_*cos(_angle.radian_)+y_*sin((_angle.radian_))),
                        _Tp(-x_*sin(_angle.radian_)+y_*cos(_angle.radian_))); }

template<typename _Tp> template<typename _Tp2>inline double DPoint_<_Tp>::distance(const DPoint_<_Tp2> & pt) const
{
	return (std::sqrt(double((x_-pt.x_)*(x_-pt.x_)+(y_-pt.y_)*(y_-pt.y_))));
}

template<typename _Tp> template<typename _Tp2>inline DPoint_<_Tp> DPoint_<_Tp>::rotate(const DPoint_<_Tp2> & pt,const Angle & _angle) const
{
	Angle  theta =_angle+(atan2(double(y_-pt.y_),double(x_-pt.x_)));
	double tmp_dis=distance(pt);
	return DPoint_<_Tp>(_Tp(pt.x_+cos(theta.radian_)*tmp_dis),_Tp(pt.y_+sin(theta.radian_)*tmp_dis));
}

template<typename _Tp>inline double DPoint_<_Tp>::norm() const
{
	return std::sqrt((double)x_*x_ + (double)y_*y_);
}
template<typename _Tp> inline Angle DPoint_<_Tp>::angle() const
{ 
	return Angle(atan2(y_,x_));
}
template<typename _Tp> template<typename _Tp2> Angle DPoint_<_Tp>::angle(const DPoint_<_Tp2>& pt) const
{
	return Angle(atan2(double(y_-pt.y_),double(x_-pt.x_)));
}

template<typename _Tp> inline DPoint_<_Tp> DPoint_<_Tp>::mirror()  const
{   return DPoint_<_Tp>(_Tp(-x_),_Tp(-y_)); }

template<typename _Tp> static inline DPoint_<_Tp>& operator += (DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{
	a.x_ = _Tp(a.x_ + b.x_);
	a.y_ = _Tp(a.y_ + b.y_);
	return a;
}

template<typename _Tp> static inline DPoint_<_Tp>& operator -= (DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{
	a.x_ = _Tp(a.x_ - b.x_);
	a.y_ = _Tp(a.y_ - b.y_);
	return a;
}

template<typename _Tp> static inline DPoint_<_Tp>& operator *= (DPoint_<_Tp>& a, int b)
{
	a.x_ = _Tp(a.x_*b);
	a.y_ = _Tp(a.y_*b);
	return a;
}

template<typename _Tp> static inline DPoint_<_Tp>& operator *= (DPoint_<_Tp>& a, float b)
{
	a.x_ = _Tp(a.x_*b);
	a.y_ = _Tp(a.y_*b);
	return a;
}

template<typename _Tp> static inline DPoint_<_Tp>& operator *= (DPoint_<_Tp>& a, double b)
{
	a.x_ = _Tp(a.x_*b);
	a.y_ = _Tp(a.y_*b);
	return a;
}

template<typename _Tp> static inline bool operator == (const DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{ return a.x_ == b.x_ && a.y_ == b.y_; }

template<typename _Tp> static inline bool operator != (const DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{ return a.x_ != b.x_ || a.y_ != b.y_; }

template<typename _Tp> static inline DPoint_<_Tp> operator + (const DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{ return DPoint_<_Tp>( _Tp(a.x_ + b.x_), _Tp(a.y_ + b.y_) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator - (const DPoint_<_Tp>& a, const DPoint_<_Tp>& b)
{ return DPoint_<_Tp>( _Tp(a.x_ - b.x_), _Tp(a.y_ - b.y_) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator - (const DPoint_<_Tp>& a)
{ return DPoint_<_Tp>( _Tp(-a.x_), _Tp(-a.y_) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (const DPoint_<_Tp>& a, int b)
{ return DPoint_<_Tp>( _Tp(a.x_*b), _Tp(a.y_*b) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (int a, const DPoint_<_Tp>& b)
{ return DPoint_<_Tp>( _Tp(b.x_*a), _Tp(b.y_*a) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (const DPoint_<_Tp>& a, float b)
{ return DPoint_<_Tp>( _Tp(a.x_*b), _Tp(a.y_*b) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (float a, const DPoint_<_Tp>& b)
{ return DPoint_<_Tp>( _Tp(b.x_*a), _Tp(b.y_*a) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (const DPoint_<_Tp>& a, double b)
{ return DPoint_<_Tp>( _Tp(a.x_*b), _Tp(a.y_*b) ); }

template<typename _Tp> static inline DPoint_<_Tp> operator * (double a, const DPoint_<_Tp>& b)
{ return DPoint_<_Tp>( _Tp(b.x_*a), _Tp(b.y_*a) ); }

}

#endif //!__DPOINT_H_


<|start_filename|>src/nubot_common/core/include/nubot/core/core.hpp<|end_filename|>
#ifndef __NUBOT_CORE_HPP__
#define __NUBOT_CORE_HPP__


#include "Circle.hpp"
#include "Angle.hpp"
#include "DPoint.hpp"
#include "PPoint.hpp"
#include "Line.hpp"
//#include "time.hpp"

#endif 
