V-rep学习笔记:机器人逆运动学数值解法(The Pseudo Inverse Method)
There are two ways of using the Jacobian matrix to solve kinematics. One is to use the transpose of the Jacobian JT. The other is to calculate the inverse of the Jacobian J-1. J is most likely redundant and non square,thus an ordinary inverse is not possible. We can try using the pseudo inverse to find a matrix that effectively inverts a non square matrix. J+ is the pseudoinverse of J, also called the Moore-Penrose inverse of J . It is defined for all matrices J , even ones which are not square or not of full row rank.
雅可比矩阵将关节空间速度映射到直角坐标空间:ΔP = J(θ)Δθ。对于机器人运动学逆解来说可以考虑求雅克比矩阵J的逆,然后根据Δθ=J(θ)-1ΔP计算出关节角变动量并反复迭代。然当很多情况下J不可逆,因此可以考虑求其广义逆(Moore-Penrose逆)来求解方程。设A∈Cm×n,b∈Cm,则线性方程组Ax=b有解的充分必要条件是AA+b=b,且通解为x=A+b + (I-A+A)y (y∈Cn任意),并且它的唯一极小范数解为x0 = A+b(矩阵论简明教程 P150 A+在解线性方程组中的应用)。根据矩阵论(《矩阵论简明教程 第二版》 科学出版社 第6章 广义逆矩阵),设J为m×n阶实矩阵,当rankJ=m时,有J+ = JT(J JT)-1;而当rankJ=n时,有J+ = (JTJ )-1 JT,此时方程组J(θ)Δθ=ΔP的解唯一。 对一般机器人来说n≥m,且rankJ=m,即有J+ = JT(J JT)-1。当n>m,即机构驱动数目多于末端自由度时,会出现多解的情况,pseudo inverse方法会寻找解向量中长度最小的一个(无穷多个解中2范数最小的解,即||Δθ0||2=min||Δθ||2,称为极小范数解)
Let ΔP be e = t - P,where t is the target position,P is the end effector position and e is the desirable change of the end effector. The first iteration will result in a new θ from equation Δθ=J(θ)-1ΔP. By using forward kinematics a new position P of the end effector is acquired and a new iteration begins. This is done until either e is small enough or the end effector does not move. 使用Pseudo Inverse方法求机器人逆解的基本步骤如下所示:

Operating Principle:
1. Shortest path in q-space
Advantages:
1. Computationally fast (second order method)
Disadvantages:
1. Matrix inversion necessary (numerical problems)
2. Unpredictable joint configurations
3. Non conservative
The pseudoinverse tends to have stability problems in the neighborhoods of singularities. At a singularity, the Jacobian matrix no longer has full row rank, corresponding to the fact that there is a direction of movement of the end effectors which is not achievable. If the configuration is exactly at a singularity, then the pseudoinverse method will not attempt to move in an impossible direction, and the pseudoinverse will be well-behaved. However, if the configuration is close to a singularity, then the pseudoinverse method will lead to very large changes in joint angles, even for small movements in the target position. In practice, roundoff errors mean that true singularities are rarely reached and instead singularity have to be detected by checking values for being near-zero. 对于平面二连杆机构,当θ2趋近于0°或180°时,机械手接近奇异形位,关节J2速度将趋于无穷大。(参考John J.Craig. Introduction to Robotics: Mechanics and Control Chapter 5-->Section 5.8 Singularities)
下面使用同样的模型验证Pseudo Inverse方法。从输出窗口可以看出,该方法迭代次数相比Jacobian Transpose法明显减少(迭代5次就达到精度要求)。The Jacobian pseudoinverse method is equivalent to solving by Newton's method.(相当于牛顿法)。Jacobian transpose is also related to solution by the method of steepest descent.(相当于最速降法或梯度法)。牛顿法是梯度法的进一步发展,梯度法在确定搜索方向时只考虑目标函数在迭代点的局部性质,即只利用一阶偏导数的信息,而牛顿法进一步利用了目标函数的二阶偏导数,考虑了梯度的变化趋势,因而可以更为全面的确定合适的搜索方向,以便很快的搜索到极小点。

