10_机械臂运动学_机械臂C++逆解——2023

就是算!

遨博机械臂改进DH参数表:

b3f670aacd0b66d7e5f8da4915cc13dc.png

机械臂正运动学连杆变换通式:

其中si代表sin(θi),ci代表cos(θi)

sij代表sin(θi-θj),cij代表cos(θi-θj)

sijk代表sin(θi-θj+θk),cijk代表cos(θi-θj-+θk),用两角和差公式直接展开即可.

8727a31a2848b10a990556fd3e20aa00.jpeg

每一个连杆变换矩阵:

8fdbfc27b0988c3fe14926ffa7d36dac.jpeg

91241f1229c5c1dea1ad05ab32c189ad.jpeg

7a0e89dddbcfb6f43e91d0625fcd30e3.jpeg

06T中第四列的前三行数据就是机器人末端连杆在笛卡儿坐标系里的位置参数,前面3*3矩阵表示姿态。

则:f6c9bdd227920efe9bcf829b45961a71.jpeg

矩阵关系式构建按照《机器人学导论》中的流程:

0618a0bc004b5a0cd1205afd5e2bbb47.jpeg

18d6b95b1613d954aaa84b40685785e7.jpeg

8a93af7e04a356e053e4419588028d7e.jpeg

533e040700fbb2b7c8a1922f192af57f.jpeg

因为关节2和关节3通常是平行的,所以和的乘积用二角和差公式将得到一个简化的表达式。只要两个旋转关节轴平行就可以这样处理,则:

2a31754fce970b0541f457e5c4a0b5a5.jpeg

则:

608c06cc1e8b87d3951b960f1a299441.jpeg

b211ce47900f6c7ecea22b40cfd0ebfd.jpeg

       上式构成了aubo机械臂的运动学方程。它们说明如何计算机器人坐标系{6}相对于坐标系{0}的位姿。上述方程式是aubo机械臂全部运动学分析的基本方程。

计算前公式准备:

-As1 + Bc1 = C                                                                         (3)

解该类型方程通常用三角换元,即:

A =ρcosφ

B =ρsinφ

Φ = atan2(B,A )

则:

d8586bd5a557fab9da2d887ee1e11c4d.jpeg

注意,该式有两个解。

sinθ = A

cosθ = B

则:

θ = atan2(A, B)                                                                          (5)

上述准备工作完成后,下面就是解方程计算,体力活,没啥技巧。

求解θ1:

根据(1)第二行第四列与r24相等,则:

-s1px + c1py = c5d6 + d2

根据(2),c5=r23,

c5 = -s1ax + c1ay,消去c5,

-(px - axd6)s1 + (py - d6ay) = d2                                              (6)

A = px - axd6

B = py - d6ay

C = d2

再根据(3),直接使用(4),则θ1可解且有两种可能。

求解θ5:

根据(1)第二行第三列与r23相等,则:

-s1ax + c1ay = c5

则:

537c7b3dd616d52b86262477678325c4.jpeg

带入公式(5),则:

θ5也有两个解,此时有4组理论解了。

求解θ6:

根据(1)第二行第一列与r21相等,则:

-s1nx + c1ny = -s5c6

根据(1)第二行第二列与r31相等,则:

-s1ox + c1oy = s5s6

由于s1c1s5已知,根据公式(5)则θ6可求.

求θ6时,带入对应的θ1θ5,不会产生新解。

求解θ234:

根据(1)第一行第三列与r13相等,则:

-s1ax + c1ay = c234s5

根据(1)第三行第三列与r33相等,则:

az = -s234s5

根据公式(5),可得θ234整体值。

注意,该值为计算理论值,但并非电机所转动的角度,即并不是示教器所显示的当前关节角。

求解θ2:

根据(1)第一行第四列与r14相等,则:

c1px + s1py = c234s5d6 - s234d5 + c23a3 + c2a2                     (7)

根据(1)第三行第四列与r34相等,则:

pz - d1 = -s234s5d6 -c234d5 - s23a3 -s2a2                                (8)

A = c234s5d6 - s234d5 + c23a3 + c2a2

B = -s234s5d6 -c234d5

C = c1px + s1py

D = pz - d1

则,(7) (8)化简为:

C = A + c23a3 + c2a2

D = B - s23a3 - s2a2

则:

c23a3 = C - A -c2a2

s23a3 = B - D -s2a2

