机器人学、机器视觉与控制 上机笔记(第一版译文版 2.1章节)
机器人学、机器视觉与控制 上机笔记(第一版译文版 2.1章节)
- 1、前言
- 2、本篇内容
- 3、代码记录
- 3.1、新建se2
- 3.2、生成坐标系
- 3.3、将T1表示的变换绘制
- 3.4、完整绘制代码
- 3.5、获取点`*`在坐标系1下的表示
- 3.6、相对坐标获取完整代码
- 4、结语
1、前言
工作需要,想同时显示出六轴协作臂,一组位姿信息逆解出的八组关节角的效果情况。就想使用MATLAB的机器人工具箱RTB去实现这一需求,辅助数据分析。朋友推荐了《机器人学、机器视觉与控制》这本书,书的作者也是工具箱RTB的作者,就开始拜读补充基础知识,并结合书中的RTB示例代码熟悉RTB的使用。个人使用的matlab2022b版本和10.4版本的RTB,实际操作时发现书本中的示例代码(猜测应该是9版本的RTB,语法未做到向下兼容)在个人使用的环境下,频繁出现报错无法运行的问题。就准备写一个改正后的实机运行记录系列。
2、本篇内容
记录书中第2.1章节中的示例代码,修改后能在10.4版本中正确运行。
3、代码记录
3.1、新建se2
原书中的第一步是用函数se2创建一个齐次变换,原书代码如下:
>> T1 = se2(1, 2, 30 * pi / 180)
T1 = 0.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000
在高位版本环境
下,运行报错,原因是se2
的函数形参变动调整了
>> T1 = se2(1, 2, 30 * pi / 180)
错误使用 matlabshared.spatialmath.internal.SE2Base
Invalid number of arguments. To create an se2, specify 2 or fewer arguments.出错 se2 (第 69 行)obj@matlabshared.spatialmath.internal.SE2Base(varargin{:});
下面我们来看看help文档中,高版本的se2
函数定义:
原书中是位移在前,旋转在后,高版本恰恰相反了。因此,新建se2
需要修改为(可能步骤有些繁琐,欢迎评论区留言优化):
>> tr = [1, 2]tr =1 2
>> rot = rotz(30)rot =0.8660 -0.5000 00.5000 0.8660 00 0 1.0000>> T1 = se2(rot(1:2, 1:2), tr)T1 = se20.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000
3.2、生成坐标系
这个没有问题,同原书一样即可,生成一个XY轴分别为[0,5]刻度的二维平面坐标系。
>> axis([0 5 0 5]);
3.3、将T1表示的变换绘制
原书代码如下:
>> trplot2(T1, 'frame', '1', 'color', 'b')
在高位版本
下,同样运行报错,报错提示如下:
>> trplot2(T1, 'frame', '1', 'color', 'b')
Unable to perform assignment because value of type 'se2' is not convertible to 'double'.出错 transl (第 88 行)t1(1:3,4,:) = x';出错 trplot2 (第 148 行)if all(size(T) == [3 3]) || norm(transl(T)) < eps原因:无法从 se2 转换为 double。
根据报错提示,T1
此时是se2
数据类型,而高版本
的trplot2
函数的第一个形参,要求数据类型为double
,那么,此处需要手动进行数据类型转换。可以参考该链接: (知乎)matlab中SE3是什么类型,怎么转换成double型矩阵?
经过实际尝试,使用tform
函数有效,转换如下:
>> T1_double = tform(T1)T1_double =0.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000
工作区中也可以观察到,数据类型变换成功。
这边需要再多说几句,知乎回答中提及的T1.T
方式尝试过,报错未识别类 'se2' 的方法、属性或字段 'T'。
,提及的另一种double(T1)
强制转换的方式也同样以失败告终。之后翻阅了tform
函数的文档看了一下,该函数应该是2022b版本以后引入的。
最终运行效果如下,记得补加上hold on
,原书中缺失,不然坐标轴刻度变化,不再是[0,5]:
>> T1_double = tform(T1)T1_double =0.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000
>> hold on
>> trplot2(T1_double, 'frame', '1', 'color', 'b')
3.4、完整绘制代码
>> tr = [1, 2]tr =1 2>> rot = rotz(30)rot =0.8660 -0.5000 00.5000 0.8660 00 0 1.0000>> T1 = se2(rot(1:2, 1:2), tr)T1 = se20.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000>> axis([0 5 0 5]);
>> T1_double = tform(T1)T1_double =0.8660 -0.5000 1.00000.5000 0.8660 2.00000 0 1.0000>> hold on
>> trplot2(T1_double, 'frame', '1', 'color', 'b')
>> rot2 = rotz(0)rot2 =1 0 00 1 00 0 1>> tr2 = [2, 1]tr2 =2 1>> T2 = se2(rot2(1:2, 1:2), tr2)T2 = se21 0 20 1 10 0 1>> T2_double = tform(T2)T2_double =1 0 20 1 10 0 1>> hold on
>> trplot2(T2_double, 'frame', '2', 'color', 'r');
>> T3 = T1 * T2T3 = se20.8660 -0.5000 2.23210.5000 0.8660 3.86600 0 1.0000>> T3_double = tform(T3)T3_double =0.8660 -0.5000 2.23210.5000 0.8660 3.86600 0 1.0000>> hold on;
>> trplot2(T3_double, 'frame', '3', 'color', 'g');
>> T4 = T2 * T1T4 = se20.8660 -0.5000 3.00000.5000 0.8660 3.00000 0 1.0000>> T4_double = tform(T4)T4_double =0.8660 -0.5000 3.00000.5000 0.8660 3.00000 0 1.0000>> hold on
>> trplot2(T4_double, 'frame', '4', 'color', 'c')
>> hold on;
>> P = [3; 2];
>> plot_point(P, '*');
最终效果如下:
3.5、获取点*
在坐标系1下的表示
原书中的inv
,在高版本使用时同样需要注意数据类型一致的问题:
% 原书中使用的变量名为P1
% 个人使用P_to_T1替换,感觉变量名意义更清晰明了些
>> P_to_T1 = inv(T1) * [P; 1]
错误使用 .*
times, .* requires both operands to be transformations or rotations (of the same type).出错 * (第 18 行)out = obj1 .* obj2;
报错原因为左侧inv(T1)
的结果仍为se2
类型,需要变为double
类型。验证如下:
>> Test = inv(T1)Test = se20.8660 0.5000 -1.8660-0.5000 0.8660 -1.23210 0 1.0000>> Test_double = tform(Test)Test_double =0.8660 0.5000 -1.8660-0.5000 0.8660 -1.23210 0 1.0000>> P_to_T1 = Test_double * [P; 1]P_to_T1 =1.7321-1.00001.0000
成功获取,点*
相对于坐标系{1}的表示为(1.7321,-1.0000)。
3.6、相对坐标获取完整代码
>> Test = inv(T1)Test = se20.8660 0.5000 -1.8660-0.5000 0.8660 -1.23210 0 1.0000>> Test_double = tform(Test)Test_double =0.8660 0.5000 -1.8660-0.5000 0.8660 -1.23210 0 1.0000>> P_to_T1 = Test_double * [P; 1]P_to_T1 =1.7321-1.00001.0000>> h2e(Test_double * e2h(P))ans =1.7321-1.0000>> homtrans(Test_double, P)ans =1.7321-1.0000>> P_to_T2 = homtrans(tform(inv(T2)), P)P_to_T2 =11
4、结语
平时工作为机械臂软件开发,书本中的matlab示例代码跑通的感觉还是挺舒服的。2.1节总体评价不错,通过二维演示了三维常见的齐次变换大致的使用思想。减去Z的维度,确实更方便初学者的理解。工作一年多,回过头来再看这些内容,也受益匪浅。
相关文章:

