六軸機器人運動學(xué)正逆解:從DH參數(shù)到工程驗證)
簡介面向機器人學(xué)學(xué)習(xí)者與工程師的六軸機器人運動學(xué)源碼資源包以UR5機器人為對象系統(tǒng)演示正運動學(xué)與逆運動學(xué)的MATLAB實現(xiàn)過程可解決六軸機械臂關(guān)節(jié)變量與末端位姿相互求解的常見需求。內(nèi)容涵蓋UR5機器人定義文件、由關(guān)節(jié)角度計算末端位置姿態(tài)的正解函數(shù)、由末端位姿反求關(guān)節(jié)角度的逆解函數(shù)以及用于驗證結(jié)果正確性的測試腳本同時附Robotics Toolbox源碼及安裝包便于深入理解D-H參數(shù)建模與運動學(xué)計算原理。整個資源包共961個文件容量約119.26MB以.m源碼為主線并包含STL模型、MLX交互式腳本、SLX仿真模型、PDF文檔等兼顧理論查閱與仿真實踐。已有10117人瀏覽學(xué)習(xí)適合機器人入門自學(xué)、課程設(shè)計參考或控制系統(tǒng)預(yù)研既可直接運行驗證也可基于源碼開展二次開發(fā)與算法改造。1. 為什么要用MATLAB啃下六軸機器人運動學(xué)這塊硬骨頭做機器人這行的人幾乎都繞不開運動學(xué)這道坎。無論是搞工業(yè)機械臂集成、做AGV復(fù)合機器人、還是研究協(xié)作臂的軌跡規(guī)劃正解和逆解永遠是一切上層算法的基礎(chǔ)。簡單說正運動學(xué)是給定六個關(guān)節(jié)角度算出末端執(zhí)行器在空間里的位姿逆運動學(xué)則是反過來——告訴你末端要到達某個位置、擺出某個姿態(tài)反推六個關(guān)節(jié)各自該轉(zhuǎn)多少度。我在實驗室?guī)н^不少學(xué)生也幫企業(yè)調(diào)過不少機械臂發(fā)現(xiàn)一個很有意思的現(xiàn)象很多人一上來就急著用ROS、用C、用各種機器人庫結(jié)果光是環(huán)境配置就勸退了一半人。而MATLAB其實是被嚴重低估的利器。它不需要你編譯、不需要你處理復(fù)雜的內(nèi)存管理矩陣運算天生就長在骨子里而機器人運動學(xué)的數(shù)學(xué)本質(zhì)恰恰就是齊次變換矩陣的連乘與矩陣方程的求解。用MATLAB來實現(xiàn)六軸機器人的正逆運動學(xué)求解代碼量少、調(diào)試直觀、還自帶可視化工具箱可以把機械臂的姿態(tài)一幀幀畫出來是理解算法原理最舒服的路徑。這篇內(nèi)容不是教科書式的理論推導(dǎo)而是我實際把一套完整的求解源碼從零寫出來、測試通過、并且在仿真環(huán)境里驗證過的全流程記錄。源碼包里包含正運動學(xué)求解函數(shù)、逆運動學(xué)解析解函數(shù)、關(guān)節(jié)角連續(xù)性處理、工作空間采樣驗證等模塊。適合三類人一是剛?cè)腴T機器人學(xué)、被DH參數(shù)和齊次變換矩陣搞得頭暈的學(xué)生二是需要在MATLAB里快速搭建運動學(xué)仿真驗證環(huán)境的工程師三是想自己動手寫一遍求解器、不想只調(diào)現(xiàn)成工具箱的硬核玩家。先說結(jié)論六軸機器人正解是閉式解屬于典型的套公式但細節(jié)多逆解可以通過解析法分離出前三個關(guān)節(jié)和后三個關(guān)節(jié)用幾何法和代數(shù)法配合求解得到最多8組解再根據(jù)關(guān)節(jié)限位和連續(xù)性挑一組最優(yōu)解。這套思路理解透了任何六軸構(gòu)型的機械臂你都能在三小時內(nèi)寫出自己的求解器。2. 機器人模型怎么建DH參數(shù)和齊次變換矩陣的實用理解2.1 四參數(shù)里的每一個到底在說什么上一節(jié)說過正解是套公式這個公式就是Denavit-Hartenberg參數(shù)簡稱DH參數(shù)。很多教材把DH參數(shù)講得特別玄乎什么坐標(biāo)系繞X軸旋轉(zhuǎn)、沿Z軸平移、連桿偏置初學(xué)者一上來就被繞暈。我用大白話翻譯一遍你就懂了。一個連桿從上一個關(guān)節(jié)坐標(biāo)系變換到下一個關(guān)節(jié)坐標(biāo)系只需要四次基本操作θ關(guān)節(jié)角繞當(dāng)前Z軸旋轉(zhuǎn)的角度d偏置沿當(dāng)前Z軸平移的距離a桿長沿新X軸平移的距離α扭轉(zhuǎn)角繞新X軸旋轉(zhuǎn)的角度為什么要這樣定義因為三維空間里從一個坐標(biāo)系到另一個坐標(biāo)系6個自由度需要6個參數(shù)但機器人關(guān)節(jié)結(jié)構(gòu)本身有約束——相鄰關(guān)節(jié)的軸線要么垂直要么平行所以4個參數(shù)就夠了。正是這個夠用的約束條件讓機器人運動學(xué)建模成為可能。我建議初學(xué)階段別急著去記矩陣相乘的最終表達式而是先在紙上畫出一個兩連桿機構(gòu)的坐標(biāo)變換過程。畫完一個連桿的坐標(biāo)變換再畫第二個你會發(fā)現(xiàn)規(guī)律非常清晰每個連桿的變換矩陣長一個樣只是四個參數(shù)值不同而已。這就是正運動學(xué)求解的天然循環(huán)結(jié)構(gòu)。2.2 一次典型的坐標(biāo)變換矩陣長什么樣比如某個連桿的DH參數(shù)是theta30度, d0.25, a0.4, alpha90度那它的變換矩陣用MATLAB寫出來就是function T dh_transform(theta, d, a, alpha) T [cos(theta), -sin(theta)*cos(alpha), sin(theta)*sin(alpha), a*cos(theta); sin(theta), cos(theta)*cos(alpha), -cos(theta)*sin(alpha), a*sin(theta); 0, sin(alpha), cos(alpha), d; 0, 0, 0, 1]; end這四個參數(shù)一個一個代進去后矩陣的最后一列就是當(dāng)前連桿末端在上一級坐標(biāo)系里的位置坐標(biāo)前3乘3的部分就是姿態(tài)。這個矩陣本身的信息量很大左上角是旋轉(zhuǎn)信息第四列上面三個數(shù)是位置信息最后一行永遠是[0 0 0 1]這個不變式是齊次變換矩陣能夠相乘的前提。我在教學(xué)的時候發(fā)現(xiàn)很多學(xué)生死記矩陣里的正負號一旦記混就全盤皆輸。我的建議是矩陣里最拗口的就是那兩個sin(theta)*sin(alpha)項你只要理解它們來自旋轉(zhuǎn)的疊加乘法就不會記錯。萬一忘了直接手推一次旋轉(zhuǎn)矩陣的乘積最多花兩分鐘比背公式靠譜得多。3. 正運動學(xué)求解從關(guān)節(jié)角到末端位姿的完整鏈路3.1 串聯(lián)機械臂的正解就是矩陣連乘六軸機器人的正運動學(xué)求解本質(zhì)上就是六個DH變換矩陣的逐級相乘。每個關(guān)節(jié)的變換矩陣把末端位置和姿態(tài)從前一關(guān)節(jié)坐標(biāo)系一步步傳遞到基座坐標(biāo)系。最終得到的變換矩陣T06 T01 * T12 * T23 * T34 * T45 * T56就是機械臂末端相對于基座坐標(biāo)系的完整位姿描述。初學(xué)者最常問的一個問題是為什么要用一個4乘4的矩陣來表示三維坐標(biāo)直接用3乘3矩陣不是更節(jié)省計算量嗎答案在于旋轉(zhuǎn)和平移必須在一個運算框架里統(tǒng)一處理。如果用3乘3矩陣旋轉(zhuǎn)和平移就得分開做兩次運算用4乘4的齊次矩陣旋轉(zhuǎn)加平移一次乘法搞定而且多次變換可以直接連乘成一個總矩陣這是串聯(lián)機器人最核心的計算模式。在實際工程中正解一般不會成為性能瓶頸。即使是在實時控制周期1毫秒的系統(tǒng)中六次4乘4矩陣乘法也就消耗幾微秒的CPU時間。真正考驗算法水平的是逆解。3.2 一份可以直接跑通的正解源碼下面這份源碼是我項目中實際使用的正運動學(xué)求解函數(shù)簡潔清晰適合照抄學(xué)習(xí)function T06 forward_kinematics(q, dh_params) % q: 1x6 關(guān)節(jié)角度向量單位弧度 % dh_params: 6x4 矩陣每行對應(yīng)一個關(guān)節(jié)的 [theta_offset, d, a, alpha] T06 eye(4); for i 1:6 theta q(i) dh_params(i, 1); T_i dh_transform(theta, dh_params(i, 2), dh_params(i,3), dh_params(i,4)); T06 T06 * T_i; end end為什么這里要單獨加一列theta_offset因為在很多實際機械臂中DH參數(shù)表里給的theta并不是直接等于關(guān)節(jié)編碼器讀數(shù)而是帶有一個初始零點偏移。這個偏移如果沒處理好很容易出現(xiàn)仿真里明明是對的真機上末端位置卻偏了一大截的問題。我舉個例子假設(shè)六軸機器人的第一個關(guān)節(jié)在DH參數(shù)表里的theta_offset是90度而編碼器零點位置恰好對應(yīng)機械臂完全展開的狀態(tài)。如果直接拿編碼器讀數(shù)去算正解末端位置會憑空旋轉(zhuǎn)90度看起來就像機械臂錯位了。加上偏移量后這個問題就消失了。用這組典型的六軸機器人DH參數(shù)測試一下% theta_offset, d, a, alpha dh [0, 0.34, 0, pi/2; 0, 0, 0.29, 0; 0, 0, 0.26, 0; 0, 0.24, 0, pi/2; 0, 0.24, 0, -pi/2; 0, 0.08, 0, 0]; q [0, -pi/4, pi/4, 0, pi/6, 0]; T06 forward_kinematics(q, dh)輸出結(jié)果是一個4乘4矩陣。你從里面可以直接讀出末端位置和末端姿態(tài)。用tform2trvec和tform2eul這兩個MATLAB內(nèi)置函數(shù)就可以把矩陣翻譯成人能看得懂的XYZ坐標(biāo)和歐拉角。3.3 驗證正解算得對不對正解代碼寫完后千萬別急著往下走先做三個基本驗證確定算出來的結(jié)果可靠再去寫逆解。我的驗證習(xí)慣是這樣的零位自檢把六個關(guān)節(jié)角全部置零算出的末端坐標(biāo)應(yīng)該和機械臂廠家數(shù)據(jù)手冊里的零位姿態(tài)坐標(biāo)一致。單關(guān)節(jié)旋轉(zhuǎn)測試只讓第一個關(guān)節(jié)從0轉(zhuǎn)到90度觀察末端位置的軌跡。如果第一個關(guān)節(jié)是腰部旋轉(zhuǎn)關(guān)節(jié)那末端應(yīng)該畫出一個圓弧且高度不變。隨機抽樣測試隨機生成200組關(guān)節(jié)角全部代入正解計算。如果有些位置點的坐標(biāo)超出機械臂工作空間范圍說明DH參數(shù)或代碼有誤。這三個驗證做完基本能確認正解代碼沒有低級錯誤。接下來就可以進入重頭戲——逆運動學(xué)了。4. 逆運動學(xué)求解解析解法的完整推導(dǎo)與代碼落地4.1 為什么說逆解是幾何直覺加代數(shù)技巧的混合體逆運動學(xué)的難點在于它是一個非線性方程組的求解問題。六軸機械臂的正運動學(xué)方程可以寫成T06 f(q1, q2, ..., q6)而逆運動學(xué)要求解的是q1...q6 f_inv(T06)。這個反函數(shù)通常無法直接寫出因為正解方程是三角函數(shù)的多重嵌套而三角函數(shù)天然具有多值性。在MATLAB里你可以直接調(diào)用內(nèi)置的數(shù)值求解器去暴力迭代比如fsolve。但我不推薦在實時控制或軌跡規(guī)劃場景里這么干原因有三數(shù)值迭代慢、容易陷入局部最優(yōu)、無法保證解在關(guān)節(jié)限位內(nèi)。真正常用的是解析解法——通過分析機械臂結(jié)構(gòu)把六個關(guān)節(jié)的求解拆分成獨立的小問題。六軸串聯(lián)機械臂的逆運動學(xué)解析解標(biāo)準(zhǔn)的處理思路是先求前三軸再求后三軸。為什么可以這樣分離因為后三個關(guān)節(jié)的軸線通常交于一點稱為腕心這個結(jié)構(gòu)設(shè)計幾乎是所有工業(yè)六軸機器人的通用構(gòu)型。腕心點的位置只由前三個關(guān)節(jié)決定與后三個關(guān)節(jié)無關(guān)。把末端的目標(biāo)位置先沿末端姿態(tài)反推一段距離得到腕心坐標(biāo)前三個關(guān)節(jié)就變成了一個三連桿到達指定位置的問題用幾何法就能解。后三個關(guān)節(jié)則是在前三個關(guān)節(jié)確定后反推姿態(tài)誤差用代數(shù)法解歐拉角。4.2 前三關(guān)節(jié)的幾何求法假設(shè)末端目標(biāo)位姿是T_desired其中位置部分是p_desired1乘3向量姿態(tài)部分是R_desired3乘3矩陣。末端執(zhí)行器坐標(biāo)系的原點到腕心的距離是d6也就是最后一個DH參數(shù)里的d值。那么腕心位置是% 把末端位置沿末端坐標(biāo)系Z軸負方向平移d6 p_wrist p_desired - d6 * R_desired * [0; 0; 1];拿到p_wrist之后前三個關(guān)節(jié)的求解就變成了經(jīng)典的平面兩連桿旋轉(zhuǎn)底座問題。以我的DH參數(shù)表為例關(guān)節(jié)1是繞基座Z軸旋轉(zhuǎn)q1 atan2(p_wrist_y, p_wrist_x)但要注意如果p_wrist_x和p_wrist_y都接近0說明腕心正好在基座正上方此時q1是退化狀態(tài)任意值都可以實際中取上一周期值即可。關(guān)節(jié)2和關(guān)節(jié)3可以把機械臂看作一個在垂直平面內(nèi)的二連桿機構(gòu)用余弦定理求解。設(shè)r sqrt(p_wrist_x^2 p_wrist_y^2)s p_wrist_z - d1則關(guān)節(jié)2和關(guān)節(jié)3的組合長度L sqrt(r^2 s^2)帶入余弦定理可得兩組解肘部向上和肘部向下。關(guān)節(jié)3的角度可以利用q2的表達反推。這段推導(dǎo)如果用文字描述容易看得云里霧里。我建議你直接畫一個側(cè)視圖基座在原點第一段桿長a2第二段桿長a3腕心在目標(biāo)點。這個圖的結(jié)構(gòu)跟人的上臂加前臂一模一樣肘關(guān)節(jié)可以朝上也可以朝下所以天然存在兩組解。再加上q1在部分構(gòu)型下可以加減180度前三關(guān)節(jié)會出現(xiàn)多組組合。4.3 后三關(guān)節(jié)的代數(shù)解法前三關(guān)節(jié)解出來后可以算出此時從基座到第4關(guān)節(jié)坐標(biāo)系的旋轉(zhuǎn)矩陣R03。目標(biāo)姿態(tài)是R_desired所以第4、5、6關(guān)節(jié)需要提供的旋轉(zhuǎn)是R36 R03 * R_desired;注意R36是一個3乘3旋轉(zhuǎn)矩陣它代表從第3關(guān)節(jié)坐標(biāo)系到末端坐標(biāo)系的姿態(tài)變換。對于大多數(shù)六軸機械臂第4、5、6關(guān)節(jié)在DH參數(shù)表里通常對應(yīng)繞Z軸、Y軸、Z軸的旋轉(zhuǎn)組合具體是哪種組合要看α參數(shù)。我用的這組DH參數(shù)中第4關(guān)節(jié)是繞Z軸第5關(guān)節(jié)是繞X軸第6關(guān)節(jié)是繞Z軸所以可以從R36的矩陣元素反解出三個關(guān)節(jié)角q5 atan2(sqrt(R36(3,1)^2 R36(3,2)^2), R36(3,3)); if abs(q5) 1e-6 % 奇異位形第4和第6關(guān)節(jié)軸線重合只能求和 q4 0; q6 atan2(-R36(1,2), R36(1,1)); else q4 atan2(R36(2,3), R36(1,3)); q6 atan2(R36(3,2), -R36(3,1)); end這里有一個非常關(guān)鍵的細節(jié)q5有正負兩個解對應(yīng)q5 ±acos(R36(3,3))。當(dāng)q5接近0時機械臂處于腕部奇異位形第4和第6關(guān)節(jié)無法單獨解出只能求它們的和或差。這不是代碼bug而是機構(gòu)本身的物理特性后續(xù)軌跡規(guī)劃時需要在算法層面繞開這個奇異區(qū)域。4.4 把多組解變一組可用解前三關(guān)節(jié)可能給出2到4組解后三關(guān)節(jié)又給出2組解組合起來最多8組解。8組解里有些關(guān)節(jié)角度超出限位有些雖然角度合法但會導(dǎo)致機械臂部件之間碰撞所以在實際工程中必須做篩選。我的篩選邏輯很簡單清晰按優(yōu)先級排序valid_solutions []; % 存儲關(guān)節(jié)限位內(nèi)且符合要求的解 for each_solution in all_solutions if all_within_joint_limits(each_solution) if collision_check(each_solution) false valid_solutions [valid_solutions; each_solution]; end end end % 選擇與當(dāng)前關(guān)節(jié)角最接近的解避免大幅度跳動 if ~isempty(valid_solutions) [~, idx] min(sum(abs(valid_solutions - current_q), 2)); best_q valid_solutions(idx, :); else error(當(dāng)前目標(biāo)位姿不可達或全部候選解均超出關(guān)節(jié)限位); end這里最實用的一招是最小關(guān)節(jié)位移優(yōu)先準(zhǔn)則。在軌跡規(guī)劃中上一周期的關(guān)節(jié)角是current_q這一周期目標(biāo)位姿算出了好幾組有效解選哪個選關(guān)節(jié)角變化總和最小的那組。因為實際電機有最大速度和加速度限制關(guān)節(jié)角跳變太大會導(dǎo)致軌跡不平滑嚴重時還會觸發(fā)驅(qū)動器過流報警。這一條經(jīng)驗我在現(xiàn)場調(diào)試時用了無數(shù)次非常管用。5. 逆解正確性和穩(wěn)定性的實測驗證5.1 用正解反驗證逆解的理論閉環(huán)逆解寫完之后最重要的一件事就是驗證它的正確性。理論上逆解和正解互為反函數(shù)所以驗證方法很簡單隨機生成一組關(guān)節(jié)角用正解算出末端位姿再用逆解求回關(guān)節(jié)角。如果兩個關(guān)節(jié)角誤差在極小范圍內(nèi)這組代碼就通了。我在實際驗證中寫了一個自動循環(huán)test_pass 0; test_total 1000; for i 1:test_total q_random rand(1,6) * [2*pi, 2*pi, 2*pi, 2*pi, 2*pi, 2*pi] - pi; % 限制隨機角度在合理范圍避開奇異位形 q_random q_random .* [1, 1, 1, 1, 1, 1]; T_target forward_kinematics(q_random, dh); q_solved inverse_kinematics(T_target, current_q, dh); T_check forward_kinematics(q_solved, dh); if norm(T_check - T_target) 1e-6 test_pass test_pass 1; end end fprintf(測試通過率: %.2f%%\n, test_pass/test_total*100);如果通過率低于99.9%就說明逆解代碼里有問題最常見的錯誤是三角函數(shù)分支寫反或者腕心偏置方向算錯。不過要特別注意一個例外當(dāng)隨機角度讓機械臂處于奇異位形附近時誤差會變大。所以在測試時要把奇異判定加進去奇異附近的樣本單獨標(biāo)注不計入通過率否則你永遠測不出100%的通過率還會白白浪費時間排查一個本就不存在的bug。5.2 末端連續(xù)軌跡追蹤測試驗證完單點逆解正確性你還應(yīng)該做一個更有說服力的測試——讓末端畫一個空間圓。具體做法是在笛卡爾空間生成圓軌跡上的100個目標(biāo)點依次調(diào)用逆解求解然后把每個目標(biāo)點的關(guān)節(jié)角序列連接起來用正解反算末端位置看看實際末端軌跡距離理想圓的半徑偏差有多大。這個測試能同時驗證三件事逆解的連續(xù)性、關(guān)節(jié)角平滑性、機械臂對連續(xù)軌跡的跟蹤能力。正常情況下軌跡偏差應(yīng)該控制在毫米級。如果偏差呈現(xiàn)鋸齒狀波動說明逆解在多組解之間來回切換沒有連續(xù)選擇同一組解分支。這個問題在工業(yè)機器人里特別致命——它會導(dǎo)致機械臂在運動過程中突然出現(xiàn)抽搐動作輕則影響加工質(zhì)量重則引發(fā)安全事故。我之前調(diào)試一個焊接機器人項目時就遇到過這個問題。六軸機械臂走到某個位置附近末端軌跡突然跳了一下焊點直接偏了3毫米。排查了很久才確認是逆解在兩組解之間切換導(dǎo)致的。解決方案就是在上一節(jié)提到的最小關(guān)節(jié)位移優(yōu)先基礎(chǔ)上再加一條分支連續(xù)性約束如果目標(biāo)點的候選解與上一周期解的距離超過某個閾值就強制忽略那組解。% 在篩選時增加連續(xù)性約束 if min_dist threshold best_q min_dist_solution; else warning(連續(xù)軌跡中檢測到解跳變嘗試其他分支); % 可以在這里加入人工勢場或者軌跡重規(guī)劃邏輯 end5.3 工作空間邊界上的逆解行為還有一個值得專門測試的場景——機械臂工作空間邊界。在邊界附近逆解通常會表現(xiàn)出兩種異常行為一是解的數(shù)量驟減八組解可能只剩一組二是解特別敏感目標(biāo)點稍微移動幾毫米關(guān)節(jié)角就劇烈變化。這兩種行為本質(zhì)上是機構(gòu)在邊界處的奇異現(xiàn)象不是什么可以修的bug。工程師要做的是在工作空間規(guī)劃階段就避開邊界。我習(xí)慣于先在MATLAB里用蒙特卡洛法畫一遍機械臂的工作空間point_cloud []; for i 1:3000 q_sample (rand(1,6) - 0.5) * 2 * [2*pi, 2*pi, 2*pi, 2*pi, 2*pi, 2*pi]; T_sample forward_kinematics(q_sample, dh); point_cloud [point_cloud; tform2trvec(T_sample)]; end scatter3(point_cloud(:,1), point_cloud(:,2), point_cloud(:,3), 2, point_cloud(:,3), filled);把工作空間點云圖畫出來之后你一眼就能看出哪些區(qū)域是邊界區(qū)哪些區(qū)域是核心區(qū)。軌跡規(guī)劃時把目標(biāo)點約束在核心區(qū)范圍內(nèi)逆解穩(wěn)定性會大幅提升。6. 把正逆解代碼組織成項目函數(shù)劃分與MATLAB工程實踐6.1 代碼目錄結(jié)構(gòu)怎么搭寫運動學(xué)求解器代碼組織得好不好直接決定你后面加軌跡規(guī)劃、動力學(xué)分析、可視化的時候會不會一團糟。我建議按下面的目錄結(jié)構(gòu)來組織一套干凈的MATLAB工程robot_kinematics/ ├── main_demo.m % 主腳本正逆解演示、可視化 ├── forward_kinematics.m % 正運動學(xué)求解 ├── inverse_kinematics.m % 逆運動學(xué)求解 ├── dh_transform.m % 單連桿DH變換矩陣 ├── joint_limits.m % 關(guān)節(jié)限位參數(shù) ├── check_workspace.m % 工作空間采樣繪制 ├── test_kinematics.m % 正逆解閉環(huán)驗證腳本 └── data/ └── dh_params.m % DH參數(shù)表返回6x4矩陣這個結(jié)構(gòu)的好處是每個函數(shù)只負責(zé)一件事main_demo.m只做編排data/dh_params.m用來集中管理機械臂型號參數(shù)。換一臺機器人只需要修改dh_params.m文件其它代碼幾乎不用動。我在實際項目中用這套結(jié)構(gòu)同時維護過三款不同品牌的六軸機械臂切換時只需要把參數(shù)表換掉正逆解代碼完全復(fù)用。6.2 一些用過的神秘坑第一坑MATLAB的atan2返回角度范圍是[-pi, pi]而很多機械臂控制系統(tǒng)要求關(guān)節(jié)角在[-2pi, 2pi]或者[0, 2pi]范圍內(nèi)。如果不做角度歸一化逆解輸出的關(guān)節(jié)角可能跟實際編碼器讀數(shù)相差一個2π的整數(shù)倍導(dǎo)致電機誤動作。我的做法是加一個角度包裝函數(shù)function q_wrapped wrap_to_pi(q) q_wrapped atan2(sin(q), cos(q)); end第二坑DH參數(shù)表里有些值是負的比如a的符號決定了連桿的偏置方向。很多初學(xué)者在搭建DH參數(shù)表時會把a的位置寫反導(dǎo)致末端位置鏡像看起來像是左手坐標(biāo)系的錯亂。正確的做法是在搭建完DH參數(shù)表后先用dh_transform畫一個單連桿的坐標(biāo)系人工檢查坐標(biāo)系指向是否和機械臂實體一致。第三坑不要在逆解函數(shù)里用inv(R)。旋轉(zhuǎn)矩陣是正交矩陣它的逆等于它的轉(zhuǎn)置。直接用transpose(R)比用inv(R)快得多而且數(shù)值穩(wěn)定性更好。這個細節(jié)在單次求解時感受不到差別但在循跡仿真幾萬個點時會明顯拖慢速度。6.3 進階能不能擴展到運動學(xué)和軌跡規(guī)劃有了穩(wěn)定的正逆解求解器往上可以接的東西非常多。比如雅可比矩陣它其實是正解矩陣對關(guān)節(jié)角求偏導(dǎo)用它可以做速度層面的映射關(guān)系——末端笛卡爾速度等于雅可比矩陣乘以關(guān)節(jié)角速度。在MATLAB里可以用jacobian符號函數(shù)或者數(shù)值差分法算出雅可比進而做奇異性分析和力的映射分析。再比如軌跡規(guī)劃笛卡爾空間的直線插值配合逆解就能實現(xiàn)直線運動關(guān)節(jié)空間的梯形速度規(guī)劃配合正解就能驗證關(guān)節(jié)運動是否超限。所有這些都可以在這套運動學(xué)求解器基礎(chǔ)上擴展不需要大改架構(gòu)。這也是我為什么堅持用函數(shù)化、模塊化的方式來組織代碼——為了后面擴展時不拆東墻補西墻。7. 總結(jié)與個人經(jīng)驗中的關(guān)鍵心得回頭梳理一遍整個實現(xiàn)過程最讓我想提醒后來者的一件事是正逆運動學(xué)看著是數(shù)學(xué)題實際是工程題。很多人在MATLAB里把正逆解跑通了覺得很興奮但一旦接到真機調(diào)試就會發(fā)現(xiàn)各種實際問題和理論不一致。關(guān)節(jié)限位、零點漂移、奇異位形、解跳變這些才是真正考驗工程能力的地方。我在自己項目的源碼里特意保留了一套完整的注釋和測試代碼方便后續(xù)接手的人快速理解每個函數(shù)的作用和邊界條件。尤其是inverse_kinematics.m這個函數(shù)我加了幾十行注釋專門說明每個解分支的來源和適用場景。這樣做的好處是即使過了三四個月自己回頭看代碼依然能在幾分鐘內(nèi)想起來當(dāng)初的設(shè)計意圖。另外一個特別受用的經(jīng)驗是在做逆解驗證時不要只測單點。把末端位姿連續(xù)變化、關(guān)節(jié)角連續(xù)變化、大量隨機點結(jié)合到一起測試才能暴露那些間歇性出現(xiàn)的穩(wěn)定性問題。我曾經(jīng)用這套方法在模擬仿真階段就暴露了一個關(guān)節(jié)角跳變問題省掉了后面真機調(diào)試的大量返工時間。這種把問題提前暴露在仿真里的做法是我強烈推薦的工作習(xí)慣。最后分享一個小技巧當(dāng)你把逆解結(jié)果用于軌跡規(guī)劃時可以在每個目標(biāo)點求解之前傳入上一時刻的關(guān)節(jié)角作為參考讓逆解自動偏向連續(xù)性更好的候選解。這個技巧看起來簡單但對于整個系統(tǒng)的運動平穩(wěn)性提升非常明顯建議你實際體驗一下。本文還有配套的精品資源點擊獲取