《机器人学一(Robotics(1))》_台大林沛群 第4周 Quiz4

前两题主要是细心观察即可,第三题主要是使用勾股定理以及简单的反三角函数求解即可,长度与角度答案分别为80和30,不作赘述,主要阐述从第四题开始的解题过程。

目录

      • P4.
      • P5 - P7.
      • P8.

P4.

在这里插入图片描述
根据上述推导过程编写代码如下:

import numpy as np
theta1 = np.pi * (-60) / 180
r1 = np.array([[np.cos(theta1), 0, np.sin(theta1)],
               [0, 1, 0],
               [-np.sin(theta1), 0, np.cos(theta1)]])
p1 = np.array([-500, 452, 410])
t1 = RP_Transformation_Matrix(r1, p1.reshape(3, 1))

r2 = np.array([[1, 0, 0],
               [0, 1, 0],
               [0, 0, 1]])
p2 = np.array([830, 20, 330])
t2 = RP_Transformation_Matrix(r2, p2.reshape(3, 1))

t = np.dot(t2, t1)
t = [[float(format(x, '.3g')) for x in t[i]] for i in range(len(t))]  # 保留 3位有效数字`

得到答案为 : 0.5//-0.866//0.866//330//472//740

P5 - P7.

在这里插入图片描述
解题代码如下:

# pieper's solution
# formula : p_04 = p_06 = t_01 * t_12 * t_23 * p _34
# p_04 = p_06 = t_06[:,-1]
t_wc = t
t_cw = np.linalg.inv(t_wc)
p_cw = t_cw[:, -1]
t_6c = np.array([[0, 0, 1, 0],
                 [0, -1, 0, 0],
                 [1, 0, 0, 206],
                 [0, 0, 0, 1]])
t_0w = np.array([[1, 0, 0, 0],
                 [0, 1, 0, 0],
                 [0, 0, 1, 373],
                 [0, 0, 0, 1]])
t_06 = np.dot(np.dot(np.linalg.inv(t_0w), t_wc), np.linalg.inv(t_6c))
print(t_06)
p_04 = t_06[:, -1]
print(p_04)

到这里求出了p_04,即pieper’s solution核心公式左侧的已知量,接下来依次计算theta角即可:
代码运行结果如下:
在这里插入图片描述
接下来利用sympy包求解theta3:

from sympy import *
# 计算theta3
theta3 = Symbol('theta3')
x, y, z = p_04[0], p_04[1], p_04[2]
r = x**2 + y**2 + z**2

k1 = a3 * cos(theta3) + d4 * sin(alpha3) * sin(theta3) + a2
k2 = -(a3 * cos(alpha2) * sin(theta3) - d4 * sin(alpha3) * cos(alpha2) * cos(theta3)
       - d4 * sin(alpha2) * cos(alpha3) - d3 * sin(alpha2))
f3 = a3 * sin(alpha2) * sin(theta3) - d4 * sin(alpha3) * sin(alpha2) * cos(theta3)\
     + d4 * cos(alpha2) * cos(alpha3) + d3 * cos(alpha2)
k3 = k1**2 + k2**2 + f3**2 + a1**2 + d2**2 + 2 * d2 * f3
k4 = f3 * cos(alpha1) + d2 * cos(alpha1)

f1 = ((r - k3)/(2 * a1)) ** 2 + ((z - k4) /sin(alpha1))**2 - k1**2 - k2**2
ans = solve([f1], ['theta3'])
ans = [ans[i][0] for i in range(len(ans))]
ans_angle = [180 * ans[i]/ np.pi for i in range(len(ans)) if ans[i]>= -180.0 and ans[i]<= 180.0]
# 根据题目对theta3的范围筛选出角度
print("可能的theta3值有:",  ans_angle)
print(ans)

代码运行结果如下:
在这里插入图片描述
题干提醒是双解,说明后续角度对theta3也会有约束,所以这里先不进行角度的选择,而是继续根据公式求解theta2角的求解。可以看到theta2需要同时满足r,z两个条件的要求,为了快速计算,分别对r, 和z约束条件下的theta2进行求解,最后判断其解。