import vrep #V-rep library
import sys
import time
import math
import numpy as np # Starts a communication thread with the server (i.e. V-REP).
clientID=vrep.simxStart('127.0.0.1', 20001, True, True, 5000, 5) # clientID: the client ID, or -1 if the connection to the server was not possible
if clientID!=-1: #check if client connection successful
print 'Connected to remote API server'
else:
print 'Connection not successful'
sys.exit('Could not connect') # Exit from Python # Retrieves an object handle based on its name.
errorCode,J1_handle = vrep.simxGetObjectHandle(clientID,'j1',vrep.simx_opmode_oneshot_wait)
errorCode,J2_handle = vrep.simxGetObjectHandle(clientID,'j2',vrep.simx_opmode_oneshot_wait)
errorCode,target_handle = vrep.simxGetObjectHandle(clientID,'target',vrep.simx_opmode_oneshot_wait)
errorCode,consoleHandle = vrep.simxAuxiliaryConsoleOpen(clientID,'info',5,1+4,None,None,None,None,vrep.simx_opmode_oneshot_wait) uiHandle = -1
errorCode,uiHandle = vrep.simxGetUIHandle(clientID,"UI", vrep.simx_opmode_oneshot_wait)
buttonEventID = -1
err,buttonEventID,aux = vrep.simxGetUIEventButton(clientID,uiHandle,vrep.simx_opmode_streaming) L1 = 0.5 # link length
L2 = 0.5
gamma = 1 # step size
stol = 1e-2 # tolerance
nm = 100 # initial error
count = 0 # iteration count
ilimit = 1000 # maximum iteration # initial joint value
# note that workspace-boundary singularities occur when q2 approach 0 or 180 degree
q = np.array([0,1]) while True:
retcode, target_pos = vrep.simxGetObjectPosition(clientID, target_handle, -1, vrep.simx_opmode_streaming) if(nm > stol):
vrep.simxAuxiliaryConsolePrint(clientID, consoleHandle, None, vrep.simx_opmode_oneshot_wait) # "None" to clear the console window x = np.array([L1*math.cos(q[0])+L2*math.cos(q[0]+q[1]), L1*math.sin(q[0])+L2*math.sin(q[0]+q[1])])
error = np.array([target_pos[0],target_pos[1]]) - x J = np.array([[-L1*math.sin(q[0])-L2*math.sin(q[0]+q[1]), -L2*math.sin(q[0]+q[1])],\
[L1*math.cos(q[0])+L2*math.cos(q[0]+q[1]), L2*math.cos(q[0]+q[1])]]) J_pseudo = np.dot(J.transpose(), np.linalg.inv(J.dot(J.transpose())))
dq = J_pseudo.dot(error)
q = q + dq nm = np.linalg.norm(error) count = count + 1
if count > ilimit:
vrep.simxAuxiliaryConsolePrint(clientID,consoleHandle,"Solution wouldn't converge\r\n",vrep.simx_opmode_oneshot_wait)
vrep.simxAuxiliaryConsolePrint(clientID,consoleHandle,'q1:'+str(q[0]*180/math.pi)+' q2:'+str(q[1]*180/math.pi)+'\r\n',vrep.simx_opmode_oneshot_wait)
vrep.simxAuxiliaryConsolePrint(clientID,consoleHandle,str(count)+' iterations'+' err:'+str(nm)+'\r\n',vrep.simx_opmode_oneshot_wait) err, buttonEventID, aux = vrep.simxGetUIEventButton(clientID,uiHandle,vrep.simx_opmode_buffer)
if ((err==vrep.simx_return_ok) and (buttonEventID == 1)):
'''A button was pressed/edited/changed. React to it here!'''
vrep.simxSetJointPosition(clientID,J1_handle, q[0]+math.pi/2, vrep.simx_opmode_oneshot )
vrep.simxSetJointPosition(clientID,J2_handle, q[1], vrep.simx_opmode_oneshot ) '''Enable streaming again (was automatically disabled with the positive event):'''
err,buttonEventID,aux=vrep.simxGetUIEventButton(clientID,uiHandle,vrep.simx_opmode_streaming) time.sleep(0.01)
上面使用Python Remote API来进行逆解计算并控制V-rep中的模型(因为涉及到矩阵求逆等运算,而我不太熟悉Lua的相关数值计算库)。需要注意的是要先在V-rep模型中调用函数simExtRemoteApiStart(portNumber)开启通信服务端,然后在Python程序的客户端进行连接。
V-rep学习笔记:机器人逆运动学数值解法(The Pseudo Inverse Method)的更多相关文章
- V-rep学习笔记:机器人逆运动学数值解法(Damped Least Squares / Levenberg-Marquardt Method)
The damped least squares method is also called the Levenberg-Marquardt method. Levenberg-Marquardt算法 ...
- V-rep学习笔记:机器人逆运动学数值解法(The Jacobian Transpose Method)
机器人运动学逆解的问题经常出现在动画仿真和工业机器人的轨迹规划中:We want to know how the upper joints of the hierarchy would rotate ...
- V-rep学习笔记:机器人逆运动学数值解法(Cyclic Coordinate Descent Method)
When performing inverse kinematics (IK) on a complicated bone chain, it can become too complex for a ...
- V-rep学习笔记:机器人逆运动学解算
IK groups and IK elements VREP中使用IK groups和IK elements来进行正/逆运动学计算,一个IK group可以包含一个或者多个IK elements: I ...
- matlab学习笔记10_6 字符串与数值间的转换以及进制之间的转换
一起来学matlab-matlab学习笔记10 10_6 字符串与数值间的转换以及进制之间的转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合 ...
- ES6学习笔记(四)-数值扩展
PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:
- python学习笔记(五)数值类型和类型转换
Python中的数值类型有: 整型,如2,520 浮点型,如3.14159,1.5e10 布尔类型 True和False e记法: e记法即对应数学中的科学记数法 >>> 1.5e1 ...
- ES6学习笔记(四)数值的扩展
1.二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 ...
- Python学习笔记(2)数值类型
进制转换 int函数任意进制转换为10进制 第一个参数传入一个字符串,任意进制的,第二个参数传入对这个字符串的解释,解释他为几进制 hex oct bin转换进制为16 8 或者2进制 例题中石油87 ...
随机推荐
- andriod之应用内置浏览器 webview
参考:http://my.eoe.cn/694183/archive/10476.html http://blog.csdn.net/it_ladeng/article/details/8136534 ...
- nginx负载均衡的实现
将一台nginx主机当作前端负载均衡服务器,后面通过交换机链接多台web服务器,提供html和php的web界面服务.通过配置前端负载均衡服务器,可以实现将html界面和php界面的分开访问,即htm ...
- java总结第三次//类和对象2、3
四.类和对象2 主要内容:Java类的继承.方法的重写.覆盖.访问控制.super 关键字.多态性及其应用 1.继承 要求:Java只支持单继承,不允许多重继承 一个子类只能有一个父类 一个父类可以派 ...
- Android NDK 开发(四)java传递数据到C【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41845701 前面几篇文章介绍了Android NDK开发的简单概念.常见错误及处 ...
- centos安装apache
查询是否已安装apache: rpm -qa httpd 安装apache: yum install httpd -y 查询: chkconfig httpd on 启动: service http ...
- Delphi中CoInitialize之探究
CoInitialize(LPVOID),它将以特定参数调用CoInitializeEx,为当前单元初始化COM库,并标记协同模式为单线程模式.参数必须为NULL.这是关于OLE和COM的问题. Co ...
- git 使用详解(5)-- get log 查看提交历史【转】
转自:http://blog.csdn.net/wh_19910525/article/details/7468549 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 限制 ...
- vim查找/替换字符串
1.:s 命令来替换字符串. :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sky :n,$s/vivia ...
- Hibernate,Session清理缓存时间点
当应用程序调用org.hibernate.Transaction的commit()的时候,commit()方法先清理缓存,然后再向数据库提交事务. 当应用程序显示调用Session.flush()方法 ...
- java 字符串处理
第一张: 第二张: