欢迎光临散文网 会员登陆 & 注册

项目设计Ⅰ——ROS小车结合aruco码定位到达目标点(源码)

2023-03-03 18:54 作者:沐凉JeremyXU  | 我要投稿

#include <iostream>

#include <fstream>

#include "ros/ros.h"

#include "geometry_msgs/Twist.h"

#include "ar_track_alvar_msgs/AlvarMarkers.h"

#include <openCV2/opencv.hpp>  

#include <tf/transform_datatypes.h>

#include <tf/transform_broadcaster.h>

#include <cmath>

#include<ctime>


//#define M_PI 3.1415926;


using namespace std;

using namespace cv;


   

class SubscribeAndPublish  

{  

    public:

        //aruco码ID

        long long ar_ID;


        //aruco码相对相机位置

        double Xc;

        double Yc;

        double Zc;


        //四元数

        double x;

        double y;

        double z;

        double w;


        //判断

        bool already = false;

        int flag = 0;


        //终点坐标

        double Xd;

        double Yd;


        double distance = 1.5;//终点坐标到aruco码距离,单位m

        double Final_Distance; //小车到终点距离


        double Angle_turn;//欧拉角


        double Omiga;//计算角速度

        double Velocity;//计算线速度


        ros::Time Beginning;

        ros::Duration Interval_time;


        SubscribeAndPublish()  

        {  

            pub_ = n_.advertise<geometry_msgs::Twist>("/cmd_vel", 100);  

           

            sub_ = n_.subscribe("/ar_pose_marker", 100, &SubscribeAndPublish::Callback,this);  

        }  


        void Callback(const ar_track_alvar_msgs::AlvarMarkers::ConstPtr& msg)  

        {  

            geometry_msgs::Twist twist;


            if(msg->markers.size() == 0  and already == false)//未找到aruco码,旋转小车寻找aruco码

            {

                twist.angular.z=0.2;

                pub_.publish(twist);

            }

            else

            {

                already = true;

                twist.angular.z = 0;//找到aruco码,停止小车

                pub_.publish(twist);

           

                //读取aruco码相关信息,包括id,pose,orientation

                ar_ID = msg->markers[0].id;


                Xc = msg->markers[0].pose.pose.position.x;

                Yc = msg->markers[0].pose.pose.position.y;

                Zc = msg->markers[0].pose.pose.position.z;


                x = msg->markers[0].pose.pose.orientation.x;

                y = msg->markers[0].pose.pose.orientation.y;

                z = msg->markers[0].pose.pose.orientation.z;

                w = msg->markers[0].pose.pose.orientation.w;

               

                //使小车正对aruco码

                if(Xc < -0.015)

                {

                    twist.angular.z=0.2;

                    pub_.publish(twist);

                }

                else if(Xc > 0.015)

                {

                    twist.angular.z=-0.2;

                    pub_.publish(twist);

                }

                else

                {

                    flag=1;


                    //通过四元数计算小车与aruco码的偏转角度    

                    tf::Quaternion q(x,y,z,w);

                    tf::Matrix3x3 m(q);

                    double roll, pitch, yaw;

                    m.getRPY(roll, pitch, yaw);

                    double getyaw = yaw*180.0/M_PI;

                   

                    //计算目的地坐标及小车与目的地的距离

                    if(getyaw > 0)

                    {

                        double Anger = M_PI - yaw;

                        Xd = Xc + distance*cos(Anger);

                        Yd = Yc + distance*sin(Anger);

                    }

                    else if(getyaw < 0)

                    {

                        double Anger = M_PI + yaw;

                        Xd = Xc + distance*cos(Anger);

                        Yd = Yc - distance*sin(Anger);

                    }

                    Final_Distance = sqrt(Xd*Xd+Yd*Yd);

                }

                //开始计算角度并转向

                if(flag == 1)

                {

                    Angle_turn = atan2(Yd,Xd);//目的地与小车的世界坐标系方位角

                }

                //逆时针转向目标点

                if(Angle_turn >= 95)

                {

                    Omiga = Angle_turn - M_PI / 2;

                    twist.angular.z = 0.2;

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

                    while(Interval_time.toSec() < Omiga+0.5)

                    {

                        pub_.publish(twist);

                        Interval_time = ros::Time::now() - Beginning;

                    }

                    falg = 2;

                }

                //顺时针转向目标点

                else if(Angle_turn <= 85 )

                {

                    Omiga = Angle_turn - M_PI / 2;

                    twist.angular.z = -0.2;

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

                    while(Interval_time.toSec() < Omiga+0.5)

                    {

                        pub_.publish(twist);

                        Interval_time = ros::Time::now() - Beginning;

                    }

                    falg = 2;

                }


             

            }

            //明确方向后开始往目的地前进

            if (flag == 2)

            {

                twist.linear.x = 0.2;

                Velocity = Final_Distance / 0.2;

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

                while(Interval_time.toSec() < Velocity)

                    {

                        pub_.publish(twist);

                        Interval_time = ros::Time::now() - Beginning;

                    }

                    falg = 3;

            }

            //到达目的地后停止小车,任务结束

            if (flag == 3)

            {

                twist.linear.x = 0;

                twist.angular.z =0;

                pub_.publish(twist);

            }  

        }  

     

    private:  

        ros::NodeHandle n_;  

        ros::Publisher pub_;  

        ros::Subscriber sub_;  

};  


   

int main(int argc, char **argv)  

{  

    //初始化  

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

    //定义对象

    SubscribeAndPublish SAPObject;  

    //调用回调函数

    ros::spin();  

     

    return 0;  

}  



项目设计Ⅰ——ROS小车结合aruco码定位到达目标点(源码)的评论 (共 条)

分享到微博请遵守国家法律