# 计算theta2
theta3 = -2.76034628749053
k1 = a3 * cos(theta3) + d4 * sin(alpha3) * sin(theta3) + a2
k2 = -(a3 * cos(alpha2) * sin(theta3) - d4 * sin(alpha3) * cos(alpha2) * cos(theta3)
       - d4 * sin(alpha2) * cos(alpha3) - d3 * sin(alpha2))
f3 = a3 * sin(alpha2) * sin(theta3) - d4 * sin(alpha3) * sin(alpha2) * cos(theta3)\
     + d4 * cos(alpha2) * cos(alpha3) + d3 * cos(alpha2)
k3 = k1**2 + k2**2 + f3**2 + a1**2 + d2**2 + 2 * d2 * f3
k4 = f3 * cos(alpha1) + d2 * cos(alpha1)

theta2 = Symbol('theta2')
# f2 = r - (2 * a1 * (k1 * cos(theta2) + k2 * sin(theta2)) + k3)
f2 = z - ((k1 * sin(theta2) - k2 * cos(theta2)) * sin(alpha1) + k4)
ans2 = solve([f2], ['theta2'])
ans2 = [ans2[i][0] for i in range(len(ans2))]
ans2_angle = [180 * ans2[i] / np.pi for i in range(len(ans2)) if ans2[i]>= -180.0 and ans2[i]<= 180.0]
print("可能的theta2值有:", ans2_angle)
print(ans2)

改换四个theta3的值,代码运行结果归纳如下:

theta2的可能值

  • theta3 == -3.05085107023123 (-174)
# 使用r条件
[-161.855697915037, -120.043627174960]  # angle
[-2.82491484173072, -2.09515654023959]  # radius
# 使用z条件
[-120.043627174960, 18.1443020849632]
[-2.09515654023959, 0.316677811859079]

所以该条件下,theta2 = -120.043627174960 (-2.09515654023959)

  • theta3 == -2.76034628749053 (-158)
# 使用r条件
[11.9128703903189, 49.5300174395328]
[0.207918811674406, 0.864461882890060]
# 使用z条件
[-130.469982560467, 11.9128703903189]
[-2.27713077069973, 0.207918811674406]

所以该条件下,theta2 = 11.9128703903189 (0.207918811674406)

  • theta3 == -0.616837009840437 (-35)
# 使用r条件
[-49.5300174395328, -11.9128703903189]
[-0.864461882890060, -0.207918811674406]
# 使用z条件
[-49.5300174395327, 168.087129609681]
[-0.864461882890058, 2.93367384191539]

所以该条件下,theta2 = -49.5300174395327 (-0.864461882890058)

  • theta3 == -0.326332227099740 (-18)
# 使用r条件
[120.043627174961, 161.855697915037]
[2.09515654023960, 2.82491484173071]
# 使用z条件
[-59.9563728250397, 161.855697915037]
[-1.04643611335020, 2.82491484173072]

所以该条件下,theta2 = 161.855697915037 (2.82491484173072)。
通过上述分析,将theta3和theta2的可能值都缩小到四个可能角度,其结果如下:

theta3和theta2的可能值

theta3 = [-3.05085107023123, -2.76034628749053, -0.616837009840436, -0.326332227099739]
theta2 = [-2.09515654023959, 0.207918811674406,  -0.864461882890058, 2.82491484173072]

接下来继续计算theta1值,与theta2情况相同,theta1受x, y 两个条件的限制,为了提高计算效率,分别在x和y条件下进行求解,最后归纳可能得theta1, theta2, theta3值。

# 计算theta1
ans = [-3.05085107023123, -2.76034628749053, -0.616837009840436, -0.326332227099739]
ans2 = [-2.09515654023959, 0.207918811674406,  -0.864461882890058, 2.82491484173072]

