首页 > 其他分享 >机器人足球-自动放球

机器人足球-自动放球

时间:2024-06-05 23:57:27浏览次数:25  
标签:gt ball runner 机器人 pos task 足球 放球 dir

策略选择-这部分放在lua层-myball.lua

c++层的内容

lua层

--desc:
Kicker_x = function()
	return COurRole_x("Kicker")
end

Kicker_y = function()
	return COurRole_y("Kicker")
end
R_x = function()
	return COurRole_x("Receiver")
end

R_y = function()
	return COurRole_y("Receiver")
end

--读取txt文件
local function readFile(fileName)
    local f = assert(io.open(fileName,'r'))
    local content = f:read('*all')
    local margin = string.find(content,' ')
    local x = tonumber( string.sub(content,0,margin))
    local y =tonumber( string.sub(content,margin,string.len(content)))
    f:close()
    return x,y
end



r2kdir =function ()
	return COurRole2RoleDir("Receiver","Kicker")
end

Receiverdir = function ()
	return CRole2BallDir("Receiver")
end

gPlayTable.CreatePlay{
	firstState = "choose",
	--先根据距离选择不同的策略
	["choose"]={
		switch=function()
			local posx,posy
			posx,posy=readFile("E:\\work\\SOM\\Team\\user_skills\\target_pos.txt")
			if (CBall2PointDist(posx,posy)<150) then
				return "GetBall1"
			else
				return "GetBall2"
			end
		end,
		Kicker   = task.GotoPos("Kicker",Kicker_x,Kicker_y,0),
		Receiver=task.GotoPos("Receiver",R_x,R_y,Receiverdir),
		Goalie=task.GotoPos("Goalie",1000,1000,0),

	},
	--策略1,直接去拿球,其他不动或离开。
	["GetBall1"] = {
		switch = function()
			
		end,
		
		Kicker   = task.GotoPos("Kicker",Kicker_x,Kicker_y,1.5),
		Receiver=task.ReceiverTask("get_place_ball"),
		Goalie=task.GotoPos("Goalie",1000,1000,0),

	},
	--策略2,一个去踢球,一个准备接球。
	["GetBall2"] = {
		switch = function()
			--判断是否踢球了,本且是否是真踢球,没有获取球速的函数,所以用距离判断是否真踢球
    		if CIsBallKick("Kicker") and CBall2RoleDist("Kicker")>30 then
				return "PlaceBall"
			end
		end,

		Kicker   = task.KickerTask("getball_shoot"),
		Receiver=task.ReceiverTask("Receiver_wait"),
		Goalie=task.GotoPos("Goalie",1000,1000,0),

	},
	--策略2,接到球之后,再放球。
	["PlaceBall"] = {
		switch = function()
			
		end,
		Kicker   = task.GotoPos("Kicker",Kicker_x,Kicker_y,1.5),
		Receiver = task.ReceiverTask("get_place_ball"),
		Goalie=task.GotoPos("Goalie",1000,1000,0),
		
	},
	
name = "myBall"
}

c++层

#include "PlayerTask.h"
#include "worldmodel.h" //相关的全局参量包
#include "maths.h"      // 相关的计算函数包
#include "util.h"       // 相关的有用的工具头文件
#include "constants.h"  // 相关的有用常量
#include <fstream>
#include <iostream>
#include <windows.h>

using namespace std;
extern "C"_declspec(dllexport)PlayerTask player_plan(const WorldModel *model, int robot_id);

namespace
{ //实地测试得出
	float head_len = 7;
	double miss = 11; //越大接球条件越宽松
	float getangle = PI / 20;
#define fast_pass 9
}

