機器人逆運動學進階:李代數、矩陣指數與旋轉流形計算

做機器人逆運動學(IK)的時候,你遲早會遇到矩陣指數和對數這些東西。為什么呢?因為計算三維旋轉的誤差,不能簡單地用歐氏距離那一套,那只對位置有效。旋轉得用另一套方法——你需要算兩個旋轉矩陣之間的差異,這就涉及到矩陣對數了。

這篇文章就是要把這事兒說清楚:從旋轉矩陣構成的李群開始,到流形和切空間,再到怎么用叉積算旋轉矩陣的導數,如何對旋轉矩陣做增量更新,最后是如何計算從一個姿態到另一個姿態需要的角速度。

SO(3):三維旋轉的數學結構

機器人的姿態其實就是一個三維坐標系。這個坐標系由三個互相垂直、長度為1的向量組成,比如最簡單的情況:(1,0,0)?、(0,1,0)?、(0,0,1)?。把這三個向量當作列向量排在一起,就得到了一個3×3的旋轉矩陣。

雖然這個矩陣在數學上屬于?3?3空間,但實際上能表示旋轉的矩陣組合要少得多,它們形成一個特殊的群,叫做三維特殊正交群SO(3)。類似的還有二維旋轉SO(2)、四維變換矩陣等等,這些都屬于李群家族。

流形和切空間:幾何概念

實數是一條直線,但SO(3)不是,它在?3?3里形成一個彎曲的流形。這個流形是連續的、可微的,你可以在上面定義距離。想在這個彎曲的表面上移動,就得沿著切線方向走,這就引出了切空間的概念。

就像函數的切線斜率由導數決定一樣,我們也可以通過計算流形切線的"斜率"來得到它的導數。

計算旋轉矩陣的導數

現在問題來了:一個旋轉矩陣R和一個角速度向量ω,怎么算R的變化率??

答案是這樣的:

這里?ω?是ω對應的反對稱矩陣:

為什么要搞成反對稱矩陣?因為實際上是想算ω和R每一列的叉積。有時候你會看到這個操作寫成帽子符號,都是一個意思。

所有3×3實反對稱矩陣構成的空間叫做𝖘𝖔(3),這是SO(3)的李代數,也就是SO(3)在單位矩陣處的切空間。雖然它在矩陣乘法下不構成群,但它是個李代數,讓我們能在非線性的SO(3)流形上做線性計算。

叉積的幾何意義

我們來仔細看看叉積ω×v是什么意思。兩個向量的叉積結果是一個同時垂直于這兩個向量的新向量,長度正比于兩向量夾角的正弦值。

把ω變成反對稱矩陣形式,就能用矩陣乘法實現叉積運算:

對矩陣R做這個操作,就等于對R的每一列都做一次叉積。

這里有個細節要注意:這個運算可以左乘也可以右乘,取決于ω是在機體坐標系還是世界坐標系下給出的。一般我們假設ω在機體坐標系,所以?ω?右乘到R上。

把ω想象成旋轉軸,|ω|是轉速,這樣理解叉積就直觀多了。如果v指向某個點,那么ω×v就是這個點繞ω軸旋轉時的速度方向。

矩陣指數:精確的旋轉更新

有了上面的理解,我們再看這個微分方程:

R的每一列代表一個坐標軸,和ω做叉積得到的矩陣描述了各個軸因為旋轉產生的速度。那怎么得到更新后的旋轉矩陣呢?

一個樸素的想法是用歐拉積分,就是把R?ω?乘個小時間步長然后加起來。但這樣做有問題:無法保證結果還是正交矩陣,也就是說可能跳出SO(3)。雖然可以每步都強制歸一化,但有更精確的方法。

上面那個微分方程其實是個線性常微分方程,解是:

矩陣指數函數通過泰勒展開定義,大部分線性代數庫都有實現。

看看用這個方法繞ω=(1.0,1.0,1.0)?旋轉的效果:
外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

矩陣對數:解決逆運動學問題

有時候我們需要反過來算:給定當前姿態R(0)和目標姿態R(t),需要什么旋轉向量才能從一個到另一個?這就像算位置的歐氏距離一樣。

對于旋轉,我們把R(0)移到等式另一邊,算矩陣對數,再除以時間t:

但事情還沒完。真正的逆運動學問題需要算誤差對關節角的導數。對于n個關節的機器人,我們要算一個3×n的雅可比矩陣:

要對R(t)關于q求導,得先過一遍對數,然后用鏈式法則。具體怎么做,作者說在另一篇文章里有。

代碼實現

下面是生成上面動畫的代碼。關鍵是用scipy的expm函數實現矩陣指數,核心更新就是一行:

R = R @ expm(hat(omega) * dt)

 import numpy as np  
