The damped least squares method is also called the Levenberg-Marquardt method. Levenberg-Marquardt算法是最优化算法中的一种。它是使用最广泛的非线性最小二乘算法,具有梯度法和牛顿法的优点。当λ很小时,步长等于牛顿法步长,当λ很大时,步长约等于梯度下降法的步长。

  The damped least squares method can be theoretically justified as follows.Rather than just finding the minimum vector ∆θ that gives a best solution to equation (pseudo inverse method就是求的极小范数解), we find the value of ∆θ that minimizes the quantity:

where λ ∈ R is a non-zero damping constant. This is equivalent to minimizing the quantity:

The corresponding normal equation is(根据矩阵论简明教程P83 最小二乘问题:设ARm×nbRm. 若x0RnAx=b的最小二乘解,则x0是方程组ATAx=ATb的解,称该式为Ax=b的法方程组.)

This can be equivalently rewritten as:

It can be shown that JTJ + λ2I is non-singular when λ is appropriate(选取适当的参数λ可以保证矩阵JTJ + λ2I非奇异). Thus, the damped least squares solution is equal to:

Now JT is an n × n matrix, where n is the number of degrees of freedom. It is easy to find that (JTJ + λ2I)−1JT= JT (JJT + λ2I)−1(等式两边同乘(JTJ + λ2I)进行恒等变形). Thus:

The advantage of the equation is that the matrix being inverted is only m×m where m = 3k is the dimension of the space of target positions, and m is often much less than n. Additionally, the equation can be computed without needing to carry out the matrix inversion, instead row operations can find f such that (JJT + λ2If e and then JTf is the solution. The damping constant depends on the details of the multibody and the target positions and must be chosen carefully to make equation numerically stable. The damping constant should large enough so that the solutions for ∆θ are well-behaved near singularities, but if it is chosen too large, then the convergence rate is too slow.

  以平面二连杆机构为例,使用同样的V-rep模型,将目标点放置在接近机构奇异位置处,使用DLS方法求逆解。在下面的Python程序中关节角初始值就给在奇异点上,可以看出最终DLS算法还是能收敛,而pseudo inverse方法在奇异点处就无法收敛。The damped least squares method avoids many of the pseudo inverse method’s problems with singularities and can give a numerically stable method of selecting ∆θ

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
lamda = 0.2 # damping constant
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,0]) 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])]]) f = np.linalg.solve(J.dot(J.transpose())+lamda**2*np.identity(2), error) dq = np.dot(J.transpose(), f)
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)

参考:

“逆运动学”——从操作空间到关节空间(上篇)

V-rep学习笔记:机器人逆运动学数值解法(Damped Least Squares / Levenberg-Marquardt Method)的更多相关文章

  1. V-rep学习笔记:机器人逆运动学数值解法(The Jacobian Transpose Method)

    机器人运动学逆解的问题经常出现在动画仿真和工业机器人的轨迹规划中:We want to know how the upper joints of the hierarchy would rotate ...

  2. 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 ...

  3. V-rep学习笔记:机器人逆运动学数值解法(Cyclic Coordinate Descent Method)

    When performing inverse kinematics (IK) on a complicated bone chain, it can become too complex for a ...

  4. V-rep学习笔记:机器人逆运动学解算

    IK groups and IK elements VREP中使用IK groups和IK elements来进行正/逆运动学计算,一个IK group可以包含一个或者多个IK elements: I ...

  5. matlab学习笔记10_6 字符串与数值间的转换以及进制之间的转换

    一起来学matlab-matlab学习笔记10 10_6 字符串与数值间的转换以及进制之间的转换 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合 ...

  6. ES6学习笔记(四)-数值扩展

    PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:

  7. python学习笔记(五)数值类型和类型转换

    Python中的数值类型有: 整型,如2,520 浮点型,如3.14159,1.5e10 布尔类型 True和False e记法: e记法即对应数学中的科学记数法 >>> 1.5e1 ...

  8. ES6学习笔记(四)数值的扩展

    1.二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 ...

  9. Python学习笔记(2)数值类型

    进制转换 int函数任意进制转换为10进制 第一个参数传入一个字符串,任意进制的,第二个参数传入对这个字符串的解释,解释他为几进制 hex oct bin转换进制为16 8 或者2进制 例题中石油87 ...

随机推荐

  1. Linux TTY框架【转】

    本文转载自:http://ju.outofmemory.cn/entry/281168 1. 前言 由于串口的缘故,TTY是Linux系统中最普遍的一类设备,稍微了解Linux系统的同学,对它都不陌生 ...

  2. 161114、websocket实现心跳重连

    心跳重连缘由 在使用websocket过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时性关闭,这时候websocket的连接已经断开, 而浏览器不会执行websocket 的 onclos ...

  3. Java中常见数据结构:list与map

    1:集合 Collection(单列集合) List(有序,可重复) ArrayList 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector 底层数据结构是数组,查询快,增删慢 线程 ...

  4. PHP stat() 函数 返回关于文件的信息。

    定义和用法 stat() 函数返回关于文件的信息. 语法 fstat(file) 参数 描述 file 必需.规定要检查的文件. 说明 获取由 file 指定的文件的统计信息.如果 file 是符号连 ...

  5. PHP实现单例模式

    <?php /** * [单例模式] * 总结:防止外部new对象:防止子类继承:防止克隆. */ header("Content-type: text/html; charset=u ...

  6. MySQL连接字符串总结

    一.MySQL Connector/ODBC 2.50 (MyODBC 2.50)连接方式 1.本地数据库连接 Driver={MySQL};Server=localhost;Option=16834 ...

  7. postgresql 热备与恢复

    一. PostgreSQL热备份的过程一般为: 数据库中执行:pg_start_backup() ; 然后使用操作系统的tar或 cp命令拷贝 PostgreSQL数据文件. 数据库中执行:pg_st ...

  8. JAVA字段的初始化规律

    JAVA字段的初始化规律 1.类的构造方法 (1)“构造方法”,也称为“构造函数”,当创建一个对象时,它的构造方法会被自动调用.构造方法与类名相同,没有返回值. (2)如果类没有定义构造函数,Java ...

  9. poj3263 Tallest Cow

    题意略去. 考虑给定的R对pair(A, B). 即A能看见B,这意味着B不比A低,并且区间内部的所有元素的高度严格小于A的高度. 我们规定区间的方向:若A > B,为反方向,反之称为正方向. ...

  10. recv send 阻塞和非阻塞

    http://blog.csdn.net/xiaofei0859/article/details/6037814 int send( SOCKET s, const char FAR *buf, in ...