M = C - A

N = B - D

则:

s23 = (N - s2a2)/a3                                                                 (9)

c23 = (M-c2a2)/a3                                                                  (10) 

将上述等式化简整理,得

-(-2Na2)s2 + 2Ma2c2 = M*M + N*N + a2*a2 - a3*a3              (11)

再令:

E= -2Na2

F= 2Ma2

G = M*M + N*N + a2*a2 - a3*a3

则根据公式(4),解得θ2.会有两种可能.故理论上2*2*2八组解。

根据(9)(10)与公式(5),得θ23值

则,根据θ234

θ4 = θ234 - θ23

θ3 = θ23 - θ2

不产生额外解。

部分验证程序如下:

//    Target <<  -0.687943   0.724766  0.0380584     214.3
//               0.725342    0.688386  0.00196604   -138.937
//              -0.0247739    0.0289579  -0.999274    200.473
//                      0          0          0          1;


    double px= 214.3;
    double py= -138.937;
    double pz= 200.473;
    double ax =  0.0380584;
    double ay = 0.00196604;
    double az = -0.999274;
    double ox = 0.724766;
    double oy = 0.688386;
    double nx = -0.687943;
    double ny = 0.725342;




    //get θ1
    //1 T01^-1
    //-s1*px + c1*py = c5*d6 + d2
    //c5 = -s1*ax + c1*ay
    //-(d6*ax + px)s1 + (py - d6*ay) = d2


    //-As1 + Bc1 = C
    //θ  =  atan2(B,A) - atan2(C, ±sqrt(A*A + B*B - C*C))




    double th1=0.0;
    double d1 = 98.50;
    double d2 = 121.50;
    double d5 = 102.50;
    double d6 = 94.0;
    double a2= 408.0;
    double a3= 376.0;
    double A = px - d6*ax;
    double B = py - d6*ay;


    double tmp1 = A*A + B*B - d2*d2;
    double tmp = sqrt(tmp1);
    //get θ1
    th1 = std::atan2(B,A) - std::atan2(d2, -tmp);
    std::cout << "joint1 ori: >>> " << ((th1)*ARC_TO_DEG) << std::endl;
    std::cout << "joint1 >>> " << ((th1 + M_PI)*ARC_TO_DEG) << std::endl;


    //get θ5
    double th5=0.0;
    tmp = -sin(th1)*ax + cos(th1)*ay;
    th5 = std::atan2(-sqrt(1-tmp*tmp), tmp);
    std::cout << "joint5 >>> " << (th5)*ARC_TO_DEG << std::endl;


    //get θ6
    double th6=0.0;
    th6 = std::atan2((-sin(th1)*ox + cos(th1)*oy)/sin(th5),
                     (sin(th1)*nx - cos(th1)*ny)/sin(th5));
    std::cout << "joint6 >>> " << (th6)*ARC_TO_DEG << std::endl;


    //get θ2-θ3+θ4 ===============
    double th234=0.0;
    tmp = (cos(th1)*ax+sin(th1)*ay)/sin(th5);
    tmp1 = -(az/sin(th5));
    th234 = std::atan2(tmp1, tmp);  //-?
    std::cout << "joint234 sum : >>> " << (th234)*ARC_TO_DEG << std::endl;


           A =  cos(th234)*sin(th5)*d6 - sin(th234)*d5;
           B = -sin(th234)*sin(th5)*d6 - cos(th234)*d5;    // shao d6
    double C = cos(th1)*px + sin(th1)*py;
    double D = pz -d1;
    double M = C - A;
    double N = B - D;
    double E = -2*N*a2;
    double F = 2*M*a2;
    double G = M*M + N*N +a2*a2 -a3*a3;


    double th2 = 0.0;
    th2 = std::atan2(F,E) - std::atan2(G, sqrt(E*E+F*F-G*G));
    std::cout << "joint2 ori: >>> " << ((th2)*ARC_TO_DEG) << std::endl;
    std::cout << "joint2 >>> " << ((th2+M_PI/2)*ARC_TO_DEG) << std::endl;