bool is_getball(const point2f &ball, const point2f &runner)
{
	//miss参数需要在比赛时实地调试
	bool get_ball = (ball - runner).length() < miss;

	if (get_ball)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//判断朝向角度是否符合
bool is_right_angle(const point2f &passer, float passer_dir, const point2f &target)
{
	float target_to_passer = (target - passer).angle();

	//两个矢量角度之差小于某个值,判断是否可以传球
	bool pass;
	
	pass = fabs(target_to_passer - passer_dir) < 0.4;
	return pass;
}

PlayerTask player_plan(const WorldModel *model, int robot_id)
{
	PlayerTask task;
	const point2f &ball = model->get_ball_pos();
	const point2f &ball_val = model->get_ball_vel();
	const point2f &runner = model->get_our_player_pos(robot_id);
	const point2f &runner_val = model->get_our_player_v(robot_id);
	//ball_totalV球的总速度
	double ball_totalV = sqrt(ball_val.x * ball_val.x + ball_val.y * ball_val.y);


	const point2f& placePos = model->get_place_pos();

	float dir = model->get_our_player_dir(robot_id);


	ifstream inputx("E:\\work\\SOM\\Team\\user_skills\\target_pos.txt", ios::in);
	double x, y;

	inputx >> x >> y;
	//point2f pos = placePos;
	point2f pos(x, y);//目标放球点


	//车到目标点的方向
	float runner_to_pos_dir = (pos - runner).angle();
	float ball_to_pos_dir = (pos - ball).angle();
	float rece_to_ball = (ball - pos).angle();

	//----------------------------球是否到目标点(距离小于7),并且速度小于40,没到就执行一大堆拿球和放球-----------
	if ((ball - pos).length() < 7 && ball_totalV < 40 )
	{
		task.needCb = false;//关闭吸球
		Sleep(50);//延迟一下,为了彻底关闭吸球,防止电机停止的比较慢
		task.orientate = dir;//角度不变
		//是否已经退出球的范围区,如果距离小于30,就一点一点退出,否则停止
		if (runner.dist(pos) < 30){
			task.target_pos = runner + Maths::vector2polar(-10, runner_to_pos_dir);
		}
		else{
			task.target_pos = runner;
		}
	}
	else
	{
		//是否拿到球,并且朝向目标位置方向(防止运球时会掉球)
		if (is_getball(ball, runner) && is_right_angle(runner, dir, pos))
		{
			//-----------------------开始运球到点--------------
			//一点一点移动,move_buff来修改,先走的快后走的慢
			double move_buff = 5;
			if ((ball - pos).length() < 15){ 
				move_buff = 1; 
			}
			else if ((ball - pos).length() < 80){
				move_buff = 10;
			}
			else{
				move_buff = 15;
			}
			task.orientate = ball_to_pos_dir;
			task.needCb = true;
			task.target_pos = runner + Maths::vector2polar(move_buff, ball_to_pos_dir);
		}
		//没有拿到球,或者朝向目标不对
		else{
			//-----------------------------控制角度部分---------------------------------
			//拿到球就开始转到目标朝向
			if (is_getball(ball, runner))
			{

				//--------------根据球的位置决定转球方向----------------------
				//buff控制转动快慢,buff可以改变
				float buff = 0.4;
				if (abs(dir - runner_to_pos_dir) < PI / 6)
				{
					buff = 0.1;
				}
				if (abs(dir - runner_to_pos_dir) < PI / 7)
				{
					buff = 0.05;
				}
				//buff取负号来判断不同情况
				if (dir < runner_to_pos_dir)
				{
					buff = -buff;
				}
				//向左转或右转
				if (abs(dir - runner_to_pos_dir) < PI)
				{
					task.orientate = dir - buff;
				}
				else
				{
					task.orientate = dir + buff;
				}

				//--------------------------转球结束--------------------
			}
			//没拿到球,就朝向球的方向
			else
			{
				task.orientate = (ball - runner).angle();
			}
			//task.target_pos = runner;
			task.needCb = true;

			//----------------以下开始为控制跑点位置--------------------

			//拿到球并且朝向有大问题,就开始原地旋转,防止小球掉落
			if (is_getball(ball, runner) && is_right_angle(runner, dir, pos) == false)
			{
				task.target_pos = runner;
			}
			else if (is_getball(ball,runner)){
				//拿到球并且角度没问题,这里不处理,因为上面已经处理过了
			}
			else
			{
				//计算出球运动方向和小车最短距离的交点。
				double k = ball_val.y / ball_val.x;
				double target_x = (runner.x / k + runner.y + k*ball.x - ball.y) / (k + 1 / k);
				double target_y = ball_val.y / ball_val.x*(target_x - ball.x) + ball.y;

				//------------------------------根据球速来控制跑点位置----------------------------
				//球速小于100时,直接去拿球
				if (ball_totalV < 60)
				{
					if ((ball - runner).length()<50){
						task.target_pos = runner + Maths::vector2polar((ball - runner).length()*0.6, (ball - runner).angle());
					}
					else{
						task.target_pos = ball;
					}
				} //球速大于100时,前往球的位置,加上球速*0.5在球运动方向上的偏移
				else if (ball_totalV > 400)
				{
						task.target_pos.x = target_x;
						task.target_pos.y = target_y;
				}
				else
				{
					point2f new_target = ball + Maths::vector2polar(ball_totalV * 0.1, ball_val.angle());
					task.target_pos.x = target_x;
					task.target_pos.y = target_y;
				}
			}
		}
	}
	


	return task;
}

#include "PlayerTask.h"
#include "worldmodel.h" //相关的全局参量包
#include "maths.h"      // 相关的计算函数包
#include "util.h"       // 相关的有用的工具头文件
#include "constants.h"  // 相关的有用常量
#include <fstream>
#include <iostream>
#include <windows.h>

using namespace std;
extern "C"_declspec(dllexport)PlayerTask player_plan(const WorldModel *model, int robot_id);

namespace
{ //实地测试得出
	float head_len = 7;
	double miss = 11; //越大接球条件越宽松
	float getangle = PI / 20;
#define fast_pass 9
}

bool is_getball(const point2f &ball, const point2f &runner)
{
	//miss参数需要在比赛时实地调试
	bool get_ball = (ball - runner).length() < miss;

	if (get_ball)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//判断朝向角度是否符合
bool is_right_angle(const point2f &passer, float passer_dir, const point2f &target,const double receiver_val)
{
	float target_to_passer = (target - passer).angle();

	//两个矢量角度之差小于某个值,判断是否可以传球,并且小车基本不移动,就说明准备好了。
	bool pass;
	pass = fabs(target_to_passer - passer_dir) < 0.07 && receiver_val<20;
	return pass;
}

PlayerTask player_plan(const WorldModel *model, int robot_id)
{
	PlayerTask task;
	const point2f &ball = model->get_ball_pos();
	const point2f &ball_val = model->get_ball_vel();
	//const point2f  ball(0,200);
	const point2f &runner = model->get_our_player_pos(robot_id);
	//const point2f &receiver = model->get_our_player_pos(1);
	const point2f &runner_val = model->get_our_player_v(robot_id);
	//const point2f &receiver_val = model->get_our_player_v(1);
	//ball_totalV球的总速度
	double ball_totalV = sqrt(ball_val.x * ball_val.x + ball_val.y * ball_val.y);

	const int get_buff = 100;
	float dir = model->get_our_player_dir(robot_id);


	ifstream inputx("E:\\work\\SOM\\Team\\user_skills\\target_pos.txt", ios::in);
	double x, y;

	inputx >> x >> y;
	//point2f pos1(x, y);(-100,0)
	point2f post(x, y);//目标放球点
	//point2f post = model->get_place_pos();
	double min = 10000;
	//拿到接球人的id给receiver,遍历场上所有的车,寻找
	const bool* exist_id = model->get_our_exist_id();
	int receiverid;
	for (int i = 0; i <= MAX_ROBOTS; i++){
		if (exist_id[i]){
			if (i != robot_id){
				const point2f &temp = model->get_our_player_pos(i);
				if (temp.dist(post) < min){
					min = temp.dist(post);
					receiverid = i;
				}
			}
		}
	}

	const point2f &receiver = model->get_our_player_pos(receiverid);
	const point2f &receiver_val = model->get_our_player_v(receiverid);
	const double receiver_tval = sqrt(pow(receiver_val.x, 2) + pow(receiver_val.y, 2));


	point2f pos = receiver;//目标踢球点

	//车到目标点的方向
	float runner_to_pos_dir = (pos - runner).angle();
	float ball_to_pos_dir = (pos - ball).angle();
	//以下参数由测试得出
	float rece_to_ball = (ball - pos).angle();


	//是否拿到球,并且朝向目标位置,并且另一辆小车基本不动了。
	if (is_getball(ball, runner) && is_right_angle(runner, dir, pos, receiver_tval))
		{
			task.orientate = dir;
			//-----------------------开始踢球--------------

			task.needKick = true;

			task.orientate = dir;
			task.flag = 0;

			//射球力度根据测试修改
			double k = 0.03;
			if (receiver.dist(runner) > 450){
				k = 0.01;
			}
			task.kickPower = k*receiver.dist(runner);

		}
		else{
			//-----------------------------控制角度部分---------------------------------
			if (is_getball(ball, runner))
			{

				//--------------根据球的位置决定转球方向----------------------

				
				//buff控制转动快慢,buff可以改变
				float buff = 0.4;
				if (abs(dir - runner_to_pos_dir) < PI / 6)
				{
					buff = 0.1;
				}
				if (abs(dir - runner_to_pos_dir) < PI / 7)
				{
					buff = 0.05;
				}
				//buff取负号来判断不同情况
				if (dir < runner_to_pos_dir)
				{
					buff = -buff;
				}
				//向左转或右转
				if (abs(dir - runner_to_pos_dir) < PI)
				{
					task.orientate = dir - buff;
				}
				else
				{
					task.orientate = dir + buff;
				}

				//--------------------------转球结束--------------------
			}
			else
			{
				task.orientate = (ball - runner).angle();
			}
			task.needCb = true;

			//----------------以下开始为控制跑点位置--------------------

			//拿到球并且朝向有大问题,就开始原地旋转,防止小球掉落
			if (is_getball(ball, runner) && is_right_angle(runner, dir, pos, receiver_tval) == false)
			{
				task.target_pos = runner;
			}
			else if (is_getball(ball, runner)){
				//拿到球并且角度没问题,这里不处理,因为上面已经处理过了
			}
			else
			{
				//------------------------------根据球速来控制跑点位置----------------------------
				//球速小于100时,直接去拿球
				if (ball_totalV < 100)
				{
					if ((ball - runner).length()<50){
						task.target_pos = runner + Maths::vector2polar((ball - runner).length()*0.6, (ball - runner).angle());
					}
					else{
						task.target_pos = ball;
					}
				} //球速大于100时,前往球的位置,加上球速*0.5在球运动方向上的偏移
				else if (ball_totalV > 400)
				{
					task.target_pos = ball + Maths::vector2polar(ball_totalV * 2, ball_val.angle());
				}
				else
				{
					task.target_pos = ball + Maths::vector2polar(ball_totalV * 0.5, ball_val.angle());
				}
			}
		}
	return task;
}


Receiver_wait.cpp

#include "PlayerTask.h"
#include "worldmodel.h" //相关的全局参量包
#include "maths.h"      // 相关的计算函数包
#include "util.h"       // 相关的有用的工具头文件
#include "constants.h"  // 相关的有用常量
#include <fstream>
#include <iostream>
#include <windows.h>

using namespace std;
extern "C"_declspec(dllexport)PlayerTask player_plan(const WorldModel *model, int robot_id);



PlayerTask player_plan(const WorldModel *model, int robot_id)
{
	PlayerTask task;
	const point2f &ball = model->get_ball_pos();
	const point2f &ball_val = model->get_ball_vel();
	const point2f &runner = model->get_our_player_pos(robot_id);

	float dir = model->get_our_player_dir(robot_id);

	ifstream inputx("E:\\work\\SOM\\Team\\user_skills\\target_pos.txt", ios::in);
	double x, y;

	inputx >> x >> y;
	point2f pos(x, y);//目标放球点
	//point2f pos = model->get_place_pos();
	//point2f pos1(300, -20);


	float ball_to_pos_dir = (pos - ball).angle();


	//车在目标点的位置上,再后退一定距离。朝向小球的方向
	task.target_pos = pos + Maths::vector2polar(-35, ball_to_pos_dir);
	task.orientate = (ball - runner).angle();
	
	
	return task;
}

标签:gt,ball,runner,机器人,pos,task,足球,放球,dir
From: https://www.cnblogs.com/darkarc/p/18234176

相关文章

  • 钉钉机器人远程重启系统服务
    fromflaskimportFlask,requestimportsubprocessapp=Flask(__name__)@app.route('/send_message',methods=['GET'])defsend_message():webhook_url='https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN'#......
  • 【杂谈】AIGC之ChatGPT-与智能对话机器人的奇妙对话之旅
    与智能对话机器人的奇妙对话之旅引言在数字时代的浪潮中,ChatGPT如同一位智慧的旅伴,它不仅能够与我们畅谈古今,还能解答我们的疑惑,成为我们探索知识海洋的得力助手。今天,就让我们走进ChatGPT的世界,一探这位智能对话机器人的奥秘。起源:ChatGPT的诞生ChatGPT的诞生,可以追溯......
  • 六足机器人运动学
    文章目录前言六足机器人运动学分析1.正运动学2.逆运动学3.MATLAB验证正逆解代码前言六足机器人运动学六足机器人运动学分析六足机器人运动学分析就是将空间直角坐标系建立再机器人腿部的关节上将腿部各关节之间的间距,关节的夹角进行关系转换,求解其位置......
  • 第三届机器人、人工智能与信息工程国际学术会议(RAIIE 2024)
    【ACM独立出版/Fellow大咖云集】2024年第二届机器人、人工智能与信息工程国际学术会议(RAIIE2024)20243rdInternationalSymposiumonRobotics,ArtificialIntelligenceandInformationEngineering大会官网:https://ais.cn/u/juURra大会时间:2024年07月05-07日大会地点:新......
  • 基于SpringBoot+Vue的足球社区管理系统(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • springboot的设计与实现(文档+源码)足球青训俱乐部管理后台系统
    大家好,我是永钊,一个混迹在java圈的码农,今天要和大家聊的是一款基于springboot的足球青训俱乐部管理后台系统,项目源码请联系永钊,目前有各类成品毕设javawebsshssmspringboot等等项目框架,源码丰富,欢迎咨询。 本网站系统重点阐述了足球青训俱乐部管理后台系统的开发过程,......
  • 自动移动机器人(AMR)技术详解
    自动移动机器人(AMR)技术是一种复杂的集成系统,它结合了多种技术来实现自主导航、感知环境和执行任务。以下是AMR技术的一些关键组件和功能:导航系统:定位技术:AMR通常使用GPS(在户外)和室内定位技术(如Wi-Fi、蓝牙、UWB或激光雷达SLAM)来确定其位置。路径规划:基于A*算法、Dijkstra......
  • 【JPCS出版|EI检索|最后一轮征稿】2024年机器人、自动化和控制工程国际会议(ICRACE 2024)
    2024年机器人、自动化和控制工程国际会议(ICRACE2024)会议官网:www.ic-race.org会议时间:2024年07月12-14日会议地点:中国-南京最终截稿时间:2024年6月28日报名截止时间:2024年7月05日征稿中(详情可与会务组老师联系)审稿回复时间:投稿后1周内提交检索类型:EICompendex,Scopus......
  • tg机器人怎么做简单:快速上手tg机器人制作的简易指南
    对于初学者来说,制作一个TG机器人可能会显得有些复杂。但是,只要掌握了一些基本的步骤和技巧,你就可以轻松地上手并制作出属于自己的TG机器人。本文将为你提供一个简易的指南。一、明确需求在开始制作机器人之前,你需要明确你的需求。专属定制前往TG&broang,&改成@即可打造你的完......
  • TG机器人功能定制全攻略
    一、引言TG机器人作为TG平台上的一种智能工具,其功能的多样性决定了其应用的广泛性。本文将为您详细介绍如何根据实际需求为TG机器人定制功能,帮助您打造一个满足特定需求的智能助手。二、需求分析在开始定制TG机器人功能之前,首先需要进行需求分析。定制机器人可通过TG#broang......