qt-Robot-PyQt5

qt-Robot-PyQt5

  • 一、演示效果
  • 二、关键程序
  • 三、下载链接


Python 脚本使用 PyQt5 作为窗口框架,OpenGL 作为 3D 环境。 每个机器人都是 DOF3_robot 类的一个实例。

所需模块:

PyQt5的
pyqtgraph/opengl
Numpy。

一、演示效果

在这里插入图片描述

二、关键程序

import rm_utilities as Rm
import numpy as np
import pyqtgraph.opengl as gl"""
Simulation of a 6 DOF robot.
- Cédric Wassenaar & Joeri Verkerk
- C.M.Wassenaar@student.hhs.nl
- 24-09-2018
"""class Link(object):"""Storage type for robot arm object"""def __init__(self):self.arm_length = 0self.arm: gl.GLMeshItem|None = Noneself.frame: gl.GLAxisItem|None = Noneself.joint: gl.GLMeshItem|None = Noneself.DH_parameters = [0, 0, 0, 0]self.homogenious_matrix: np.array|None = Noneself.hg_matrix_list = []self.p = Noneclass Robot(object):"""Class to create robot object for OpenGl implementation"""def __init__(self, view3D):self.view3D = view3D# Presetsself.radius = 0.2self.width = .6 * 2 * self.radiusself.depth = self.widthself.depth_cylinder = 1.2 * self.widthself.segments = 40self.joint_color = (0.8, 0.2, 1, 1)  # yellowself.arm_color = (0.4, 0.4, 0.4, 1)  # light blueself.cycle = 0self.iteration = 0self.N = 0self.ready = Falseself.print_text = []# define arm lengthsself.arm_lengths = [1.75,1.60,1.25,0.00,0.00,0.00,0.50,0.00]# Create a list of arm piecesself.link = [Link()] * (len(self.arm_lengths) + 1)# define Target rotation for the end effector# self.target_rotation = Rm.make_rotation_matrix("x", np.radians(00))self.target_rotation = np.eye(3, 3)# define trajectory# X, Y, Z, Ax, Ay, Az (degrees)self.trajectory = np.array([[-1.5, 1, 2, 0, 0, 0],[1.5, 0.5, 4, 0, 0, np.pi/2],[1.5, 2.0, 1, 0, np.pi, np.pi/2],[-0.0, 2.0, 3, 0, np.pi, 0],[-1.5, 2, 2, 0, 0, 0]])self.setup()def setup(self):"""Function for user defined objects and functions:return:"""# create all arm piecesself.link[0].frame = self.create_main_axis()self.link[1] = self.add_arm(self.link[0], self.arm_lengths[0])self.link[1].frame.setSize(0.5, 0.5, 0.5)self.link[2] = self.add_arm(self.link[1], self.arm_lengths[1])self.link[2].frame.setSize(0.5, 0.5, 0.5)self.link[3] = self.add_arm(self.link[2], self.arm_lengths[2])self.link[3].frame.setSize(0.1, 0.1, 0.1)self.link[4] = self.add_arm(self.link[3], self.arm_lengths[3])self.link[4].frame.setSize(0.1, 0.1, 0.1)self.link[5] = self.add_arm(self.link[4], self.arm_lengths[4])self.link[5].frame.setSize(0.1, 0.1, 0.1)self.link[6] = self.add_arm(self.link[5], self.arm_lengths[5])self.link[6].frame.setSize(0.1, 0.1, 0.1)self.link[7] = self.add_arm(self.link[6], self.arm_lengths[6])self.link[7].frame.setSize(0.1, 0.1, 0.1)self.link[8] = self.add_arm(self.link[7], self.arm_lengths[7])# Rotate arms to work with Denavit Hartenberg parametersself.link[1].arm.rotate(90,  1, 0, 0)self.link[2].arm.rotate(-90, 0, 1, 0)self.link[3].arm.rotate(-90, 0, 1, 0)# Predefine static values of the Denavit Hartenberg parametersself.link[0].DH_parameters = [0,                    0,                  0,                      0]self.link[1].DH_parameters = [0,                    1.57079,            self.arm_lengths[0],    0]self.link[2].DH_parameters = [self.arm_lengths[1],  0,                  0,                      0]self.link[3].DH_parameters = [self.arm_lengths[2],  0,                  0,                      0]self.link[4].DH_parameters = [0,                    1.57079,            0,                1.57079]self.link[5].DH_parameters = [0,                    -1.57079,           0,                      0]self.link[6].DH_parameters = [0,                    1.57079,            0,                      0]self.link[7].DH_parameters = [0,                    0,                  0,                      0]self.link[8].DH_parameters = [0,                    0,                  self.arm_lengths[6],    0]def set_new_trajectory(self, new_trajectory, precision):"""Sets and calculates new trajectory for robot"""self.trajectory = Rm.interpolate(new_trajectory, precision)self.N = self.trajectory.shape[0]self.iteration = 0self.calculate_path()def calculate_path(self):"""In order to reduce CPU use the inverse kinematics are pre-calculated and saved in a list,the update_window methods will then iterate through this list."""# Clear old pathself.print_text = []for i in range(1, len(self.link)):self.link[i].hg_matrix_list = []# Create new pathlength = len(self.trajectory)for current in range(length):# In order to prevent call by reference the trajectory values are copied.pos = self.trajectory[current].copy()rotation = Rm.rotate_xyz(pos[3:])pos[0] = pos[0] - self.arm_lengths[6] * rotation[0, 2]pos[1] = pos[1] - self.arm_lengths[6] * rotation[1, 2]pos[2] = pos[2] - self.arm_lengths[6] * rotation[2, 2]# The Inverse kinematics are calculated in the rm_utilitiesV3 fileangles, error = Rm.inverse_algorithm_3DOF(self.arm_lengths, pos)# If the robot arm is not capable of reaching the given coordinate it will raise an errorif not error:# The dynamic values of the Denavit Hartenberg parameters are now updated.self.link[1].DH_parameters[3] = angles[0]self.link[2].DH_parameters[3] = angles[1]self.link[3].DH_parameters[3] = angles[2]# The homogenious matrices are created for link 0 to 4for i in range(5):self.link[i].homogenious_matrix = Rm.make_DH_matrix(self.link[i].DH_parameters)# The H03 matrix is calculated using the @ symbol (matrix multiplication)H03 = self.link[0].homogenious_matrix @ \self.link[1].homogenious_matrix @ \self.link[2].homogenious_matrix @ \self.link[3].homogenious_matrix @ \self.link[4].homogenious_matrix# The 3x3-rotation matrix R36 is calculatedR36 = np.matrix.transpose(H03[:3, :3]) @ rotation# The inverse kinematics for the wrist is calculated with R36rotate, R_compare = Rm.inverse_kinematics_wrist(R36)self.link[5].DH_parameters[3] = rotate[0]self.link[6].DH_parameters[3] = rotate[1]self.link[7].DH_parameters[3] = rotate[2]for i in range(5, 9):self.link[i].homogenious_matrix = Rm.make_DH_matrix(self.link[i].DH_parameters)# The end effector matrices are calculatedH36 = self.link[5].homogenious_matrix @ \self.link[6].homogenious_matrix @ \self.link[7].homogenious_matrix @ \self.link[8].homogenious_matrixH06 = H03 @ H36p0 = np.array([self.trajectory[current, 0],self.trajectory[current, 1],self.trajectory[current, 2],1])TH6 = np.linalg.inv(H06).dot(p0)# All flattened homogenious matrices are saved in a listfor i in range(1, len(self.link)):# self.link[i].frame.setTransform(self.link[i].homogenious_matrix.flatten())matrix = self.link[i].homogenious_matrix.flatten()self.link[i].hg_matrix_list.append(matrix)# The positions are saved in textformatangles = str(format(np.degrees(angles[0]), '.1f')) + \"\t" + str(format(np.degrees(angles[1]), '.1f')) + \"\t" + str(format(np.degrees(angles[2]), '.1f')) + "\n\n"rotate = str(format(np.degrees(rotate[0]), '.1f')) + \"\t" + str(format(np.degrees(rotate[1]), '.1f')) + \"\t" + str(format(np.degrees(rotate[2]), '.1f')) + "\n\n"self.print_text.append("R36:\n" + str(R36) +"\n\nR36 check:\n" + str(R_compare) +"\n\nArm Angles:\n" + angles +"Wrist Angles:\n" + rotate +"Target: " + str(self.trajectory[current]) +"\noc: " + str(pos) +"\nTH6: " + str(TH6))# Each 5th step of the trajectory a small block is rendered to show the path of the robotif (current % 6) > 4:self.show_path(H06)else:print("Error Calculating, position possibly out of range")self.ready = Truedef __str__(self):return self.print_text[self.iteration]def add_arm(self, parent_object, length):""":param parent_object::param length::return:"""link = Link()link.frame = self.set_new_axis(parent_object.frame)link.arm = self.create_arm(length)link.arm.setParentItem(link.frame)link.arm_length = lengthlink.arm.rotate(-90, 0, 1, 0)link.arm.translate(self.width / 2, -self.width / 2, self.width / 2)link.joint = self.create_joint()link.joint.setParentItem(link.frame)link.joint.translate(0, 0, -self.depth_cylinder/ 2)return linkdef create_arm(self, length) -> gl.GLMeshItem:"""Creates a box that is attached to a certain object"""size = (length, self.width, self.depth)vertices_arm, faces_arm = Rm.box(size)arm = gl.GLMeshItem(vertexes=vertices_arm, faces=faces_arm,rawEdges=False, drawFaces=True, color=self.arm_color)self.view3D.addItem(arm)return armdef create_joint(self) -> gl.GLMeshItem:"""Creates a joint that is attached to a certain object"""vertices_joint, faces_joint = Rm.cylinder(self.radius, self.depth_cylinder, self.segments)joint = gl.GLMeshItem(vertexes=vertices_joint, faces=faces_joint,drawEdges=False, drawFaces=True, color=self.joint_color)self.view3D.addItem(joint)return jointdef set_new_axis(self, parent_object) -> gl.GLAxisItem:"""Adds axis to given object"""axis = gl.GLAxisItem(antialias=True, glOptions='opaque')axis.updateGLOptions({'glLineWidth': (3,)})axis.setParentItem(parent_object)self.view3D.addItem(axis)return axisdef create_main_axis(self) -> gl.GLAxisItem:"""Create the basis axis"""axis = gl.GLAxisItem()axis.updateGLOptions({'glLineWidth': (6,)})self.view3D.addItem(axis)return axisdef show_path(self, frame):vertices_arm, faces_arm = Rm.box((0.05, 0.05, 0.05))box = gl.GLMeshItem(vertexes=vertices_arm, faces=faces_arm,rawEdges=False, drawFaces=True, color=(1, 0.3, 0.4, 1))box.setParentItem(self.link[0].frame)m1 = np.array_split(frame.flatten(), 4)box.setTransform(m1)self.view3D.addItem(box)def update_window(self):"""Render new frame of 3D view"""if not self.ready:return # When ready the robot is rendered and updated.for i in range(1, len(self.link)):a1 = self.link[i].hg_matrix_list[self.iteration]m1 = np.array_split(a1, 4)self.link[i].frame.setTransform(m1)# increase the counter, such that next time we get the next pointself.iteration += 1# if the counter arives at N, reset it to 0, to repeat the trajectoryif self.iteration == self.N:self.iteration = 0self.cycle += 1