//    th2 = std::atan2(F,E) - std::atan2(G, -sqrt(E*E+F*F-G*G));
//    std::cout << "another joint2 ori: >>> " << ((th2)*ARC_TO_DEG) << std::endl;
//    std::cout << "another joint2 >>> " << ((th2-M_PI/2)*ARC_TO_DEG) << std::endl;


    double th2_3 = 0.0;
    th2_3 = std::atan2((N-sin(th2)*a2)/a3, (M-cos(th2)*a2)/a3);
    double th3 = 0.0;
    double th4 = 0.0;
    th3 = -(th2_3 -th2);
    th4 = th234 - th2_3 ;
    std::cout << "joint3 ori: >>>: >>> " << ((th3)*ARC_TO_DEG) << std::endl;
    std::cout << "joint4 ori:>>> " << ((th4)*ARC_TO_DEG) << std::endl;
    std::cout << "joint3 >>>: >>> " << ((th3+2*M_PI)*ARC_TO_DEG) << std::endl;
    std::cout << "joint4 >>> " << ((th4+M_PI/2)*ARC_TO_DEG) << std::endl;

关注公众公众号,后台留言“C++逆解验证”获取完整程序!

0e5c4da321405a8fb662b3bf8558114e.png

往期机械臂系列精彩回顾:

机械臂运动学正解验证

Matlab机械臂运动学示教演示

机械臂运动学D-H参数学习笔记(2)

3_机械臂运动学之刚体的运动

4_机械臂运动学基础向量空间

5_机械臂运动学基础_矩阵

6_机械臂运动学_刚体转动的描述

9_机械臂运动学_正解C++推导验证

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

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

相关文章

如何获取气象数据

问题 如何获取气象数据 详细问题 笔者使用NOAA获取部分气象数据&#xff0c;但是涉及字段有限&#xff0c;如何获取更丰富的气象数据&#xff0c;譬如包括太阳辐射、温度、湿度、云覆盖等信息呢&#xff1f; 解决方案 步骤1、访问https://power.larc.nasa.gov/data-access…

财务数据处理问题及解决方案分享

一、平台介绍 财务自营计费主要承接京东自营数据在整个供应链中由C端转B端的功能实现&#xff0c;在整个供应链中属于靠后的阶段了&#xff0c;系统主要功能是计费和向B端的汇总。 二、问题描述 近年来自营计费数据量大增&#xff0c;有百亿的数据量&#xff0c;一天中汇总占…

【Linux】信号-下

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;信号递达&#xff0c;信号未决&#x…

软考20-上午题-串及其模式匹配

串&#xff08;字符串&#xff09;是一种特殊的线性表&#xff0c;其数据元素为字符。如&#xff1a;"abc"。 一、串的定义 由字符构成的有限序列&#xff0c;是一种线性表。 串的比较&#xff1a;以字符的ASCII值作为依据。比较操作从两个字符串的第一个字符开始&a…

Openresty+Lua+Redis实现高性能缓存

一、背景 当我们的程序需要提供较高的并发访问时&#xff0c;往往需要在程序中引入缓存技术&#xff0c;通常都是使用Redis作为缓存&#xff0c;但是要再更进一步提升性能的话&#xff0c;就需要尽可能的减少请求的链路长度&#xff0c;比如可以将访问Redis缓存从Tomcat服务器…

4. 树(二叉树、二叉查找树/二叉排序树/二叉搜索树、平衡二叉树、平衡二叉B树/红黑树)

树 1. 二叉树1.1 概述1.2 特点1.3 二叉树遍历方式1.3.1 前序遍历(先序遍历)1.3.2 中序遍历1.3.3 后序遍历1.3.4 层序遍历 2. 二叉查找树&#xff08;二叉排序树、二叉搜索树&#xff09;2.1 概述2.2 特点 3. 平衡二叉树3.1 概述3.2 特点3.3 旋转3.3.1 左旋3.3.2 右旋 3.4 平衡二…

Quartus IP 之mif与hex文件创建与使用

一、mif与hex概述 ROM IP的数据需要满足断电不丢失的要求&#xff0c;ROM IP数据的文件格式一般有三种文件格式&#xff1a;.mif、.hex、.coe&#xff0c;Xilinx与Intel Altera支持的ROM IP数据文件格式如下&#xff1a; Xilinx与Altera支持的ROM文件格式 Alterahex、mifAM&am…

JS第二天、原型、原型链、正则

☆☆☆☆ 什么是原型&#xff1f; 构造函数的prototype 就是原型 专门保存所有子对象共有属性和方法的对象一个对象的原型就是它的构造函数的prototype属性的值。prototype是哪来的&#xff1f;所有的函数都有一个prototype属性当函数被创建的时候&#xff0c;prototype属性…

