当前位置: 首页 > news >正文

如何在Python用Plot画出一个简单的机器人模型

如何在Python中使用 Plot 画出一个简单的模型

在下面的程序中,首先要知道机器人的DH参数,然后计算出每一个关节的位置,最后利用 plot 函数画出关节之间的连杆就可以了,最后利用 animation 库来实现一个动画效果。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.pyplot as plt
import numpy as np
from IPython import embed
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk


# 取消科学计数法,保留6位小数
np.set_printoptions(precision=6, suppress=True)

class Robot(object):
	def __init__(self):
		self.alpha_list = []
		self.a_list = []
		self.d_list = []
		self.theta_list = []

	def SetDHParamList(self, alpha_list, a_list, d_list, theta_list):
		self.alpha_list = alpha_list
		self.a_list = a_list
		self.d_list = d_list
		self.theta_list = theta_list

	def DH(self, index, theta):
		theta = theta + self.theta_list[index]
		T = np.zeros([4, 4])
		c_t = np.cos(theta * np.pi/180)
		s_t = np.sin(theta * np.pi/180)
		c_a = np.cos(self.alpha_list[index] * np.pi/180)
		s_a = np.sin(self.alpha_list[index] * np.pi/180)
	
		T[0] = [c_t, - s_t * c_a,     s_t * s_a,  self.a_list[index] * c_t]
		T[1] = [s_t,   c_t * c_a,   - c_t * s_a,  self.a_list[index] * s_t]
		T[2] = [  0,         s_a,           c_a,        self.d_list[index]]
		T[3] = [  0,           0,             0,                    1]

		# print(T)

		return np.mat(T)
	
	def GetRobotTool(self, q_list):
		T6 = np.identity(4, dtype= float)
		for i in range(6):
			T = self.DH(i, q_list[i])
			T6 = T6 * T
		
		return T6


class ShowRobot(object):
	def __init__(self):
		self.ax = None
		self.robot = None
		self.q_list = [0, 0, 0, 0, 0, 0]

		fig_width, fig_height = plt.gcf().get_size_inches()
		# 根据画布大小自动调整直线的粗细, 这里乘上系数3只是为了更好地显示效果
		self.line_thicknes = max(fig_width / 50, fig_height / 50) * 60
		self.s200 = max(fig_width / 50, fig_height / 50) * 200
		self.fontsize = max(fig_width / 50, fig_height / 50) * 80
		self.alpha = 0.7 #透明度


	def ShowFrame(self, T, length = 1, width = 2):
		# 使用quiver绘制坐标轴
		# 参数说明:
		# origin[0], origin[1], origin[2] 是箭头的起点
		# x_axis[0], x_axis[1], x_axis[2] 是箭头的方向
		# length 是箭头的长度
		# arrow_length_ratio 是箭头头部与箭杆的比例
		# linewidth 是箭杆的宽度
		self.ax.quiver(T[0, 3], T[1, 3], T[2, 3], T[0, 0], T[1, 0], T[2, 0], color='r', length=length, arrow_length_ratio=0.1, linewidth=width)
		self.ax.quiver(T[0, 3], T[1, 3], T[2, 3], T[0, 1], T[1, 1], T[2, 1], color='g', length=length, arrow_length_ratio=0.1, linewidth=width)
		self.ax.quiver(T[0, 3], T[1, 3], T[2, 3], T[0, 2], T[1, 2], T[2, 2], color='b', length=length, arrow_length_ratio=0.1, linewidth=width)

	def ShowLink(self, joint_index, T_start, T_end):
		mx2, my2, mz2 = np.array([T_start[0, 3],T_end[0, 3]]), np.array([T_start[1, 3], T_end[1, 3]]), np.array([T_start[2, 3], T_end[2, 3]])
		self.ax.plot(mx2, my2, mz2, solid_capstyle='round', color='blue', linewidth=self.line_thicknes, alpha=self.alpha)
		self.ax.text(T_start[0, 3], T_start[1, 3], T_start[2, 3], "J" + str(joint_index), color='r', fontsize=self.fontsize, zorder=1, ha='center')
		self.ax.scatter(T_start[0, 3], T_start[1, 3], T_start[2, 3], c='orange', marker='.', s=self.s200)


	# 更新函数,用于每一帧的更新
	def update(self, frame):
		self.ax.cla()  # 清除所有轴

		# 设置坐标轴标签
		self.ax.set_xlabel('X')
		self.ax.set_ylabel('Y')
		self.ax.set_zlabel('Z')

		# # 设置图形显示范围
		self.ax.set_xlim([-1000, 1000])
		self.ax.set_ylim([-1000, 1000])
		self.ax.set_zlim([-1000, 1000])

		T_start = np.identity(4, dtype= float)
		T_end = np.identity(4, dtype= float)
		self.ShowFrame(T_start, length=300)

		# 关节角度固定不变
		self.q_list = [0, 0, 0, 0, 0, 0]
		# 关节角度每一帧都在更新,呈现出一种动画效果
		# self.q_list = [frame, frame - 90, 0, 0, 0, 0]
		for joint_index in range(6):
			T_start = T_end
			T = self.robot.DH(joint_index, self.q_list[joint_index])
			T_end = T_end * T
			# print(T_end)
			self.ShowLink(joint_index, T_start, T_end)

		self.ShowFrame(T_end, length=300)