三、下载链接

https://download.csdn.net/download/u013083044/88851028

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/478417.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity2023.1.19没有PBR Graph?

Unity2023.1.19没有PBR Graph? 关于Unity2023.1.19没有PBR graph的说法,我没看见管方给出的答案,百度则提到了Unity2020版之后Shader Graph的“全新更新”,之前也没太注意版本的区别,以后项目尽量都留心一下。 之前文章说过,孪生智慧项目推荐使用URP渲染管线,以上的截…

10_Java泛型

一、为什么要有泛型 1.泛型的设计背景 集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分…

NBlog个人博客部署维护过程记录 -- 后端springboot + 前端vue

项目是fork的Naccl大佬NBlog项目,页面做的相当漂亮,所以选择了这个。可以参考2.3的效果图 惭愧,工作两年了也没个自己的博客系统,趁着过年时间,开始搭建一下. NBlog原项目的github链接:Naccl/NBlog: &#…

阿里云ECS服务器如何选择操作系统?

阿里云服务器镜像怎么选择?云服务器操作系统镜像分为Linux和Windows两大类,Linux可以选择Alibaba Cloud Linux,Windows可以选择Windows Server 2022数据中心版64位中文版,阿里云服务器网aliyunfuwuqi.com来详细说下阿里云服务器操…