theta3 = ans[2]
theta2 = ans2[2]
f1 = a3 * cos(theta3) + d4 * sin(alpha3) * sin(theta3) + a2
f2 = a3 * cos(alpha2) * sin(theta3) - d4 * sin(alpha3) * cos(alpha2) * cos(theta3) \
     - d4 * sin(alpha2) * cos(alpha3) - d3 * sin(alpha2)
f3 = a3 * sin(alpha2) * sin(theta3) - d4 * sin(alpha3) * sin(alpha2) * cos(theta3) \
     + d4 * cos(alpha2) * cos(alpha3) + d3 * cos(alpha2)
# f1 = f1(theta3, a2, a3, alpha3, d4)
# print(f1)
g1 = cos(theta2) * f1 - sin(theta2) * f2 + a1
g2 = sin(theta2) * cos(alpha1) * f1 + cos(theta2) * cos(alpha1) * f2 - sin(alpha1) * f3 - d2 * sin(alpha1)


theta1 = Symbol('theta1')
# f3 = x - (cos(theta1) * g1 - sin(theta1) * g2)
f3 = y - (sin(theta1) * g1 + cos(theta1) * g2)
ans3 = solve([f3], [theta1])
ans3 = [ans3[i][0] for i in range(len(ans3))]
ans3_angle = [180 * ans3[i] / np.pi for i in range(len(ans3))]
print("可能的theta1值有:", ans3_angle)
print(ans3)

最后求得的结果归纳如下:

  • theta3 = -174, theta2 = -120
# 使用x条件
[-115.684399755326, 115.684399755326]
[-2.01907366892376, 2.01907366892376]
# 使用y条件

  • theta3 = -158, theta2 = 12
# 使用x条件
[-64.3156002446744, 64.3156002446744]
[-1.12251898466604, 1.12251898466604]
# 使用y条件
[64.3156002446746, 115.684399755325]
[1.12251898466604, 2.01907366892375]

得出可能的theta1 = 64

  • theta3 = -35, theta2 = -50
# 使用x条件
[-64.3156002446745, 64.3156002446745]
[-1.12251898466604, 1.12251898466604]

# 使用y条件
[64.3156002446744, 115.684399755326]
[1.12251898466604, 2.01907366892375]

得出的可能theta1 = 64

  • theta3 = -18, theta2 = 162
# 使用x条件
[-115.684399755326, 115.684399755326]
[-2.01907366892375, 2.01907366892375]

# 使用y条件

这里得出,可能的(theta3, theta2) = (-158, 12) / (-35, -50) 可能的theta1值为64,求解完毕。

p5p6p7
-158//-3512//-5064

P8.

在这里插入图片描述
代码求解如下:

from week03 import link_transformations as lt
import numpy as np
import math as mt

# link_transformation_function (alpha, a, theta, d)

# 先求出R_04 = R_01 * R_12 * R_23 * R_34
# 这里使用(theta3, theta2) = (-158, 12) / (-35, -50)
R_01 = lt.link_transformation_function(0, 0, 64, 0)
R_12 = lt.link_transformation_function(-90, -30, -50, 0)
R_23 = lt.link_transformation_function(0, 340, -35, 0)
alpha = np.pi * (-90) / 180
R_3_rotation_x = [[1, 0, 0, 0],
                  [0, np.cos(alpha), -np.sin(alpha), 0],
                  [0, np.sin(alpha), np.cos(alpha), 0],
                  [0, 0, 0, 1]]
R = np.dot(R_01, R_12)
R = np.dot(R, R_23)
R = np.dot(R, R_3_rotation_x)
R_03 = R[:3, :3]
print("R_03:\n", R_03)

# R_06已知
R_06 = [[-0.866, 0, 0.5],
        [0, -1, 0],
        [0.5, 0, 0.866]]

# 求取R_36
R_36 = np.dot(np.linalg.inv(R_03), R_06)
print(R_36)

# 利用Z-Y-Z求取theta4, theta5, theta6
r13 = R_36[0][2]
r23 = R_36[1][2]
r31 = R_36[2][0]
r32 = R_36[2][1]
r33 = R_36[2][2]

