合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释

2023-05-16

第三次作业

题目:已知2个点的信息,定位自己的绝对坐标。

 

设图中C(0,0),P1(-52.5,-32), P2(-52.5, 32), P3(52.5,32), P4(52.5,-32), P5(0,-32), P6(0,32), P7(-30,-7), P8(-30, 7), P9(30,7), P10(30, -7),G1(-52.5,0),G2(52.5,0)

随机得到附近2点距离自己的信息(r,theta), r表示目标点距离自己的距离,theta表示以自己中心的极角.(顺时针(0,180),逆时针(0,-180)。计算自己的位置。

输入示例:(P8 22 0) (P7 27.7 30)   

求出机器人在场上的绝对位置。

  px=-8.2,py=10.14

如果是输入为

(P8 22 0) (P7 10.4 30)   

(P8 14 -30) (P7 14 30) 

则计算结果是什么?

注意: 角度是目标相对于身体的角度,server发给agent的相对角度的值是视野估算的,是很大误差的,所以用来确定自己位置的大概范围,不能用来参与计算。   

首先我们根据题目可以分析,角度是不能用来计算的,所以只能使用距离来计算,但是我们只知道两个目标点和分别到这两个目标点的距离怎么才能求出自己的位置呢?

相信有聪明的同学就知道了,以目标点为圆心做圆,两个圆的交点处即为我所在的位置。

但是这又迎来一个新的问题,两个圆有交点除了相切一个交点和重合无数个交点以外,都是两个交点,这样我们又如何才能知道自己的位置是在哪个交点处呢?

这就需要用到我们之前不用多的角度了,角度是以我面朝方向为基准的相对角度,所以跟球场上的绝对角度不一样,所以我们需要经过一点处理才能使用这个角度。

用第一个点的角度减去第二个点的角度,这样我们就能得到两个点在我视野内的角度差(注意这个是有正负的,正表示面朝第二个点时顺时针才能转到第一个点,负则相反)。

然后我们要根据已知两点的坐标求两点相对于我可能在的两个交点的绝对角度,然后两个绝对角度相减就能得到两个相对角度,两个相对角度与前面题目已知求出来的相对角度对比,由于有误差,所以我们不能用等于来判断,而是在几度的误差内就判定为相等。

这是绝对坐标的坐标系图

 

 

 

代码我跟以前一样在关键地方写了注释,所以大家观看应该不是问题

import re
import math


class Point:
    """
    坐标点类,用于封装坐标点,并且提供两点之间的坐标和两点之间的绝对角度
    """
    def __init__(self, x=0, y=0):
        self.__x = x
        self.__y = y
        pass

    def __str__(self):
        return "("+str(self.__x)+","+str(self.__y)+")"

    def get_x(self):
        return self.__x

    def get_y(self):
        return self.__y

    def get_distance(self, point):
        result = ((self.__x - point.get_x())**2+(self.__y - point.get_y())**2)**0.5
        return result

    def azimuthangle(self,point):
        """
        求出对象与点point的绝对角度,水平向右为0顺时针为正,角度范围0-360
        :param point:
        :return:
        """
        x1, y1, x2, y2 = self.__x, self.__y, point.get_x(), point.get_y()
        angle = 0.0
        dx = x2 - x1
        dy = y2 - y1
        if x2 == x1:
            angle = math.pi / 2.0
            if y2 == y1:
                angle = 0.0
            elif y2 < y1:
                angle = 3.0 * math.pi / 2.0
        elif x2 > x1 and y2 > y1:
            angle = math.atan(dx / dy)
        elif x2 > x1 and y2 < y1:
            angle = math.pi / 2 + math.atan(-dy / dx)
        elif x2 < x1 and y2 < y1:
            angle = math.pi + math.atan(dx / dy)
        elif x2 < x1 and y2 > y1:
            angle = 3.0 * math.pi / 2.0 + math.atan(dy / -dx)
        return angle * 180 / math.pi

    pass


# 所有标志点组成一个字典,方便后续使用
flag = {
'c' : Point(0,0),
'P1' : Point(-52.5,-32),
'P2' : Point(-52.5, 32),
'P3' : Point(52.5,32),
'P4' : Point(52.5,-32),
'P5' : Point(0,-32),
'P6' : Point(0,32),
'P7' : Point(-30,-7),
'P8' : Point(-30, 7),
'P9' : Point(30,7),
'P10' : Point(30, -7),
'G1' : Point(-52.5,0),
'G2' : Point(52.5,0),
}


class Robot:
    """
    简单封装一个机器人类,用于输出结果
    """
    def __init__(self):
        self.point = Point()
        pass

    def __str__(self):
        return "我在场上的绝对位置为:" + str(self.point)

    def get_position(self, s):
        print("输入:"+s)
        point = decode_point(s)
        self.point = point[0]
        return point

    pass


class Circle:
    def __init__(self,point, r):
        """
        园的一般式(x-x0)^2+(y-y0)^2=r^2
        :param point:圆心坐标
        :param r:
        """
        self.point = point
        self.__r = float(r)
        pass

    def __str__(self):
        return "圆心"+str(self.point)+"半径"+str(self.__r)      # 返回基本信息

    def get_center(self):
        return self.point

    def get_r(self):
        return self.__r

    def get_point(self, cir, angle):
        """
        用于求取两个圆之间的交点
        :param cir: 要求交点的圆
        :param angle: 后续取舍交点要用的角度
        :return: 满足条件的点
        """
        center_1, center_2 = self.point, cir.get_center()                          # 获取两个圆的圆心坐标点
        cros_point_1, cros_point_2 = Point(-100, -100), Point(-100, -100)          # 初始化两个要返回的坐标点
        r_1, r_2 = self.__r, cir.get_r()                                           # 获取两个圆的半径
        x1, y1, x2, y2 = center_1.get_x(), center_1.get_y(), center_2.get_x(), center_2.get_y()  # 将坐标拆开方便使用
        center_dis = center_1.get_distance(center_2)                                # 获取两圆心之间的距离
        # print("距离:",center_dis, center_1,center_2, r_1-r_2)
        if center_dis < 1e-6:                                               # 当两圆心的距离小于1e-6时可近似看成重合
            # print("两圆重合!")
            pass
        elif center_dis > r_1 + r_2 or center_dis < max(r_1, r_2) - min(r_1, r_2):      # 当距离小于两圆半径差或者大于半径和时不存在交点
            # print("无交点!")
            pass
        else:                           # 有交点的情况
            # print("有交点")
            AE = (center_dis ** 2 + r_1 ** 2 - r_2 ** 2) / (2 * center_dis)         # 圆1到圆心连线与垂线交点的距离
            x0 = x2 + (x1 - x2) * AE / center_dis                                   # 该交点的横坐标
            y0 = y2 + (y1 - y2) * AE / center_dis                                   # 该交点的纵坐标
            CE = (r_1 ** 2 - AE ** 2) ** 0.5                                        # 两圆交点到该交点的距离
            if 1e-6 > x1 - x2 > -1e-6:                                              # 近似看成相等,此时两标志物垂直
                cros_x_1, cros_x_2 = x1 + CE, x1 - CE
                cros_y_1, cros_y_2 = y1 + AE, y1 + AE
            elif 1e-6 > y1 - y2 > 1e-6:                                             # 近似看成相等,此时两标志物水平
                cros_x_1, cros_x_2 = x1 + AE, x1 + AE
                cros_y_1, cros_y_2 = y1 + CE, y1 - CE
            else:                                                                   # 此时两标志点所在直线倾斜
                k1 = (y1 - y2) / (x1 - x2)                                          # 圆心连线斜率
                k2 = -1 / k1                                                        # 圆交点与圆心和垂线交点的斜率
                cos = (1 / (k2**2 + 1))**0.5                                        # 将斜率转化为cos
                sin = k2 * cos                                                      # 将斜率转化为sin
                cros_x_1, cros_x_2 = x0 + CE*cos, x0 - CE*cos                       # 求出两圆的交点x坐标
                cros_y_1, cros_y_2 = y0 + CE*sin, y0 - CE*sin                       # 求出交点y坐标
                pass
            # print(cros_point_1, cros_point_2)
            if 32 > cros_y_1 > -32 and 52.5 > cros_x_1 > -52.5:                     # 判断交点在不在场内
                cros_point_1 = Point(cros_x_1, cros_y_1)                            # 打包交点
                # 求出交点从第一个标志点到第二个标志点转过的角度,正表示逆时针转动,负表示顺时针转动
                ang =  cros_point_1.azimuthangle(cir.get_center()) - cros_point_1.azimuthangle(self.point)
                a = ang - angle                                                      # 求出程序所得的角度与题目所给的角度的差值
                # print(a, ang,angle,cros_point_1)
                if not 2 > a > -2:                                                  # 角度差值在2度以内就算重合
                    cros_point_1 = Point(100,100)                                   # 不满足条件就弃用该点
            if 32 > cros_y_2 > -32 and 52.5 > cros_x_2 > -52.5:                     # 同理
                cros_point_2 = Point(cros_x_2, cros_y_2)
                ang = cros_point_2.azimuthangle(cir.get_center()) - cros_point_2.azimuthangle(self.point)
                a = ang - angle
                # print(a, ang,angle, cros_point_2)
                if not 2 > a > -2:
                    cros_point_2 = Point(100,100)
                pass

        return cros_point_1, cros_point_2                                               # 返回所求的两个交点
    pass



def decode_point(msg):
    points = list()                           # 用来存放求出的所有交点
    tmp = re.findall(r'[(](.*?)[)]',msg)       # 正则匹配括号内的内容
    cirs = list()                              # 用于存放构造的所有圆
    angle = list()                             # 用于存放机器人到每个标志点的相对角度
    for item in tmp:
        info = item.split()     # info为解析后的标志点的信息,依次为标志点名字,标志点的角度(弃用),标志点与我的距离
        angle.append(float(info[2]))                    # 角度信息保存
        cirs.append(Circle(flag[info[0]], info[1]))     # 以标志点为中心,与我的距离为半径做圆

    for c1 in cirs:                             # 遍历圆
        for c2 in cirs:                         # 再遍历圆
            if c1 is not c2:                    # 如果不是同一个圆,就计算交点
                ang = angle[cirs.index(c1)] - angle[cirs.index(c2)]  # 计算第一个标志点到第二个标志点的角度
                point = c1.get_point(c2, ang)   # 得到的交点
                for p in point:
                    if 32 > p.get_y() > -32 and 52.5 > p.get_x() > -52.5:  # 如果在圆内,就添加到点中
                        points.append(p)        # 不出意外只有一个点,如果有多个标志位可能会有一点小误差,所以需要把所有满足条件的点都添加进去

    # for p in points:
    #     print(p)
    return points   # 返回所有满足条件的点


if __name__ == '__main__':
    robot = Robot()                     # 创建一个机器人对象用来调用函数和输出结果。
    s_1 = '(P8 22 0) (P7 27.7 30)'      # 测试用例
    s_2 = '(P8 22 0) (P7 10.4 30)'
    s_3 = '(P8 14 -30) (P7 14 30)'
    robot.get_position(s_1)             # 直接调用封装好的函数获取坐标
    print(robot)                        # 输出绝对坐标

没啦,这一次不是临时写的,没有bug啦,而且这个代码还可以处理输入为四个点的数据哦,求出来多个我的位置,但是为了方便(懒得继续搞),我只取了第一个为我的位置,大家可以找例子试试(求出来的位置会有一点误差是很正常的哦,老师说这个本来就不是很准确),我这里就不给大家演示了。

还是那句话,学以致用才是真正的学到了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释 的相关文章

  • 安装Pytorch时出现ERROR: Could not find a version that satisfies the requirement...的解决方法

    一 问题描述 当我们创建了一个虚拟环境 xff0c 在环境中使用pip命令安装Pytorch时经常会出现以下错误 xff1a 二 解决方法 下面罗列几种有用的解决方法 xff1a 1 切换网络 出现这种问题很可能是因为网络太卡导致无法从该路
  • 使用Rviz完成摄像头(camera)的视频采集

    文章目录 一 准备摄像头二 使用Rviz三 Rviz显示摄像头 一 准备摄像头 1 找到虚拟机设置 xff0c 将USB设置为3 1 2 连接摄像头 3 连接成功如下 4 检查能否使用 使用cheese命令 二 使用Rviz 1 启动Rvi
  • SAM-Segment Anything Model进行单张图片的检测记录

    一 代码和模型下载 下载链接 GitHub facebookresearch segment anything 将代码下载并解压到一个没有中文的路径下 页面往下滑找到需要下载的模型 nbsp 这里提供了三个模型 vit b的大小是358m
  • Segment Anything(SAM)全图分割做mask

    项目的源码和模型下载以及环境配置等可参考我的上一篇文章 xff0c 这里不再赘述 文章链接 xff1a https blog csdn net m0 63604019 article details 130221434 在项目中创建一个名为
  • labelme的使用学习

    windows下图像标注软件labelme安装及使用教程 xff1a https www rstk cn news 12836 html action 61 onClick 问题 xff1a 如何将labelme标注产生的json文件中的某
  • Unet做分割的详细步骤

    参考文章 xff1a https blog csdn net ECHOSON article details 122914826 我是参考上面这个文章来做的 xff0c 但是在做实验的过程中还是出现了很多问题 xff0c 所以这里还是自己写
  • Java语法之多态

    上次给大家分享了Java的继承 xff0c 今天小编给大家分享面向对象三大特性的第三大特性 xff0c 也就是多态 xff0c fighting 目录 x1f388 一 多态 x1f388 1 1多态的概念 x1f388 1 2多态的实现条
  • 实现调度器

    实现调度器 调度器是操作系统的核心 xff0c 其主要功能就是实现任务的切换 xff0c 即从就绪列表里面找到优先级最高的任务 xff0c 然后去执行该任务 1 启动调度器 xff08 1 xff09 void vTaskStartSche
  • 任务相关知识

    任务管理 从系统的角度来看 xff0c 任务是竞争系统资源的最小运行单元 在任何时刻 xff0c 只有一个任务得到运行 xff0c 每个任务都在自己的环境中运行 xff0c 而这个运行的任务由FreeRTOS的调度器决定 FreeRTOS
  • 串口打印中文乱码及注释乱码问题

    1 使用keil5代码注释出现中文乱码问题 在使用keil5中出现如下问题 xff1a 这时候的解决方法是在keil5顶头工具栏上进入 xff1a Edit Configuration xff0c 如下然后进行选择GB2312编码方式 xf
  • keil5中安装Arm Compiler 5.06问题

    keil5 5 7版本中安装Arm Compiler 5 06问题 在最新的keil5 7版本中不再默认安装Arm Compiler 5 06编译器 xff0c 所以此版本需要自己独立下载并进行安装 具体步骤如下 xff1a 1 官网下载A
  • 五、FreeRTOS中任务控制块(TCB)、任务句柄和内核对象句柄

    文章目录 1 什么是任务控制块 xff1f 2 任务控制块的内容3 什么是任务句柄 xff1f 4 什么是内核对象句柄 xff1f 1 什么是任务控制块 xff1f 任务控制块实际上就是一个结构体 在FreeRTOS中 xff0c 系统为了
  • 凸优化基础知识

    文章目录 一 学习任务二 学习内容1 计算几何1 1 计算几何 的定义1 2 直线表达 2 凸集2 1 定义2 2 平面表达2 3 超平面表达 3 凸函数3 1 定义3 2 Hessian Matrix 矩阵3 3 判别 4 凸规划4 1
  • 八、任务的创建与删除

    文章目录 1 任务的三要素 xff1a 主体函数 任务栈 任务控制块 2 与任务相关的部分API函数 xff08 1 xff09 xTaskCreate xff08 2 xff09 void vTaskDelete TaskHandle t
  • 三、STM32中systick中断的优先级

    1 systick中断的优先级 systick为内核外设中断 xff0c 与普通外设中断的优先级有些区别 xff0c 并没有抢占优先级和子优先级的说法 对于M3来说内核外设的中断优先级由内核SCB这个外设的寄存器 xff1a SHPRx x
  • 二十、事件组

    文章目录 1 基本概念2 使用场景 xff1a 用于任务间 任务和中断间的同步 xff08 非数据传输 xff09 3 事件组结构体 xff08 事件控制块 xff09 内容解析4 为什么采用的是关闭调度器而不是关闭中断 xff1f 5 创
  • 3、如何使用GDB来进行命令行debug

    文章目录 一 与前面的联系二 GDB的一些认识1 什么是gdb2 gdb作用3 gdb可实现的功能 三 GDB常用的调试命令 一 与前面的联系 对于前面说到的launch json文件就是用于debug的配置文件 xff0c 在前面的vsc
  • 1、vscode搭建C++开发环境及一些配置文件的含义

    文章目录 一 vscode搭建开发环境1 下载和配置MinGW w64 编译器套件2 安装到电脑中3 配置环境变量4 测试是否安装成功5 vscode上安装C C 43 43 插件 二 配置编译环境时各个文件的含义1 task json x
  • 5、cmake的简单认识及CMakeLists.txt的编写语法

    文章目录 1 cmake是什么 xff08 1 xff09 cmake的两大功能 2 CMakeLists txt常用命令 xff08 即如何编写CMakeLists txt文件 xff09 xff08 1 xff09 cmake常见预定义
  • 6、在vscode上利用cmake创建第一个简单C++程序

    文章目录 xff08 1 xff09 前期准备工作 xff1a 即安装对应的环境1 xff09 在vscode上安装插件 xff1a C C 43 43 Cmake CMake tools2 xff09 安装Cmake环境 xff08 这是

随机推荐

  • 7、在vscode上利用cmake构建多文件C++工程

    文章目录 xff08 1 xff09 创建如下工程文件夹 xff1a 其中头文件放在include文件夹中 xff0c 源文件放在src文件夹中 xff08 2 xff09 在vscode上打开工程文件夹 xff0c 在对应的文件夹内建立相
  • js实现猜数字游戏

    随机输入两个数min 和max 在两个数中间生成一个随机数 进行猜数字游戏 且有猜的次数限制 1 不限制次数版本 function getRandom min max return Math floor Math random max mi
  • ubuntu更换阿里云镜像源操作步骤

    过程较为复杂 xff0c 能清楚自己改了镜像源 xff0c 避免了忘记或备份等 修改下载 xff08 镜像源 xff09 源 输入 xff1a sudo nano etc apt sources list 2 将所有deb 后的网址http
  • CSRF攻击原理与防御方法

    文章目录 CSRF概念CSRF攻击攻击原理及过程CSRF漏洞检测防御CSRF攻击1 验证 HTTP Referer 字段2 在请求地址中添加 token 并验证3 在 HTTP 头中自定义属性并验证 CSRF概念 CSRF跨站点请求伪造 C
  • Windows11安装Linux子系统(Ubuntu22.04LTS)+安装ROS

    目录 一 准备工作 二 安装Ubuntu 22 04 1 LTS 三 启动Ubuntu遇到的报错及解决方案 四 换源 五 安装ROS 设置编码 添加源 安装ROS 设置环境变量 测试 一 准备工作 控制面板 程序 程序和功能 启动或关闭 W
  • 如何在Github上建立自己的个人博客网站详细教程

    概述 之前闲着没事 就利用Github建了一个个人博客网站 效果还不错 今天就来分享一下 建立自己个人博客网站的好处 1 面试装逼 这个不必多说 2 把平时积累的知识和项目记录下来 方便日后查看使用 3 不受其他博客平台的限制 准备工作 开
  • 看野火的视频,用正点原子的板子(STM32F4探索者)做系统定时器实验

    1 实验目的 编写一个毫秒级的延时函数 xff0c 控制LED的亮灭 这里的灯是LED1 xff0c 端口是GPIOF xff0c 引脚是PIN10 2 实验流程 2 1 准备知识 SysTick 系统定时器 xff0c 24位 xff0c
  • 用正点原子的板子(STM32F4探索者)做PWM 输出实验

    1 实验目的 使用 TIM14 的通道 1 来产生 PWM 控制 LED0 DS0 的亮度 2 实验准备和流程 由上图可以看出 xff0c GPIOF9引脚对应的是定时器TIM14的通道1 由上图可以看出 xff0c GPIOF9引脚对应的
  • MATLAB快速入门(二):矩阵

    矩阵 目录 矩阵 1 冒号表达式 2 矩阵元素的引用 3 矩阵的运算 3 1算术运算 3 2逻辑运算 4 特殊矩阵 5 矩阵变换 5 1对角阵 5 2三角阵 5 3矩阵旋转 5 4稀疏矩阵 6 矩阵求值 1 冒号表达式 e1 e2 e3 省
  • toString方法使用

    一 Object类中toString的作用 1 在主方法中我们可以直接用toString 输出对象其中的内容 2 我们需要直接输出对象中所属内容时 xff0c 直接使用toString 方法输出语句 xff0c 输出内容不友好 xff0c
  • px4+mavros+offboard控制+gazebo仿真以及与pixhawk4飞控连接(一)

    记录一下自己从px4到板载控制的一系列流程以及踩坑过程 xff0c 希望也可以帮助大家避雷 话不多说直接上干货 一 软 硬件平台 px4版本 xff1a 1 10 1 飞控板 xff1a pixhawk4 ros版本 xff1a melod
  • 浅谈穿越机飞控如何烧写固件及其相关设置问题

    背景 xff1a 自己本人是无人机爱好者对穿越机也较为痴迷 xff0c 在使用DJI FPV天空端时发现无法显示OSD信息 xff0c 同时在眼镜端的OSD开关已经打开 xff0c 查阅相关资料发现自己的飞控版本过低需要烧写到4 1 0以上
  • XSS攻击原理及防范

    文章目录 一 XSS攻击简介二 XSS攻击分类1 反射型2 存储型3 DOM based型 三 XSS防范1 cookie安全策略2 X XSS Protection设置3 XSS防御HTML编码4 XSS 防御HTML Attribute
  • Jetson Xavier NX安装librealsense

    在nx上安装librealsense可以使用由jetsonhacks开源的安装脚本installRealSenseSDK 克隆仓库 xff0c 进入目录 git clone https github com jetsonhacks inst
  • Kubernetes(K8s)的简介及基础知识

    1 关于Kubernetes xff08 K8s xff09 的简介 Kubernetes xff0c 简称又叫K8s xff0c 为什么简称要叫K8s xff0c 据说是因为Kubernetes单词中K字母和S字母之间相隔8个字母 xff
  • 爬虫实战(三)

    随着互联网的不断发展 xff0c 网络数据的规模和价值也不断提升 在这个大数据时代 xff0c 如何从海量数据中提取有价值的信息并加以利用 xff0c 成为了数据科学 商业分析 金融预测 社会研究等领域中一个重要的问题 而网络爬虫作为一种数
  • 数据库连接

    一 连接数据库的方法和工具 数据库连接是访问数据库的关键步骤之一 xff0c 通过连接数据库 xff0c 我们可以进行数据的增删改查等操作 下面介绍几种连接数据库的方法和工具 命令行工具 在命令行中输入相应的命令即可连接数据库 常用的命令行
  • C语言之十进制转化为十六进制

    作者 xff1a 从未止步 博客主页 xff1a 从未止步的博客 专栏 xff1a 和我一起学C 语录 xff1a Every day is a second chance 行动是理想最高贵的表达 xff0c 给大家介绍一款超牛的斩获大厂o
  • 合肥工业大学机器人足球仿真robcup作业二(python实现)附代码有注释

    用面向对象的思维设计相关类 xff0c 从而实现直线与直线 直线与圆 直线与矩形的交点 要求各给出每个案例的至少一个示例的程序 这是第二次机器人足球的作业代码 xff0c 写的比较潦草 xff0c 但是用的方法还是通俗易懂的 xff0c 基
  • 合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释

    第三次作业 题目 xff1a 已知2个点的信息 定位自己的绝对坐标 设图中C 0 0 P1 52 5 32 P2 52 5 32 P3 52 5 32 P4 52 5 32 P5 0 32 P6 0 32 P7 30 7 P8 30 7 P