from scipy.linalg import expm  
import matplotlib.pyplot as plt  
from mpl_toolkits.mplot3d import Axes3D  
from matplotlib.animation import FuncAnimation  def hat(omega):  return np.array([  [0,         -omega[2],  omega[1]],  [omega[2],   0,        -omega[0]],  [-omega[1],  omega[0],  0]  ])  # Angular velocity vector (rad/s)  
omega = np.array([1.0, 1.0, 1.0])  dt = 0.05  
T = 5  
N = int(T / dt)  # Initialize rotation matrix as identity  
R = np.eye(3)  # Store rotation matrices  
Rs = [R.copy()]  
for _ in range(N):  R = R @ expm(hat(omega) * dt)  Rs.append(R.copy())  fig = plt.figure()  
ax = fig.add_subplot(111, projection='3d')  # Set plot limits and labels  
ax.set_xlim([-1.5, 1.5])  
ax.set_ylim([-1.5, 1.5])  
ax.set_zlim([-1.5, 1.5])  
ax.set_xlabel('X')  
ax.set_ylabel('Y')  
ax.set_zlabel('Z')  
ax.set_title('Rotating 3D Coordinate Frame')  # Initialize quiver objects for x, y, z axes  
quiver_x = ax.quiver(0, 0, 0, 1, 0, 0, color='r', length=1, normalize=True)  
quiver_y = ax.quiver(0, 0, 0, 0, 1, 0, color='g', length=1, normalize=True)  
quiver_z = ax.quiver(0, 0, 0, 0, 0, 1, color='b', length=1, normalize=True)  def update(num):  # Remove previous quivers (if any)  for artist in ax.collections:  artist.remove()  R = Rs[num]  x_axis = R[:, 0]  y_axis = R[:, 1]  z_axis = R[:, 2]  ax.quiver(0, 0, 0, *x_axis, color='r', length=1, normalize=True)  ax.quiver(0, 0, 0, *y_axis, color='g', length=1, normalize=True)  ax.quiver(0, 0, 0, *z_axis, color='b', length=1, normalize=True)  return []  ani = FuncAnimation(fig, update, frames=len(Rs), interval=50, blit=False)  from matplotlib.animation import PillowWriter  
ani.save("rotation.gif", writer=PillowWriter(fps=20))  plt.show()

總結

本文從理論到實踐全面介紹了矩陣指數在機器人逆運動學中的應用。我們從SO(3)李群和𝖘𝖔(3)李代數的數學結構出發,解釋了為什么旋轉計算需要特殊的數學工具。通過流形和切空間的幾何概念,我們理解了旋轉矩陣導數的計算方法,并學會了使用反對稱矩陣實現叉積運算。矩陣指數函數提供了精確的旋轉更新方法,能夠保證旋轉矩陣在更新過程中始終保持正交性,避免了傳統歐拉積分可能導致的數值不穩定問題。而矩陣對數則解決了逆向問題——如何計算從當前姿態到目標姿態所需的旋轉誤差和角速度。這套方法的核心優勢在于能夠在非線性的旋轉空間中進行精確計算,為逆運動學算法提供了必要的數學工具,特別是在計算雅可比矩陣時所需的旋轉導數。對于需要高精度姿態控制的機器人應用,這些數學工具是必不可少的。

https://avoid.overfit.cn/post/352201d5dfd749e48e2b6ccf8e81abf0

作者:Nikolaus Correll

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96572.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96572.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96572.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機視覺(opencv)實戰十八——圖像透視轉換