# 已知theta5可以有正负两解,分别求出两组解
theta5 = -mt.atan2(mt.sqrt(r31**2 + r32**2), r33)
theta4 = mt.atan2(r23 / mt.sin(theta5), r13 / mt.sin(theta5))
theta6 = mt.atan2(r32 / mt.sin(theta5), -r31 / mt.sin(theta5))

theta4_angle = theta4 * 180 / np.pi + 180
theta5_angle = theta5 * 180 / np.pi
theta6_angle = theta6 * 180 / np.pi + 180
print("第一组解:", theta4_angle, theta5_angle, theta6_angle)
print("第一组解:", theta4_angle, theta5_angle, theta6_angle-360)


theta5 = mt.atan2(mt.sqrt(r31**2 + r32**2), r33)
theta4 = mt.atan2(r23 / mt.sin(theta5), r13 / mt.sin(theta5))
theta6 = mt.atan2(r32 / mt.sin(theta5), -r31 / mt.sin(theta5))

theta4_angle = theta4 * 180 / np.pi + 180
theta5_angle = theta5 * 180 / np.pi
theta6_angle = theta6 * 180 / np.pi + 180
print("第二组解:", theta4_angle, theta5_angle, theta6_angle)
print("第二组解:", theta4_angle - 360, theta5_angle, theta6_angle - 360)

在求解时,T_03是按照D-H表达法的逻辑去求得的,而最后的T_34并不是实际的T_34,而是经过处理后符合“Z-Y-Z”旋转规范的T_34。
代码运行结果如下:
在这里插入图片描述
实际上最后可以看到,最后只求得一组有效的theta解,即
(theta1, theta2, theta3, theta4, theta5, theta6) = (64, -50, -35, 27, -82, -65),求解完成。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nn.BCEWithLogitsLoss中weight参数和pos_weight参数的作用及用法

nn.BCEWithLogitsLoss中weight参数和pos_weight参数的作用及用法 weight参数pos_weight参数 weight参数 上式是nn.BCEWithLogitsLoss损失函数的计算公式&#xff0c;其中w_n对应weight参数。 如果我们在做多分类任务&#xff0c;有些类比较重要&#xff0c;有些类不太重要&…

Java实现城市桥梁道路管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询城市桥梁4.2 新增城市桥梁4.3 编辑城市桥梁4.4 删除城市桥梁4.5 查询单个城市桥梁 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的城市桥梁道路管理系统&#xff0c;支持…

项目压测优化实践思路

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

Vue入门六(前端路由的概念与原理|Vue-router简单使用|登录跳转案例|scoped样式|混入(mixin)|插件)

文章目录 前要&#xff1a;前端路由的概念与原理1&#xff09;什么是路由2&#xff09;SPA与前端路由3&#xff09;什么是前端路由4&#xff09;前端路由的工作方式 一、Vue-router简单使用1&#xff09;什么是vue-router2) vue-router 安装和配置的步骤① 安装 vue-router 包②…

【MATLAB源码-第112期】基于matlab的IDMA系统仿真,输出误码率和误块率,采用turbo编码。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 IDMA&#xff08;交织多址接入&#xff09;系统详细描述 1. 基本原理&#xff1a; - IDMA是一种基于码分多址&#xff08;CDMA&#xff09;的通信技术&#xff0c;它通过为每个用户分配一个独特的交织模式来实现用户之间…

vue前端开发自学基础,动态切换组件的显示

vue前端开发自学基础,动态切换组件的显示&#xff01;这个是需要借助于&#xff0c;一个官方提供的标签&#xff0c;名字叫【Component】-[代码demo:<component :is"ComponetShow"></component>]。 下面看看代码详情。 <template><h3>动态…

eureka进行服务注册

1.引入依赖 在想要在eureka注册的服务的pom.xml文件中引入eureka客户端依赖 <!--eureka客户端依赖--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> …

