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

这篇具有很好参考价值的文章主要介绍了合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第三次作业

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

合肥工业大学机器人技术第三次作业,机器人,python

 

设图中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的相对角度的值是视野估算的,是很大误差的,所以用来确定自己位置的大概范围,不能用来参与计算。   

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

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

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

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

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

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

这是绝对坐标的坐标系图

合肥工业大学机器人技术第三次作业,机器人,python

 

 

 

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

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

还是那句话,学以致用才是真正的学到了。文章来源地址https://www.toymoban.com/news/detail-715951.html

到了这里,关于合肥工业大学机器人足球仿真robcup作业三(python实现)附代码有注释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 合肥工业大学计算机网络实验一

    计算机网络实验报告# ✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验报告 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!

    2024年02月03日
    浏览(53)
  • 合肥工业大学计算机组成原理实验报告

    ✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :本科生课设-计算机组成原理实验 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!

    2024年02月04日
    浏览(51)
  • 合肥工业大学嵌入式系统原理实验报告

    ✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 : 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出过多少努力,

    2024年02月07日
    浏览(58)
  • 课程《FPGA技术及应用》作业分享(合肥工业大学仪器学院)

    合工大测控系教学 1. 简述EDA技术的发展进程。简要叙述什么是EDA技术。 EDA技术(Electronic Design Automation)是一种用于电子产品设计与制造的软件工具。 EDA技术的发展进程: 1960年代:开发出第一代EDA工具,用于电路设计与模拟。 1970年代:EDA工具发展到第二代,支持二维自动

    2024年02月03日
    浏览(64)
  • 合肥工业大学网络安全实验IP-Table

    ✅作者简介:CSDN内容合伙人、信息安全专业在校大学生🏆 🔥系列专栏 :hfut实验课设 📃新人博主 :欢迎点赞收藏关注,会回访! 💬舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付出

    2024年02月04日
    浏览(51)
  • 合肥工业大学 宣城校区 数据结构与算法实验 队列、二叉树、查找和排序

    1.实验目标 熟练掌握队列的顺序存储结构和链式存储结构。 熟练掌握队列的有关算法设计,并在循环顺序队列和链队列上实现。 根据具体给定的需求,合理设计并实现相关结构和算法。 2.实验内容和要求 循环顺序队列的实验要求 循环顺序队列结构和运算定义,算法的实现以

    2024年02月11日
    浏览(49)
  • 专业135总400+合工大合肥工业大学833信号分析与处理信息通信上岸经验分享

    专业135总400+合工大合肥工业大学833信号分析与处理信息通信上岸经验分享 基础课经验很多,大同小异,我分享一下自己的833专业课复习经验。 一:用到的书本 1.《信号与系统》(第三版)郑君里,高等教育出版社,2011 2.《数字信号处理》(第四版),高西全,西安电子科技

    2024年02月08日
    浏览(49)
  • 合肥工业大学宣城校区Java技术实验二 基于GUI的网络通信程序设计

    1.掌握Java中GUI程序的编写,包括事件监听机制。 2.掌握Java的网络通信编程,ServerSocket,Socket类的使用。 3.掌握Java中多线程的编程,Thread类,Runnable接口的使用。 4.掌握用面向对象的方法分析和解决复杂问题。 编写程序完成以下功能: 1.设计一个基于GUI的客户-服务器的

    2023年04月24日
    浏览(48)
  • 专业课145+合肥工业大学833信号分析与处理考研经验合工大电子信息通信

    今年专业课145+也是考研科目中最满意的一门,其他基本相对平平,所以这里我总结一下自己的专业课合肥工业大学833信号分析与处理的复习经验。 我所用的教材是郑君里的《信号与系统》(第三版)和高西全、丁玉美的《数字信号处理》(第四版),另外自己还看了祖师爷

    2024年01月18日
    浏览(62)
  • 专业140+总410+合工大合肥工业大学833信号分析与处理综合考研经验电子信息与通信工程,真题,大纲,参考书。

    一、专业课: 833信号分析与处理综合是两门,信号和数字信号处理,复习内容较多,大家专业课要早点开始,由于近年数学难度一再提高,专业课成了高分突破的法宝,我当时先准备报考中科大843也是信号和数字信号处理,一直跟Jenny老师的中科大843专业课辅导课,不熟悉

    2024年02月20日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包