专修戴尔R730xd服务器闪电灯 心跳亮黄灯故障

2024年开年第二天接到一个用户反馈说他公司有一台DELL PowerEdge R730xd服务器春节前由于市电问题意外断电关机了,刚好碰上春节就没去开机了,今天工厂开工服务器通电发现开不了机,且机器过了一会后报了2个黄灯错误,如下图&#xf…

redis scan命令导致cpu飙升

一.背景 今天下午Redis的cpu占用突然异常升高,一度占用达到了90%,触发了钉钉告警,之后又回到正常水平,跟DBA沟通,他说主要是下面这个语句的问题 SCAN 0 MATCH fastUser:6136* COUNT 10000这个语句的执行时长很短&…

408计算机网络--基础概论

学习计算机网络走以前需要首先明白一个大的概念,计算机网络通常分为通信子网(实现数据通信)和资源子网(实现资源共享/数据处理)七层妖塔 计算机网络:是一个将分散的、具有独立功能的计算机系统&#xff0…

如何选择阿里云服务器配置?阿里云服务器CPU内存带宽攻略

阿里云服务器配置怎么选择?根据实际使用场景选择,个人搭建网站可选2核2G配置,访问量大的话可以选择2核4G配置,企业部署Java、Python等开发环境可以选择2核8G配置,企业数据库、Web应用或APP可以选择4核8G配置或4核16G配…