项目02《游戏-08-开发》Unity3D

基于 项目02《游戏-07-开发》Unity3D &#xff0c; 本次任务做物品相互与详情的功能&#xff0c; 首先要做 点击相应&#xff0c; 接下来用接口实现点击相应事件&#xff0c;具体到代码中&#xff0c;我们找到需要响应鼠标事件的对象&#xff0c; 双击PackageCell…

食堂预约系统

文章目录 前言​部分沟通内容技术点小程序功能部分代码段功能图 商家管理系统功能说明功能图登录页面商家管理页面 食品管理订单管理其他功能 结束语 前言​ 最近&#xff0c;接了个小项目——学校食堂预约取餐系统。 具体需求如下图&#xff1a; 部分沟通内容 技术点 系统…

C++:模板初阶

泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段。模板是泛型编程的基础。 函数模板 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定类型版本。…

百面嵌入式专栏(面试题)网络编程面试题

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍网络编程面试题 。 1、什么是IO多路复用 I/O多路复用的本质是使用select,poll或者epoll函数,挂起进程,当一个或者多个I/O事件发生之后,将控制返回给用户进程。以服务器编程为例,传统的多进程(多线程…

antv/x6 边添加鼠标悬浮高亮和删除功能

antv/x6 边添加鼠标悬浮高亮和删除功能 效果添加悬浮效果和删除工具取消悬浮效果边删除后的回调函数 效果 添加悬浮效果和删除工具 this.graph.on(edge:mouseenter, ({ cell }) > {let cellId cell.store.data.source.celllet sourceCell _this.graph.getCellById(cellId…

绝地求生:盘点游戏内七款真人脸模,你最喜欢哪款?

从27.1版本更新后&#xff0c;游戏内上线了荣都地图代言人吴彦祖和李政宰的真人脸模&#xff0c;从此闲游盒的各位盒友灵魂搭配的资源库里又多了两位英俊脸庞&#xff0c;那么今天闲游盒来盘点一下游戏内上线的七款真人脸模&#xff0c;看看大家更喜欢哪款呢? 吴彦祖和李政宰 …

CSS-IN-JS

CSS-IN-JS 为什么会有CSS-IN-JS CSS-IN-JS是web项目中将CSS代码捆绑在JavaScript代码中的解决方案。 这种方案旨在解决CSS的局限性&#xff0c;例如缺乏动态功能&#xff0c;作用域和可移植性。 CSS-IN-JS介绍 1&#xff1a;CSS-IN-JS方案的优点&#xff1a; 让css代码拥…

【MySQL】DQL的总结和案例学习

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-VWRkWqFrRMi4uLRa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

bert分类模型使用

使用 bert-bert-chinese 预训练模型去做分类任务&#xff0c;这里找了新闻分类数据&#xff0c;数据有 20w&#xff0c;来自https://github.com/649453932/Bert-Chinese-Text-Classification-Pytorch/tree/master/THUCNews 数据 20w &#xff0c;18w 训练数据&#xff0c;1w 验…

挑战!贪吃蛇小游戏的实现(1)

引言 相信大家都玩过贪吃蛇这个游戏&#xff01; 玩家控制一个不断移动的蛇形角色&#xff0c;在一个封闭空间内移动。随着时间推进&#xff0c;这个蛇形角色会逐渐增长&#xff0c;通常是通过吞食屏幕上出现的物品&#xff08;如点或者其他标志&#xff09;来实现。每当贪吃…

JQuery动态插入Bootstrap模态框(Modal)

这里所说的动态插入&#xff0c;是指用JS的append()方式追加元素内容&#xff0c;而不是静态写在HTML里面。 为什么会用到这种方式呢&#xff1f;比如登录框。有些网站在大部分页面都有登录按钮&#xff0c;如果是用Bootstrap的模态框调用的话&#xff0c;常规方式都是写在HTM…

目标检测及相关算法介绍

文章目录 目标检测介绍目标检测算法分类目标检测算法模型组成经典目标检测论文 目标检测介绍 目标检测是计算机视觉领域中的一项重要任务&#xff0c;旨在识别图像或视频中的特定对象的位置并将其与不同类别中的对象进行分类。与图像分类任务不同&#xff0c;目标检测不仅需要…