def APP():

	L1 = 388
	L2 = 50
	L3 = 330
	L4 = 50
	L5 = 332
	L6 = 96
	alpha_list = [90, 0, 90, -90, 90, 0]
	a_list     = [L2, L3, L4, 0, 0, 0]
	d_list     = [L1, 0, 0, L5, 0, L6]
	theta_list = [0, 90, 0, 0, 0, 0]


	robot = Robot()
	show_robot = ShowRobot()
	robot.SetDHParamList(alpha_list, a_list, d_list, theta_list)

	# 创建一个3D图形
	fig = plt.figure()
	ax = fig.add_subplot(111, projection='3d')
	show_robot.ax = ax
	show_robot.robot = robot

	root = tk.Tk()
	canvas = FigureCanvasTkAgg(fig, master = root)
	canvas.get_tk_widget().pack()
	ani = animation.FuncAnimation(fig, show_robot.update, interval = 50)
	canvas.draw()
	tk.mainloop()

	# 显示动画
	plt.show()

if __name__ == "__main__":
	APP()

下面是实际显示出来的3D机器人模型,其中也画出了机器人的基坐标系和末端工具坐标系。
3D 机器人模型
·

在 Update 函数中,可以在每一帧中去更新关节角度,然后呈现出一种动画的效果。

		# 关节角度固定不变
		self.q_list = [0, 0, 0, 0, 0, 0]
		# 关节角度每一帧都在更新,呈现出一种动画效果
		# self.q_list = [frame, frame - 90, 0, 0, 0, 0]

相关文章:

  • llama-factory || AutoDL平台
  • ASP.NET Core 3.1 修改个别API返回JSON序列化格式
  • MySQL整体架构
  • Docker - 网络
  • 用冒泡排序法模拟qsort函数
  • LabVIEW中三种PSD分析VI的区别与应用
  • 微调训练方法概述:Fine-tuning、Prompt-tuning、P-tuning 及其他高效技术
  • pwa的基本使用
  • 2W8000字 LLM架构文章阅读指北
  • pytorch2.6.0版本测试YOLOv5中detect.py错误解决办法
  • http报文的content-type参数和spring mvc传参问题
  • 高频 SQL 50 题(基础版)_550. 游戏玩法分析 IV
  • 系统架构设计师—计算机基础篇—系统性能评价
  • 深度学习pytorch之4种归一化方法(Normalization)原理公式解析和参数使用
  • 小结:BGP协议
  • AtCoder Beginner Contest 001(A - 積雪深差、B - 視程の通報、C - 風力観測、D - 感雨時刻の整理)题目翻译
  • 贪心算法+题目
  • Sqli-labs
  • 从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(八) 聊天框用户列表
  • ByteBuddy
  • 织梦中英文网站源码/网站免费网站免费优化优化
  • 有什么做数据的网站/郑州制作网站公司
  • 大连哪个公司做网站开发的/太原seo哪家好
  • 男人女人做那事网站/google浏览器官网入口
  • 网站开发一般需要多久/常见的搜索引擎有哪些
  • 公司在网站做广告怎么做分录/怎样下载优化大师