IDEA连接database数据库

文章目录 一、连接数据库1、连接mysql2、连接参数配置3、配置驱动从maven仓库下载:要求联网将提前下载好的jar放到本地目录 4、完成 二、执行sql1、选择要操作的数据库2、执行sql 三、问题1、可能因为时区问题连接不上 一、连接数据库 1、连接mysql 2、连接参数配置…

css pointer-events 多层鼠标点击事件

threejs 无法滑动视角,菜单界面覆盖threejs操作事件。 pointer-events /* Keyword values */ pointer-events: auto; pointer-events: none; pointer-events: visiblePainted; /* SVG only */ pointer-events: visibleFill; /* SVG only */ pointer-events: visib…

提取游戏音频文件.bnk

提取游戏音频文件.bnk 什么是.bnk准备Wwise-Unpacker工具使用Wwise-Unpacker工具总结 什么是.bnk .bnk其实是一种对音频的加密方式,一个.bnk文件中通常包含了多个语音文件,一般可以使用Wwise-Unpacker来解码.bnk格式文件 准备Wwise-Unpacker工具 Wwis…

从零开始手写mmo游戏从框架到爆炸(十五)— 命令行客户端改造

导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客 到现在,我们切实需要一个客户端来完整的进行英雄选择,选择地图,打怪等等功能。所以我们需要把之前极为简陋的客户端改造一下。 首先…