2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第四弹 第一题
#1024程序员节|征文#

往期回顾
前期准备
摄像头bug解决
手搓机械臂
视觉模块的封装


第一问: 需要将一颗黑棋,放入棋盘中的五号位置。 理想思路:依据摄像头,依据机械臂及其传感器。建立机械臂的逆运动学方程。然后完成精准定位,考虑到手搓机械臂的不稳定性。以及摄像头的精度。 所以本团队不使用上述思路。 实施思路:将一个黑色棋子的位置,与5号棋子的位置进行绑定。也就是说,确定三个舵机的角度即可。
下面附上我们团队的代码:
import RPi.GPIO as GPIO
import time
import cv2
import numpy as np
import copyclass ArmControl:def __init__(self):GPIO.setwarnings(False)# 初始化舵机引脚self.servos = {'base': 16,'shoulder': 20,'elbow': 21}# 设定每个九宫格位置对应的舵机角度self.position_angles = {0: (55, 100, 80), # 初始位置1: (91, 107, 40), # 位置 1: 基座 97°,肩部 14°,肘部 0°2: (86, 106, 38), # 位置 2: 基座 90°,肩部 14°,肘部 0°3: (81, 106, 36), # 位置 3: 基座 82°,肩部 14°,肘部 0°4: (90, 102, 68), # 位置 4: 基座 97°,肩部 5°,肘部 3°5: (86, 102, 68), # 位置 5: 基座 90°,肩部 0°,肘部 78°6: (78, 102, 68), # 位置 6: 基座 82°,肩部 5°,肘部 3°7: (89, 101, 88), # 位置 7: 基座 99°,肩部 0°,肘部 45°8: (84, 102, 88), # 位置 8: 基座 90°,肩部 0°,肘部 45°9: (78, 101, 88), # 位置 9: 基座 80°,肩部 0°,肘部 46°'A1': (99, 108, 49), # 取棋子位置 1: 基座 97°,肩部 14°,肘部 0°'B1': (101, 104, 71), # 取棋子位置 1: 基座 97°,肩部 14°,肘部 0°'C1': (100, 104, 87), # 取棋子位置 1: 基座 97°,肩部 14°,肘部 0°'D1': (103, 103, 100), # 取棋子位置 1: 基座 97°,肩部 14°,肘部 0°'A2': (74, 107, 47), # 取棋子位置 2: 基座 97°,肩部 14°,肘部 0°'B2': (70, 104, 73), # 取棋子位置 2: 基座 97°,肩部 14°,肘部 0°'C2': (68, 104, 90), # 取棋子位置 2: 基座 97°,肩部 14°,肘部 0°'D2': (63, 103, 104), # 取棋子位置 2: 基座 97°,肩部 14°,肘部 0°}# 设置GPIO模式GPIO.setmode(GPIO.BCM)# 设置舵机引脚self.pwm = {}self.last_time = 0 # 上一次设置时间self.debounce_time = 0.5 # 防抖时间(秒)for servo in self.servos.values():GPIO.setup(servo, GPIO.OUT)self.pwm[servo] = GPIO.PWM(servo, 50) # 50Hzself.pwm[servo].start(0)def set_servo_angle(self, pwm, target_angle, speed):"""将舵机平滑旋转到指定角度,并实现防抖逻辑"""current_time = time.time() # 获取当前时间# 防抖逻辑if current_time - self.last_time < self.debounce_time:return # 如果距离上次设置时间小于防抖时间,则不执行# 计算占空比duty = self.angle_to_duty_cycle(target_angle)# 确保占空比在合理范围内if duty < 0:duty = 0elif duty > 12: # 假设最大是180度duty = 12pwm.ChangeDutyCycle(duty)time.sleep(speed) # 按速度控制时间延迟pwm.ChangeDutyCycle(0) # 停止PWM信号self.last_time = current_time # 更新最后设置时间def move_servo(self, servo_name, angle):"""指定舵机移动到指定角度"""self.set_servo_angle(self.pwm[self.servos[servo_name]], angle, 0.5) # 设置速度为0.5秒def move_to_position(self, position):"""移动机械臂到指定棋盘位置(1-9)"""if position in self.position_angles:angles = self.position_angles[position] # 获取角度元组self.move_servo('base', angles[0])time.sleep(0.5)# 移动基座self.move_servo('elbow', angles[2])time.sleep(0.5)self.move_servo('shoulder', angles[1]) # 移动肩部# 移动肘部else:print("无效的位置编号!")def remove_to_position(self, position):"""移动机械臂到指定棋盘位置(1-9)"""if position in self.position_angles:angles = self.position_angles[position] # 获取角度元组self.move_servo('shoulder', angles[1])# 移动基座time.sleep(0.5)self.move_servo('elbow', angles[2])time.sleep(1)self.move_servo('base', angles[0])else:print("无效的位置编号!")def angle_to_duty_cycle(self, angle):"""将角度转换为PWM占空比(0到100之间)"""return (angle / 18) + 2 # 示例转换,具体根据舵机类型调整def cleanup(self):"""清理GPIO设置"""for pwm in self.pwm.values():pwm.stop()GPIO.cleanup()class RelayController: # 电磁铁控制def __init__(self, relay_pin,led_pin, debounce_time=0.5):"""初始化继电器控制类:param relay_pin: 继电器连接的 GPIO 引脚:param debounce_time: 控制继电器的状态保持时间(秒)"""self.relay_pin = relay_pinself.led_pin=led_pinself.debounce_time = debounce_time# 设置 GPIO 模式为 BCMGPIO.setmode(GPIO.BCM)# 设置引脚为输出模式GPIO.setup(self.relay_pin, GPIO.OUT)GPIO.setup(self.led_pin, GPIO.OUT)def turn_on(self):"""开启继电器"""print("继电器开启")GPIO.output(self.relay_pin, GPIO.HIGH) # 继电器开启def turn_off(self):"""关闭继电器"""print("继电器关闭")GPIO.output(self.relay_pin, GPIO.LOW) # 继电器关闭# 点亮LED灯1秒GPIO.output(self.led_pin, GPIO.HIGH) # 点亮LEDtime.sleep(1) # 等待1秒GPIO.output(self.led_pin, GPIO.LOW) # 关闭LEDdef run(self):"""控制继电器的状态"""try:while True:self.turn_on()time.sleep(self.debounce_time) # 保持状态self.turn_off()time.sleep(self.debounce_time) # 保持状态except KeyboardInterrupt:print("程序终止,清理 GPIO 设置")finally:self.cleanup()def cleanup(self):"""清理 GPIO 设置"""GPIO.cleanup()def main1():# 初始化舵机控制arm_control = ArmControl()relay_controller = RelayController(relay_pin=17,led_pin=12) # 假设继电器连接在 GPIO 17 引脚try:# 初始位置(0)print("移动到初始位置")arm_control.move_to_position('A1')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('B1')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('C1')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('D1')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('A2')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('B2')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('C2')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)time.sleep(2)arm_control.move_to_position('D2')time.sleep(10) # 延时2秒,确保机械臂到达初始位置arm_control.remove_to_position(0)except KeyboardInterrupt:print("操作中断")finally:# 清理GPIO设置arm_control.cleanup()relay_controller.cleanup()if __name__ == "__main__":main1()相关文章:
2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第四弹 第一题
#1024程序员节|征文# 往期回顾 前期准备 摄像头bug解决 手搓机械臂 视觉模块的封装 第一问: 需要将一颗黑棋,放入棋盘中的五号位置。 理想思路:依据摄像头,依据机械臂及其传感器。建立机械臂的逆运动学方程。然后完…...
优化多表联表查询的常见方法归纳
目录 一、使用mybatis的嵌套查询 二、添加表冗余字段,减少联表查询需求 三、分表预处理,前端再匹配 一、使用mybatis的嵌套查询 【场景说明】 前端需要展示一张列表,其中的字段来源于多张表,如何进行查询优化? 【…...
Java毕业设计 基于SpringBoot发卡平台
Java毕业设计 基于SpringBoot发卡平台 这篇博文将介绍一个基于SpringBoot发卡平台,适合用于Java毕业设计。 功能介绍 首页 图片轮播 商品介绍 商品详情 提交订单 文章教程 文章详情 查询订单 查看订单卡密 客服 后台管理 登录 个人信息 修改密码 管…...
VRoid Studio 介绍 3D 模型编辑器
VRoid Studio 是由日本公司 pixiv 开发的一款免费 3D 模型创建软件,专门设计用于轻松制作 3D 虚拟角色。它的主要特点是用户友好,允许没有 3D 建模经验的用户创建高质量的 3D 人物角色,尤其是针对虚拟主播(Vtuber)、动…...
软件设计模式------抽象工厂模式
抽象工厂模式(Abstract Factory Pattern),又称Kit模式,属于对象创建型模式。 一:先理解两个概念: (1)产品等级结构: 即产品的继承结构。 通俗来讲,就是不同品…...
基于springboot+微信小程序校园自助打印管理系统(打印1)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于springboot微信小程序校园自助打印管理系统实现了管理员、店长和用户。管理员实现了用户管理、店长管理、打印店管理、打印服务管理、服务类型管理、预约打印管理和系统管理。店长实现…...
解锁文本数据可视化的无限可能:Wordcloud库全解析
文章目录 **🌟解锁文本数据可视化的无限可能:Wordcloud库全解析🔐**1. **背景介绍**2. **Wordcloud库是什么?**3. **如何安装Wordcloud库?**4. **Wordcloud库的基本函数使用方法**5. **实际应用场景**6. **常见问题及解…...
代码审计-Python Flask
1.Jinjia2模版注入 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2。jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于…...
深度学习:开启人工智能的新纪元
深度学习:开启人工智能的新纪元 深度学习是机器学习的一个子领域,它基于人工神经网络的学习算法,特别是那些具有多个非线性变换的层(即“深度”)。这些算法模仿人脑处理信息的方式,通过学习数据的多层次表…...
第十四章_File类与IO流
目录 1. java.io.File类的使用 1.1 概述 1.2 构造器 1.3 常用方法 1、获取文件和目录基本信息 2、列出目录的下一级 3、File类的重命名功能 4、判断功能的方法 5、创建、删除功能 1.4 练习 2. IO流原理及流的分类 2.1 Java IO原理 2.2 流的分类 2.3 流的API 3. …...
Qml-CheckBox的使用
Qml-CheckBox的使用 CheckBox属性 CheckBox的继承关系: CheckBox – AbstractButton – Control – Item; CheckBox的属性主要继承于AbstractButton。属性checkState:勾选状态,值为:Qt.Unchecked、Qt.Checked、Qt.PartiallyChec…...
Java的RocketMQ使用
在 Spring Boot 中,RocketMQ 和 Kafka 都是常用的消息中间件,它们的使用方法有一些相似之处,也有各自的特点。 一、RocketMQ 在 Spring Boot 中的使用 引入依赖 在项目的pom.xml文件中添加 RocketMQ 的依赖。 <dependency><groupId…...
中间件之MQ-Kafka
一、引言 Apache Kafka是一个分布式消息队列系统,最初由LinkedIn开发,并于2011年开源。Kafka以其高吞吐量、低延迟和容错能力而著名,广泛应用于日志收集、实时流处理、事件驱动架构等领域。本文将详细介绍Kafka的基本概念、特点、应用场景以…...
[DB] NSM
Database Workloads(数据库工作负载) 数据库工作负载指的是数据库在执行不同类型任务时所需的资源和计算方式,主要包括以下几种类型: 1. On-Line Transaction Processing (OLTP) 中文:联机事务处理解释:…...
Redis 高可用:从主从到集群的全面解析
目录 一、主从复制 (基础)1. 同步复制a. 全量数据同步b. 增量数据同步c. 可能带来的数据不一致 2. 环形缓冲区a. 动态调整槽位 3. runid4. 主从复制解决单点故障a. 单点故障b. 可用性问题 5. 注意事项a. Replica 主动向 Master 建立连接b. Replica 主动向 Master 拉取数据 二、…...
全能型选手视频播放器VLC 3.0.21 for Windows 64 bits支持Windows、Mac OS等供大家学习参考
全能型选手视频播放器,支持Windows、Mac OS、Linux、Android、iOS等系统,也支持播放几乎所有主流视频格式。 推荐指数: ★★★★★ 优点: ◆、界面干净简洁,播放流畅 ◆、支持打开绝大多数的文件格式,包…...
解决在Vue3中使用monaco-editor创建多个实例的导致页面卡死的问题
最近在项目中使用到了monaco-editor来实现相关的业务功能,按照官方使用方法进行了相关操作,但是在使用的时候,总是会导致创建多个编辑器实例,导致页面卡死的情况,下面来看看怎么处理这种情况吧,先说一下我使…...
【某农业大学计算机网络实验报告】实验二 交换机的自学习算法
实验目的: (1)理解交换机通过逆向自学习算法建立地址转发表的过程。 (2)理解交换机转发数据帧的规则。 (3)理解交换机的工作原理。 实验器材: 一台Windows操作系统的PC机。 实…...
燕山大学23级经济管理学院 10.18 C语言作业
燕山大学23级经济管理学院 10.18 C语言作业 文章目录 燕山大学23级经济管理学院 10.18 C语言作业1C语言的基本数据类型主要包括以下几种:为什么设计数据类型?数据类型与知识体系的对应使用数据类型时需要考虑的因素 21. 逻辑运算符2. 真值表3. 硬件实现4…...
【880线代】线性代数一刷错题整理
第一章 行列式 2024.8.20日 1. 2. 3. 第二章 矩阵 2024.8.23日 1. 2024.8.26日 1. 2. 3. 4. 5. 2024.8.28日 1. 2. 3. 4. 第四章 线性方程组 2024.9.13日 1. 2. 3. 4. 5. 2024.9.14日 1. 第五章 相似矩阵 2024.9.14日 1. 2024.9.15日 1. 2. 3. 4. 5. 6. 7. 2024.9.…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
