• Nenhum resultado encontrado

Geração de Trajetórias no ROS

N/A
N/A
Protected

Academic year: 2021

Share "Geração de Trajetórias no ROS"

Copied!
85
0
0

Texto

(1)

Geração de Trajetórias no ROS

Walter Fetter Lages

fetter@ece.ufrgs.br

Universidade Federal do Rio Grande do Sul Escola de Engenharia

Departamento de Sistemas Elétricos de Automação e Energia ENG10026 Robótica A

(2)

Introdução

Implementada na biblioteca KDL (Kinematics

and Dynamics Library

)

Implementa classes para especificar:

Caminhos

Perfis de velocidade

Trajetórias de frames

Trajetória no espaço cartesiano

Trajetórias de cadeias cinemáticas

(3)

Classe KDL::Path

(4)

Classe KDL::Path

class Path { public:

enum IdentifierType { ID_LINE =1,ID_CIRCLE =2,

ID_COMPOSITE =3, ID_ROUNDED_COMPOSITE =4, ID_POINT =5, ID_CYCLIC_CLOSED =6 };

virtual double LengthToS(double length)=0; virtual double PathLength()=0;

virtual Frame Pos(double s) const=0;

virtual Twist Vel(double s,double sd) const=0;

virtual Twist Acc(double s,double sd,double sdd) const=0; virtual void Write(std::ostream &os)=0;

static Path ∗Read(std::istream &is); virtual Path ∗Clone()=0;

virtual IdentifierType getIdentifier() const=0; virtual ~Path() {};

(5)

KDL::Path_Circle

Implementa um caminho em arco de

circunferênca

class Path_Circle:public Path

{

public:

Path_Circle(const Frame &F_base_start,const Vector &

V_base_center,

const Vector &V_base_p,const Rotation &R_base_end, double alpha,RotationalInterpolation ∗otraj,

double eqradius,bool _aggregate=true); virtual ~Path_Circle();

(6)

KDL::Path_Composite

Permite a formação de caminhos compostos

class Path_Composite:public Path

{

public:

Path_Composite();

void Add(Path ∗geom,bool aggregate=true);

virtual int GetNrOfSegments(); virtual Path ∗GetSegment(int i);

virtual double GetLengthToEndOfSegment(int i);

virtual void GetCurrentSegmentLocation(double s,int &

segment_number,double &inner_s);

virtual ~Path_Composite();

(7)

KDL::Path_Cyclic_Closed

Permite a formação de caminhos fechados e

repetitivos

class Path_Cyclic_Closed:public Path

{

public:

Path_Cyclic_Closed(Path ∗_geom,int _times,bool _aggregate=true)

;

virtual ~Path_Cyclic_Closed();

(8)

KDL::Path_Line

Implementa um caminho em linha reta

class Path_Line:public Path

{

public:

Path_Line(const Frame &F_base_start,const Frame &F_base_end,

RotationalInterpolation ∗orient,double eqradius,

bool _aggregate=true);

Path_Line(const Frame &F_base_start,const Twist &twist_in_base,

RotationalInterpolation ∗orient,double eqradius,

bool _aggregate=true);

virtual ~Path_Line();

(9)

KDL::Path_Point

Implementa um caminho pontual

class Path_Point:public Path

{

public:

Path_Point(const Frame& F_base_start);

virtual ~Path_Point();

(10)

KDL::Path_RoundedComposite

Caminho composto com transições suaves

class Path_RoundedComposite:public Path

{

public:

Path_RoundedComposite(double radius,double eqradius,

RotationalInterpolation ∗orient,bool aggregate=true);

void Add(const Frame &F_base_point);

void Finish();

virtual int GetNrOfSegments(); virtual Path ∗GetSegment(int i);

virtual double GetLengthToEndOfSegment(int i);

virtual void GetCurrentSegmentLocation(double s,int &

segment_number,double &inner_s);

virtual ~Path_RoundedComposite();

(11)

KDL::RotationalInterpolation

Especifica a parte rotacional de um caminho no

(12)

KDL::RotationalInterpolation

class RotationalInterpolation

{

public:

virtual void SetStartEnd(Rotation start,Rotation end)=0; virtual double Angle()=0;

virtual Rotation Pos(double theta) const=0;

virtual Vector Vel(double theta,double thetad) const=0;

virtual Vector Acc(double theta,double thetad,double thetadd) const=0;

virtual void Write(std::ostream &os) const=0;

static RotationalInterpolation ∗Read(std::istream &is); virtual RotationalInterpolation ∗Clone() const=0;

virtual ~RotationalInterpolation();

(13)

KDL::RotationalInterpolation_SingleAxis

Interpolação através da rotação em torno de um

único eixo

class RotationalInterpolation_SingleAxis: public

RotationalInterpolation { public: RotationalInterpolation_SingleAxis(); virtual ~RotationalInterpolation_SingleAxis(); };

(14)

Classe KDL::VelocityProfile

Representa um perfil de velocidade

(15)

KDL::VelocityProfile

class VelocityProfile

{

public:

virtual void SetProfile(double pos1,double pos2)=0;

virtual void SetProfileDuration(double pos1,double pos2,double

duration)=0;

virtual double Duration() const=0;

virtual double Pos(double time) const=0; virtual double Vel(double time) const=0; virtual double Acc(double time) const=0; virtual void Write(std::ostream &os) const=0; static VelocityProfile ∗Read(std::istream &is); virtual VelocityProfile ∗Clone() const=0;

(16)

KDL::VelocityProfile_Dirac

Perfil de velocidade delta de Dirac

class VelocityProfile_Dirac:public VelocityProfile

{

public:

virtual ~VelocityProfile_Dirac();

(17)

KDL::VelocityProfile_Rectangular

Perfil de velocidade retangular

class VelocityProfile_Rectangular:public VelocityProfile

{

public:

VelocityProfile_Rectangular(double _maxvel=0);

void SetMax(double _maxvel);

virtual ~VelocityProfile_Rectangular();

(18)

KDL::VelocityProfile_Spline

Perfil de velocidade em spline

Polinômio de grau 5

class VelocityProfile_Spline:public VelocityProfile

{

public:

VelocityProfile_Spline();

VelocityProfile_Spline(const VelocityProfile_Spline &p);

virtual ~VelocityProfile_Spline();

virtual void SetProfileDuration(double pos1, double vel1, double

pos2, double vel2, double duration);

virtual void SetProfileDuration(double pos1, double vel1, double

acc1, double pos2, double vel2, double acc2, double duration);

(19)

KDL::VelocityProfile_Trap

Perfil de velocidade trapezoidal

class VelocityProfile_Trap:public VelocityProfile

{

public:

VelocityProfile_Trap(double _maxvel=0,double _maxacc=0);

virtual void SetProfileVelocity(double pos1,double pos2,double

newvelocity);

virtual void SetMax(double _maxvel,double _maxacc); virtual ~VelocityProfile_Trap();

(20)

KDL::VelocityProfile_TrapHalf

Perfil de velocidade trapezoidal pela metade

Só o início ou só o final

class VelocityProfile_TrapHalf:public VelocityProfile

{

public:

VelocityProfile_TrapHalf(double _maxvel=0,double _maxacc=0,

bool _starting=true);

void SetMax(double _maxvel,double _maxacc,bool _starting);

virtual ~VelocityProfile_TrapHalf();

(21)

Classe KDL::Trajectory

Implementa uma trajetória cartesiana

(22)

KDL::Trajectory

class Trajectory

{

public:

virtual double Duration() const=0;

virtual Frame Pos(double time) const=0; virtual Twist Vel(double time) const=0; virtual Twist Acc(double time) const=0; virtual Trajectory ∗Clone() const=0;

virtual void Write(std::ostream &os) const=0; static Trajectory ∗Read(std::istream &is);

virtual ~Trajectory();

(23)

KDL::Trajectory_Composite

Implementa uma trajetória cartesiana composta

Os elementos adicionados com Add() são

destruídos pelo destrutor da classe.

Devem ser alocados dinamicamente

class Trajectory_Composite:public Trajectory

{

public:

Trajectory_Composite();

virtual void Add(Trajectory ∗elem); virtual void Destroy();

virtual ~Trajectory_Composite();

(24)

KDL::Trajectory_Segment

Implementa um segmento de trajetória cartesiana

class Trajectory_Segment:public Trajectory

{

public:

Trajectory_Segment(Path ∗_geom,VelocityProfile ∗_motprof,bool

_aggregate=true);

Trajectory_Segment(Path ∗_geom,VelocityProfile ∗_motprof,double

duration,bool _aggregate=true);

virtual Path ∗GetPath();

virtual VelocityProfile ∗GetProfile(); virtual ~Trajectory_Segment();

(25)

KDL::Trajectory_stationary

“Trajetória” cartesiana com o robô parado

class Trajectory_Stationary:public Trajectory

{

public:

Trajectory_Stationary(double _duration,const Frame &_pos);

virtual ~Trajectory_Stationary();

(26)

Exemplo - Trajetória Cartesiana

Caminho especificado através de via points

(0.61, 0, 0.1477), (0.437, −0.424, 0.1477),

(0.238, −0.505, 0.1477),

(0.437, 0.424, 0.1477), (0.238, 0.505, 0.1477),

(0.61, 0, 0.1477)

Perfil de velocidade trapezoidal

Velocidade máxima 0.1 m/s

Aceleração 0.02 m/s

2

Trajetória fica parada 1 s no ponto final

Discretização de 0.1 s

Publica mensagem

(27)

geometry_msgs::PoseStamped

std_msgs/Header header uint32 seq time stamp string frame_id geometry_msgs/Pose pose geometry_msgs/Point position float64 x float64 y float64 z geometry_msgs/Quaternion orientation float64 x float64 y float64 z

(28)

Pacote eng10026_trajectories

Criar o pacote:

cd ~/catkin_ws/src

catkin_create_pkg eng10026_trajectories roscpp orocos_kdl

kdl_conversions −s Eigen3

package.xml

deve ser editado para configurar

os detalhes de documentação e incluir

dependências

(29)

CMakeLists.txt

Editar CMakeLists.txt para descomentar e

ajustar as tags add_executable e

target_link_libraries:

add_executable(pose_trajectory_publisher src/ pose_trajectory_publisher.cpp) target_link_libraries(pose_trajectory_publisher ${catkin_LIBRARIES} ${Eigen3_LIBRARIES} )

(30)

Inclusão no Meta-Pacote

O pacote eng10026_trajectories será

incluido no meta-pacote eng10026

Editar o arquivo package.xml do pacote

eng10026

e incluir

(31)

pose_trajectory_publisher.cpp

#include <ros/ros.h> #include <kdl/path_roundedcomposite.hpp> #include <kdl/rotational_interpolation_sa.hpp> #include <kdl/velocityprofile_trap.hpp> #include <kdl/trajectory_segment.hpp> #include <kdl/trajectory_stationary.hpp> #include <kdl/trajectory_composite.hpp> #include <kdl/utilities/error.h> #include <kdl_conversions/kdl_msg.h> #include <geometry_msgs/PoseStamped.h>

(32)

pose_trajectory_publisher.cpp

int main(int argc,char∗ argv[])

{ ros::init(argc,argv,"trajectory_publisher"); ros::NodeHandle node; ros::Publisher posePublisher=node.advertise<geometry_msgs:: PoseStamped>("pose",10); try {

Path_RoundedComposite path(0.02,0.002,new

(33)

pose_trajectory_publisher.cpp

path.Add(Frame(Rotation::RPY(0,0,0),Vector(0.61,0,0.1477))); path.Add(Frame(Rotation::Quaternion(0,0,−0.375,0.926),Vector (0.437,−0.424,0.1477))); path.Add(Frame(Rotation::RotZ(−M_PI/2),Vector (0.238,−0.505,0.1477))); path.Add(Frame(Rotation::Quaternion(0,0,0.375,0.926),Vector (0.437,0.424,0.1477))); path.Add(Frame(Rotation::RotZ(M_PI/2∗0),Vector (0.238,0.505,0.1477))); path.Add(Frame(Rotation::RPY(0,0,0),Vector(0.61,0,0.1477))); path.Finish(); VelocityProfile_Trap velocityProfile(0.1,0.02);

(34)

pose_trajectory_publisher.cpp

Trajectory_Segment ∗trajectorySegment=new Trajectory_Segment

(&path,&velocityProfile,false);

Trajectory_Composite trajectory; trajectory.Add(trajectorySegment);

trajectory.Add(new Trajectory_Stationary(1.0,Frame(Rotation::

RPY(0,0,0),Vector(0.61,0,0.1477)))); double dt=0.1; double t=0.0; ros::Rate loop(1/dt); while(ros::ok()) { Frame pose=trajectory.Pos(t);

(35)

pose_trajectory_publisher.cpp

geometry_msgs::PoseStamped poseMsg; poseMsg.header.stamp=ros::Time::now(); poseMsg.header.frame_id="map"; tf::poseKDLToMsg(pose,poseMsg.pose); posePublisher.publish(poseMsg); ros::spinOnce(); loop.sleep(); if(t <= trajectory.Duration()) t+=dt; } }

(36)

pose_trajectory_publisher.cpp

catch(Error &error)

{

ROS_ERROR_STREAM("Error : " << error.Description() << std::

endl);

ROS_ERROR_STREAM("Type " << error.GetType() << std::endl

); }

posePublisher.shutdown();

return 0;

(37)

Visualização da Trajetória

A visualização de geometry_msgs/Pose no

rviz é através de um vetor

Não é muito adequada para vizualizar a

orientação em 3D

É mais conveniente vizualizar um frame

É necessário publicar o frame no tópico /tf

Fazer um conversor de

geometry_mgs/PoseStamped

para

tf:tfMessage

(38)

tf/tfMessage

geometry_msgs/TransformStamped[] transforms std_msgs/Header header uint32 seq time stamp string frame_id string child_frame_id geometry_msgs/Transform transform geometry_msgs/Vector3 translation float64 x float64 y float64 z geometry_msgs/Quaternion rotation float64 x float64 y float64 z

(39)

Pacote trajectory_conversions

Criar o pacote:

cd ~/catkin_ws/src

catkin_create_pkg trajectory_conversions roscpp orocos_kdl

kdl_conversions kdl_parser

geometry_msgs trajectory_msgs std_msgs

package.xml

deve ser editado para configurar

os detalhes de documentação e incluir

dependências

(40)

CMakeLists.txt

Editar CMakeLists.txt para descomentar e

ajustar as tags add_executable e

target_link_libraries:

add_executable(pose_stamped2tf src/pose_stamped2tf.cpp) target_link_libraries(pose_stamped2tf

${catkin_LIBRARIES} ${Eigen3_LIBRARIES} )

(41)

pose_stamped2tf.cpp

#include <ros/ros.h>

#include <geometry_msgs/PoseStamped.h> #include <tf/tfMessage.h>

(42)

pose_stamped2tf.cpp

class PoseStampedToTf

{

public:

PoseStampedToTf(const ros::NodeHandle &node,const char

child_frame_id); ~PoseStampedToTf(void); private: ros::NodeHandle node_; ros::Subscriber poseSubscriber_; ros::Publisher tfPublisher_; std::string child_frame_id_;

void poseStampedCB(const geometry_msgs::PoseStamped::

(43)

pose_stamped2tf.cpp

PoseStampedToTf::PoseStampedToTf(const ros::NodeHandle &node,

const char ∗child_frame_id)

{

node_=node;

child_frame_id_=child_frame_id;

poseSubscriber_=node_.subscribe("pose",10,&PoseStampedToTf::

poseStampedCB,this); tfPublisher_=node_.advertise<tf::tfMessage>("/tf",10); } PoseStampedToTf::~PoseStampedToTf(void) { poseSubscriber_.shutdown(); tfPublisher_.shutdown();

(44)

pose_stamped2tf.cpp

void PoseStampedToTf::poseStampedCB(const geometry_msgs::

PoseStamped::ConstPtr &poseMsg) const

{ tf::tfMessage tfMsg; tfMsg.transforms.resize(1); tfMsg.transforms[0].header.stamp=poseMsg−>header.stamp; tfMsg.transforms[0].header.frame_id=poseMsg−>header.frame_id; tfMsg.transforms[0].child_frame_id=child_frame_id_;

(45)

pose_stamped2tf.cpp

tfMsg.transforms[0].transform.translation.x=poseMsg−>pose. position.x; tfMsg.transforms[0].transform.translation.y=poseMsg−>pose. position.y; tfMsg.transforms[0].transform.translation.z=poseMsg−>pose. position.z; tfMsg.transforms[0].transform.rotation=poseMsg−>pose.orientation ; tfPublisher_.publish(tfMsg); }

(46)

pose_stamped2tf.cpp

int main(int argc,char∗ argv[])

{

ros::init(argc,argv,"pose_stamped2tf");

ros::NodeHandle node;

if(argc != 2)

{

ROS_ERROR_STREAM("pose_stamped2tf: No child frame id.\n"

);

return −1;

}

(47)

pose_stamped2tf.cpp

ros::spin();

return 0;

(48)

display.launch

<launch>

<node name="trajectory_publisher" pkg="

eng10026_trajectories" type="pose_trajectory_publisher" />

<node name="pose2tf" pkg="trajectory_conversions" type="

pose_stamped2tf" args="trajectory" />

<node name="rviz" pkg="rviz" type="rviz" args="−d $(find

eng10026_trajectories)/rviz/display.rviz" />

(49)

Instalação dos Pacotes

Baixar e descompactar os pacotes

indigo-eng10026-trajectories.tgz

e

indigo-trajectory-conversions.tgz

cd ~/catkin_ws/src wget http://www.ece.ufrgs.br/ros−pkgs/indigo−eng10026− trajectories.tgz tar −xvzpf indigo−eng10026−trajectories.tgz wget http://www.ece.ufrgs.br/ros−pkgs/indigo−trajectory− conversions.tgz tar −xvzpf indigo−trajectory−conversions.tgz cd .. catkin_make

(50)

Execução

roslaunch eng10026_trajectories display.launch

(51)

Trajetória

-0.5 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4 0.5 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 y(t) [m] x(t) [m] x(t) x y(t) 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 xc (t) [m] x(t) -0.5 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4 0.5 y(t) [m] y(t)

(52)
(53)

Mapeamento para o Espaço das Juntas

As Poses no espaço cartesiano devem ser

mapeadas para o espaço das juntas pelo modelo

cinemático inverso

Publicadas através da mensagem

trajectory_msgs::

JointTrajectoryPoint

float64[] positions float64[] velocities float64[] accelerations float64[] effort duration time_from_start

(54)

CMakeLists.txt

incluída no pacote

trajectory_conversions

Editar CMakeLists.txt para adicionar as

tags add_executable

e

target_link_libraries:

add_executable(pose_stamped2joint src/pose_stamped2joint.

cpp)

target_link_libraries(pose_stamped2joint

${catkin_LIBRARIES} )

(55)

pose_stamped2joint.cpp

#include <ros/ros.h> #include <geometry_msgs/PoseStamped.h> #include <trajectory_msgs/JointTrajectoryPoint.h> #include <kdl/chainiksolverpos_lma.hpp> #include <kdl_conversions/kdl_msg.h> #include <kdl_parser/kdl_parser.hpp> class Pose2Joint { public:

Pose2Joint(ros::NodeHandle node,const std::string &root,const std::

string &tip,const Eigen::Matrix<double,6,1> &L);

(56)

pose_stamped2joint.cpp

private: ros::NodeHandle node_; ros::Subscriber poseSub_; ros::Publisher jointTrajPointPub_; KDL::Chain chain_; KDL::ChainIkSolverPos_LMA ∗ikSolverPos_; KDL::JntArray q_; ros::Time t0_;

void poseCB(const geometry_msgs::PoseStamped &pose);

(57)

pose_stamped2joint.cpp

Pose2Joint::Pose2Joint(ros::NodeHandle node,const std::string &root,

const std::string &tip,const Eigen::Matrix<double,6,1> &L):q_

(0) {

node_=node; KDL::Tree tree;

if(!kdl_parser::treeFromParam("robot_description",tree))

ROS_ERROR_STREAM("Failed to construct KDL tree.");

if(!tree.getChain(root,tip,chain_)) ROS_ERROR_STREAM("Failed

to get chain from KDL tree.");

(58)

pose_stamped2joint.cpp

t0_=ros::Time::now();

jointTrajPointPub_=node_.advertise<trajectory_msgs::

JointTrajectoryPoint>("joint_trajectory_point",10);

poseSub_=node_.subscribe("/pose",10,&Pose2Joint::poseCB,this);

} Pose2Joint::~Pose2Joint(void) { poseSub_.shutdown(); jointTrajPointPub_.shutdown(); delete ikSolverPos_; }

(59)

pose_stamped2joint.cpp

void Pose2Joint::poseCB(const geometry_msgs::PoseStamped &

poseStamped) {

KDL::Frame goalFrame;

tf::poseMsgToKDL(poseStamped.pose,goalFrame);

int error=ikSolverPos_−>CartToJnt(q_,goalFrame,q_);

if(error != 0) ROS_ERROR_STREAM("Failed to compute invere

kinematics: (" << error << ") "

(60)

pose_stamped2joint.cpp

trajectory_msgs::JointTrajectoryPoint jointTrajPoint; jointTrajPoint.positions.resize(q_.data.size()); Eigen::VectorXd::Map(&jointTrajPoint.positions[0],jointTrajPoint. positions.size())=q_.data; jointTrajPoint.time_from_start=poseStamped.header.stamp−t0_;; jointTrajPointPub_.publish(jointTrajPoint); }

(61)

pose_stamped2joint.cpp

int main(int argc,char∗ argv[])

{

ros::init(argc,argv,"pose_stamped2joint");

if(argc < 3)

{

ROS_ERROR_STREAM("Please, provide a chain root and

a chain tip"); return −1; } ros::NodeHandle node; Eigen::Matrix<double,6,1> L; L << 1.0 , 1.0 , 1.0, 0.01, 0.01, 0.01;

(62)

pose_stamped2joint.cpp

Pose2Joint pose2joint(node,argv[1],argv[2],L); ros::spin();

return 0;

(63)

trajectory.launch

<launch>

<node name="trajectory_publisher" pkg="eng10026_trajectories" type="pose_trajectory_publisher" />

<node name="pose2tf" pkg="trajectory_conversions" type="

pose_stamped2tf" args="trajectory" />

<include file="$(find q2d_description)/launch/q2d.launch" />

<node name="ik" pkg="trajectory_conversions" type="

pose_stamped2joint" args="origin_link tool_link 1 1 0 0 0 0" />

<node name="joint_demux" pkg="trajectory_conversions" type="

joint_demux" />

<node name="rviz" pkg="rviz" type="rviz" args="−d $(find

eng10026_trajectories)/rviz/display.rviz" />

(64)

Execução

roslaunch eng10026_trajectories trajectory.launch rostopic echo /joint_trajectory_point

(65)

Referência para o Controlador

Pode ser necessário mapear o tópico

/joint_trajectory_point

para as

referências dos controladores

Se forem utilizados controladores

independentes por junta, cada controlador tem

uma referência do tipo std_msg/Float64:

float64 data

Se for utilizado controlador por torque

calculado, a referência já é do tipo

trajectory_msgs/

JointTrajectoryPoint

(66)

CMakeLists.txt

incluído no pacote

trajectory_conversions

Editar CMakeLists.txt para adicionar as

tags add_executable

e

target_link_libraries:

add_executable(joint_demux src/joint_demux.cpp) target_link_libraries(joint_demux

${catkin_LIBRARIES} )

(67)

joint_demux.cpp

#include <string> #include <ros/ros.h> #include <std_msgs/Float64.h> #include <trajectory_msgs/JointTrajectoryPoint.h> class JointDemux { public: JointDemux(ros::NodeHandle node); ~JointDemux(void); private: ros::NodeHandle node_;

(68)

joint_demux.cpp

ros::Subscriber jointTrajPointSub_;

std::vector<ros::Publisher> jointPosPub_;

void jointTrajPointCB(const trajectory_msgs::JointTrajectoryPoint

&jointTrajPoint); };

JointDemux::JointDemux(ros::NodeHandle node) {

node_=node;

jointTrajPointSub_=node_.subscribe("joint_trajectory_point",10,&

JointDemux::jointTrajPointCB,this);

(69)

joint_demux.cpp

JointDemux::~JointDemux(void)

{

jointTrajPointSub_.shutdown();

for(int i=jointPosPub_.size()−1;i >= 0;i−−)

{

jointPosPub_[i].shutdown(); jointPosPub_.pop_back(); }

(70)

joint_demux.cpp

void JointDemux::jointTrajPointCB(const trajectory_msgs::

JointTrajectoryPoint &jointTrajPoint) {

for(int i=jointPosPub_.size();i < jointTrajPoint.positions.size();i

++) { ros::Publisher jointPosPub; jointPosPub=node_.advertise<std_msgs::Float64>("position "+std::to_string(i),10); jointPosPub_.push_back(jointPosPub); }

(71)

joint_demux.cpp

for(int i=0;i < jointTrajPoint.positions.size() && i <

jointPosPub_.size();i++) { std_msgs::Float64 cmdMsg; cmdMsg.data=jointTrajPoint.positions[i]; jointPosPub_[i].publish(cmdMsg); } }

(72)

joint_demux.cpp

int main(int argc,char∗ argv[])

{ ros::init(argc,argv,"joint_demux"); ros::NodeHandle node; JointDemux pose2joint(node); ros::spin(); return 0; }

(73)

gazebo.launch

<launch>

<include file="$(find q2d_bringup)/launch/gazebo.launch" />

<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

<node name="trajectory_publisher" pkg="eng10026_trajectories" type="pose_trajectory_publisher" />

<node name="pose2tf" pkg="trajectory_conversions" type="

pose_stamped2tf" args="trajectory" />

<node name="ik" pkg="trajectory_conversions" type="

(74)

gazebo.launch

<node name="joint_demux" pkg="trajectory_conversions" type="

joint_demux">

<remap from="position0" to="shoulder_controller/command" />

<remap from="position1" to="elbow_controller/command" />

</node>

<node pkg="tf2_ros" type="static_transform_publisher" name="

q2d_origin_publisher" args="0 0 0 0 0 0 1 map origin_link" />

<node name="rviz" pkg="rviz" type="rviz" args="−d $(find

eng10026_trajectories)/rviz/gazebo.rviz" />

(75)

Execução

(76)
(77)

Trajetórias no Espaço das Juntas

Usualmente o caminho é uma reta

Pode-se usar diretamente a classe

KDL::VelocityProfile

e derivadas para

gerar a trajetória de cada junta

Movimento de (0, 0) a (

π

4

, −

π

4

)

Tempo final=5 s

Publica o tópico trajectory_msgs/

(78)

CMakeLists.txt

incluído no pacote

eng10026_trajectories

Editar CMakeLists.txt para adicionar as

tags add_executable

e

target_link_libraries:

add_executable(joint_trajectory_publisher src/ joint_trajectory_publisher.cpp) target_link_libraries(joint_trajectory_publisher ${catkin_LIBRARIES} ${Eigen3_LIBRARIES} )

(79)

joint_trajectory_publisher.cpp

#include <ros/ros.h>

#include <kdl/velocityprofile_spline.hpp>

#include <trajectory_msgs/JointTrajectoryPoint.h> using namespace KDL;

int main(int argc,char∗ argv[])

{

ros::init(argc,argv,"joint_trajectory_publisher");

ros::NodeHandle node;

ros::Publisher jointPublisher=node.advertise<trajectory_msgs::

(80)

joint_trajectory_publisher.cpp

const int nJoints=2;

std::vector<VelocityProfile_Spline> velocityProfile(nJoints);

double p0[nJoints]={0, 0};

double pf[nJoints]={M_PI_4,−M_PI_4}; double tf=5.0;

for(int i=0;i < velocityProfile.size();i++)

velocityProfile[i].SetProfileDuration(p0[i],0,0,pf[i],0,0,tf); double dt=0.1; double t=0.0; ros::Rate loop(1/dt); while(ros::ok()) {

(81)

joint_trajectory_publisher.cpp

trajectory_msgs::JointTrajectoryPoint jointMsg;

for(int i=0;i < velocityProfile.size();i++)

{ jointMsg.positions.push_back(velocityProfile[i].Pos(t)); jointMsg.velocities.push_back(velocityProfile[i].Vel(t)); jointMsg.accelerations.push_back(velocityProfile[i].Acc(t)); } jointMsg.time_from_start.fromSec(t); jointPublisher.publish(jointMsg); ros::spinOnce(); loop.sleep(); (t < tf) t+=dt;

(82)

joint_trajectory_publisher.cpp

jointPublisher.shutdown();

return 0;

(83)

gazebo_joint.launch

<launch>

<include file="$(find q2d_bringup)/launch/gazebo.launch" />

<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

<node name="trajectory_publisher" pkg="eng10026_trajectories" type="joint_trajectory_publisher" />

<node name="joint_demux" pkg="trajectory_conversions" type="

joint_demux">

<remap from="position0" to="shoulder_controller/command" />

<remap from="position1" to="elbow_controller/command" />

(84)

gazebo_joint.launch

<node pkg="tf2_ros" type="static_transform_publisher" name="

q2d_origin_publisher" args="0 0 0 0 0 0 1 map origin_link" />

<node name="rviz" pkg="rviz" type="rviz" args="−d $(find

eng10026_trajectories)/rviz/gazebo_joint.rviz" />

(85)

Execução

Referências

Documentos relacionados

A atividade de administração e gestão de recursos de terceiros iniciou-se no SMBCB em dezembro de 1996, e desde janeiro de 2005, o SMBCB, tem amplos e gerais

Resultados obtidos no levantamento realizado 66 dias após a aplicação, mediante o desdobramento da interação dosagem x espalhante-adesivo mostraram que o cyhe- xatin, na dosagem

É apresentada a diversidade não só de Apocynoideae na porção oriental da região Nordeste do Brasil, como também a flora de Apocynaceae de um trecho de Mata Atlântica do

estação de referência coletando dados, enquanto um outro percorre as estações de interesse, onde permanece parado entre 5 a 20 min para coletar dados. Método

Keywords: Glaucoma; Filtering surgery; Minimally invasive surgical procedures/methods; Anterior chamber.. RESUMO | Embora a cirurgia de glaucoma minimamente in- vasiva, que

Deste modo, a problemática desta pesquisa consistiu na falta de dados e informações de caráter operacional que pudessem delimitar os custos atrelados a atividade do cultivo da soja,

Resultados: Este estudo evidência os limites e possibilidades da atuação profissional do assistente social no ambulatório de implante coclear do Hospital Universitário Polydoro

Importante: é necessário que as coordenações dos Programas de Pós-Graduação tenham cadastrado no SIGAA as suas linhas de pesquisa, caso contrário, não será possível selecionar