圖像透視變換詳解與實戰在圖像處理中,透視變換(Perspective Transform) 是一種常見的幾何變換,用來將圖像中某個四邊形區域拉伸或壓縮,映射到一個矩形區域。常見應用場景包括:糾正拍照時的傾斜(…

【飛書多維表格插件】

coze中添加飛書多維表格記錄插件 添加單條記錄 [{"fields":{"任務詳情":"選項1","是否完成":"未完成"}}]添加多條記錄 [{"fields":{"任務詳情":"選項1","是否完成":"已完…

Java基礎 9.14

1.Collection接口遍歷對象方式2-for循環增強增強for循環,可以代替iterator選代器,特點:增強for就是簡化版的iterator本質一樣 只能用于遍歷集合或數組package com.logic.collection_;import java.util.ArrayList; import java.util.Collectio…

數據結構(C語言篇):(十三)堆的應用

目錄 前言 一、堆排序 1.1 版本一:基于已有數組建堆、取棧頂元素完成排序 1.1.1 實現邏輯 1.1.2 底層原理 1.1.3 應用示例 1.1.4 執行流程 1.2 版本二:原地排序 —— 標準堆排序 1.2.1 實現邏輯 1.2.2 底層原理 1.2.3 時間復雜度計算…

4步OpenCV-----掃秒身份證號

這段代碼用 OpenCV 做了一份“數字模板字典”,然后在銀行卡/身份證照片里自動找到身份證號那一行,把每個數字切出來跟模板比對,最終輸出并高亮顯示出完整的身份證號碼,下面是代碼解釋:模塊 1 工具箱(通用函…

馮諾依曼體系:現代計算機的基石與未來展望

馮諾依曼體系:現代計算機的基石與未來展望 引人入勝的開篇 當你用手機刷視頻、用電腦辦公時,是否想過這些設備背后共享的底層邏輯?從指尖輕滑切換APP,到電腦秒開文檔,這種「無縫銜接」的體驗,其實藏著一個改…

前端基礎 —— C / JavaScript基礎語法

以下是對《3.JavaScript(基礎語法).pdf》的內容大綱總結:---📘 一、JavaScript 簡介 - 定義:腳本語言,最初用于表單驗證,現為通用編程語言。 - 應用:網頁開發、游戲、服務器(Node.js&#xff09…

springboot 二手物品交易系統設計與實現

springboot 二手物品交易系統設計與實現 目錄 【SpringBoot二手交易系統全解析】從0到1搭建你的專屬平臺! 🔍 需求確認:溝通對接 🗣 📊 系統功能結構:附思維導圖 ☆開發技術: &#x1f6e…

【Android】可折疊式標題欄

在 Android 應用開發中,精美的用戶界面可以顯著提升應用品質和用戶體驗。Material Design 組件中的 CollapsingToolbarLayout 能夠為應用添加動態、流暢的折疊效果,讓標題欄不再是靜態的元素。本文將深入探討如何使用 CollapsingToolbarLayout 創建令人驚…

Debian13下使用 Vim + Vimspector + ST-LINK v2.1 調試 STM32F103 指南

1. 硬件準備與連接 1.1 所需硬件 STM32F103C8T6 最小系統板ST-LINK v2.1 調試器連接線(杜邦線) 1.2 硬件連接 ST-LINK v2.1 ? STM32F103C8T6 連接方式:ST-LINK v2.1 引腳STM32F103C8T6 引腳功能說明SWDIOPA13數據線SWCLKPA14時鐘線GNDGND共地…

第21課:成本優化與資源管理

第21課:成本優化與資源管理 課程目標 掌握計算資源優化 學習成本控制策略 了解資源調度算法 實踐實現成本優化系統 課程內容 21.1 成本分析框架 成本分析系統 class CostAnalysisFramework {constructor(config) {this.config

SAP HANA Scale-out 04:CalculationView優化

CV執行過程計算視圖激活時,生成Stored ModelSELECT查詢時:首先將Stored Model實例化為runtime Model 計算引擎執行優化,將runtime Model轉換為Optimized Runtime ModelOptimized Runtime Model通過SQL Optimizer進行優化計算引擎優化特性說明…

鴻蒙審核問題——Scroll中嵌套了List/Grid時滑動問題

文章目錄背景原因解決辦法1、借鑒Flutter中的解決方式,如下圖2、鴻蒙Next中對應的解決方式,如下圖3、官方文檔回訪背景 來源一次審核被拒的情況。也是出于粗心導致的。之前在flutter項目中也是遇到過這種問題的。其實就是滾動視圖內嵌滾動視圖造成的&am…

測試電商購物車功能,設計測試case

在電商場景中,購物車是連接商品瀏覽與下單支付的關鍵環節,需要從功能、性能、兼容性、安全性等多維度進行測試。以下是購物車功能的測試用例設計: 一、功能測試 1. 商品添加到購物車 - 未登錄狀態下,添加商品到購物車(…

Linux --- 常見的基本指令

一. 前言本篇博客使用的 Linux 操作系統是 centos ,用來學習Linux 的 Linux 系統的內核版本和系統架構信息版本如下所示:上圖的主要結構為:主版本號-次版本號 修正次數,3.10.0 是操作系統的主版本號;當我們在維護一段L…

微信小程序 -開發郵箱注冊驗證功能

一、前端驗證:正則表達式與插件結合正則表達式設計 使用通用郵箱格式校驗正則,并允許中文域名(如.中國): const emailReg /^[a-zA-Z0-9._%-][a-zA-Z0-9-](?:\.[a-zA-Z0-9-])*\.[a-zA-Z]{2,}(?:\.[a-zA-Z]{2})?$/i;…

docker 部署 code-server

docker 部署 code-servercode-serverError response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headersdocker 配置正確步驟 阿里云源permission de…

網絡編程專題:從源碼解析網絡編程常用方法(基于6.16.3內核)

前言 本文是因為作者在研究下面這個代碼時發現的問題: int main() {// 1. 創建 IPv4 專用地址結構體 sockaddr_instruct sockaddr_in ipv4_addr;memset(&ipv4_addr, 0, sizeof(ipv4_addr)); // 初始化清零// 2. 填充 IPv4 專屬信息ipv4_addr.sin_family AF_IN…

2025年數字公共治理專業重點學什么內容?(詳細指南)

數字公共治理作為一個新興的跨學科領域,近年來受到越來越多高校和學生的關注。這個專業融合了多個學科的知識體系,旨在培養掌握現代治理理念和技術應用能力的復合型人才。對于在校大學生而言,了解這一專業的學習內容和發展方向,有…

一招解決 win 下 終端打印中文亂碼問題

適合所有終端 cmd powershell git bash, 原理:修改電腦的區域設置,勾選使用 UTF-8 1.電腦搜索 區域, 打開區域設置2. 打開相關設置3. 點擊更改 日期、時間或數字格式4. 選則管理-點擊更改系統區域設置,在彈出框中勾選 …