机器人学、机器视觉与控制 上机笔记(第一版译文版 2.1章节)
机器人学、机器视觉与控制 上机笔记(第一版译文版 2.1章节) 1、前言2、本篇内容3、代码记录3.1、新建se23.2、生成坐标系3.3、将T1表示的变换绘制3.4、完整绘制代码3.5、获取点*在坐标系1下的表示3.6、相对坐标获取完整代码 4、结语 1、前言 工作需要&a…...
关于vue2+antd 信息发布后台不足的地方
有的写法可以cv 1.序号递增 {title: "序号",customRender: (text, record, index) > ${index 1},align: "center",}, 2.关于类型 {title: "类型",dataIndex: "type",align: "center",customRender: function (t) {sw…...
Ubuntu+Anaconda 常用指令记录
Anaconda 使用指令记录 1 创建环境 conda create -n name pythonx.x(python版本自己指定)例如 conda create --name myenv: 创建名为"myenv"的新环境。 conda activate myenv: 激活名为"myenv"的环境。 conda deactivate: 退出当前环境。 2 删除环境 c…...
P5732 【深基5.习7】杨辉三角 python解法
# 【深基5.习7】杨辉三角 ## 题目描述 给出 n<20,输出杨辉三角的前 n 行。 如果你不知道什么是杨辉三角,可以观察样例找找规律。 ## 输入格式 ## 输出格式 ## 样例 #1 ### 样例输入 #1 6 ### 样例输出 #1 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5…...

VitePress-12-markdown中使用vue的语法
前言 VitePress 中,markdown文档最终都会转换成为 html文件,我们在访问的时候,也是直接访问的 xxx.html 文件。而且,markdown文档会被作为 [vue单文件] 进行处理,因此,我们我们可以在文档中使用 vue 语法&…...

“bound drug/molecule”or “unbound drug/molecule”、molecule shape、sketching是什么?
“bound drug/molecule”or “unbound drug/molecule” For clarity, the following terms will be used throughout this study: “bound drug/molecule” (or “unbound drug/molecule”) refers to the drug/molecule that is bound (or unbound) to proteins [48]. 意思就是…...
深入理解C语言中的函数指针:概念、机制及实战应用
在C语言的世界里,函数是一等公民,可以被赋值给变量,这种特殊的变量就是我们今天要探讨的主角——函数指针。函数指针作为C语言中一种强大的工具,允许我们以间接方式调用函数,从而实现动态绑定、回调函数、策略模式等多…...

《UE5_C++多人TPS完整教程》学习笔记1 ——《P2 关于本课程(About This Course)》
本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P2 关于本课程(About This Course)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者&…...

权限系统设计
权限系统设计 RBAC 基于角色的访问控制 ABAC 基于属性的访问控制 普通的系统无非 CRUD,那系统如何控制一个用户该看到哪些数据、能操作哪些功能?日常开发中最常用到 RBAC 和 OAuth2 这两种访问控制和授权方案 RBAC 基于角色的访问控制 所有的访问控制模…...

Ubuntu Desktop - Screenshot (截图工具)
Ubuntu Desktop - Screenshot [截图工具] 1. Search your computer -> Screenshot -> Lock to Launcher2. gnome-screenshot3. System Settings -> Keyboard -> ShortcutsReferences 1. Search your computer -> Screenshot -> Lock to Launcher 2. gnome-s…...

docker 1:介绍
docker 1:介绍 docker解决哪些问题: 传统APP在安装到不同电脑的时候可能会遇到依赖问题,比如缺少VS 20xx,软件无法运行”的情况。docker使用容器技术将软件 依赖打包为image包发布,解决了依赖问题。docker有一个官…...
RibbonBar RibbonPage切换事件
在开发的过程中,我们会用到点击切换page,来响应对应的事件,例如以下事件: 头文件中: void ribboncurrentPageIndexChanged(int index); 实现文件中: connect(ribbonBar(), SIGNAL(currentPageIndexChang…...

Conda历史版本下载地址和python对应关系
一、前言 因为Conda安装版本问题,带来了很多问题,虽然不能直接确定二者之间的关系,但是安装指定版本的conda,确实是一个比较好的方法。特此记忆。 二、下载地址 下载最新版本:Free Download | Anaconda 下载历史版本ÿ…...
Clickhouse查询语句执行过程
问题 简述clickhosue中一条select语句的执行过程,使用的引擎是ReplacingMergeTree。例如: select col1,col2 from table final prewhere col3 > ? and col4 ? and col5 ? -- col3为分区键,col4为二级索引,col5为主键字段 where col…...

【动态规划】【中位数】【C++算法】1478. 安排邮筒
# 作者推荐 【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目 本文涉及知识点 动态规划汇总 LeetCode1478. 安排邮筒 给你一个房屋数组houses 和一个整数 k ,其中 houses[i] 是第 i 栋房子在一条街上的位置,现需要在这条街上安排 k…...
C#系列-数据结构+递归算法+排序算法(3)
C#数据结构 在C#中,数据结构是用于组织和管理数据的方式,以便更有效地进行数据的存储、访问和操作。数据结构对于算法的性能和设计至关重要,因为它们决定了数据如何在内存中布局以及如何与算法进行交互。C#提供了许多内置的数据结构…...
Redis实现秒杀
前期准备 缓存选择考虑 Redis和Redis Cluster(分布式版本),是一个分布式缓存系统。其支持多种数据结构,也支持MQ。Redis在性能上做了大量优化。因此使用Redis或者Redis Cluster就可以轻松实现一个强大的秒杀系统。 用Redis的这…...
4 scala集合-Map
和 Java 一样,Scala 也有表示键值对(Key-Value)集合的 Map 数据结构。同样,Map 也分不可变和可变,不可变需要使用类 scala.collection.mutable.Map。 1 不可变 Map 可以使用以下语法定义不可变 Map 对象 val/var ma…...
QT 对象树模型
QObject是Qt里边绝大部分类的根类 QObject对象之间是以对象树的形式组织起来的。 当两个QObject(或子类)的对象建立了父子关系的时候。子对象就会加入到父对象的一个成员变量叫children(孩子)的list(列表)…...

ubuntu快速安装miniconda
ubuntu快速安装miniconda 环境 ubuntu.22.04 显卡 RTX 3050 关于选择Miniconda还是Anaconda的问题,Anaconda安装包比较大,耗时比较长,如果你是绝对的初学者,选择Anaconda会比较稳妥一些;否则建议你还是选择Miniconda安…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...