canvas创建图像数据,并在画布上展示

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

QT上位机开发(进度条操作)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 进度条是一个比较常见的控件。如果某个操作需要很长的时间才能完成&#xff0c;那么这个时候最好有一个进度条提示&#xff0c;这样比较容易平复一…

价值7500的在线授权网站源码支持IP+域名+双向授权全开源

PHP授权验证更新系统完整版&#xff0c;一键更新系统&#xff0c;一键卡密生成自助授权功能&#xff0c;域名ip双重验证功能等等 修复盗版检测&#xff0c;确保实时查看盗版 修复在线加密系统&#xff0c;一键加密 授权系统几乎所有的程序都能整合使用,包括您的app和计算机程序…

OpenCV——八邻域断点检测

目录 一、理论基础1、八邻域2、断点检测 二、代码实现三、结果展示四、参考链接 OpenCV——八邻域断点检测由CSDN点云侠原创&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫。 一、理论基础 1、八邻域 图1 八邻域示意图 图…

debian12部署Gitea服务

首先安装git、wget、sqlite&#xff0c;然后进行用户和组的相关设置 sudo apt install -y git wget sqlite3 新增一个git用户与一个git组 sudo adduser --system --group --disabled-password --shell /bin/bash --home /home/git --gecos Git Version Control git 给git用户设…

Echarts 对饼状图上的各模块添加点击事件

文章目录 需求分析 需求 实现 echarts 中饼图点击区块事件 分析 当用户点击饼状图上的各个模块时&#xff0c;我们可以通过 JavaScript 监听 click 事件来实现相应的交互逻辑。 <!DOCTYPE html> <html> <head><meta charset"utf-8"><…

vmware16安装centos9stream

此次下载的是centos9 stream &#xff0c;使用vmware16。因为centos9stream版本比较新&#xff0c;所以vmware16无法识别此系统&#xff0c;不过无伤大雅。但是可能会导致兼容性问题&#xff0c;比如开机关机会很慢&#xff0c;建议还是用vmware17&#xff01; 下载镜像文件&a…

什么是MongoDB

概念&#xff1a; MongoDB 是一个文档数据库&#xff08;以 JSON 为数据模型&#xff09;&#xff0c;由 C 语言编写&#xff0c;旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中…

vue3-列表渲染

v-for 我们可以使用 v-for 指令基于一个数组来渲染一个列表。 v-for 指令的值需要使用 (item in items) 形式的特殊语法&#xff0c;其中 items 是源数据的数组&#xff0c;而 item 是迭代项的别名&#xff0c; (item, index) in items index 表示当前项的位置索引(可选参数)…

MySQL-多表联合查询

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

自带操作屏幕,还有AI附体的耳夹式耳机,Sanag塞那S5 Pro体验

如今耳机已经成为了我们生活中不可或缺的存在&#xff0c;很多朋友都喜欢那种能让自己获得身临其境的听觉体验的耳机。但是&#xff0c;传统的入耳式耳机常常会导致耳朵不适&#xff0c;而且特别不适合在户外使用。我最近发现了一款设计很特殊的耳机&#xff0c;就是这副sanag塞…

部署Tomcat

Tomcat简介 名称由来&#xff1a;Tomcat最初是由 Sun的软件构架师詹姆斯邓肯戴维森开发的&#xff0c;后来他帮助将其变 为开源项目&#xff0c;并由Sun贡献给Apache软件基金会&#xff0c;由于大部分开源项目OReilly都会出一本相关的 书&#xff0c;并且将其封面设计成某个动物…

深度解析JVM类加载器与双亲委派模型

概述 Java虚拟机&#xff08;JVM&#xff09;是Java程序运行的核心&#xff0c;其中类加载器和双亲委派模型是JVM的重要组成部分。本文将深入讨论这两个概念&#xff0c;并解释它们在实际开发中的应用。 1. 什么是类加载器&#xff1f; 类加载器是JVM的一部分&#xff0c;负…
最新文章