ロボットアームの6次元力センサーの重力補償原理

重力補償原理

1. 力覚センサーデータ解析

ここに画像の説明を挿入します

6次元力覚センサの3つの力成分とトルク成分のゼロ点値を(F x 0 , F y 0 , F z 0 ) (F_{x0},F_{y0},F_{z0)として記録します。 })( F× 0Fy0 _Fz0 _)( M x 0 , M y 0 , M z 0 ) (M_{x0},M_{y0},M_{z0})( M× 0My0 _Mz0 _

センサーとエンドツールの重力はGGですG、6 次元力センサー座標系の重心の座標は(x, y, z) (x, y, z)( x ,z

グラビティGG3 つの座標軸におけるGの分力とモーメントはそれぞれ(G x , G y , G z ) (G_x,G_y,G_z)( G×GはいGz)( M gx , M gy , M gz ) (M_{gx},M_{gy},M_{gz})( MGXMジー_Mジーズ_

力とモーメントの関係から、次のように求めることができます(正の方向は右手の法則で決まります) {
M gx = G z × y − G y × z M gy = G x × z − G z × x M gz = G y × x − G x × y \left\{ \begin{array}{c} M_{gx}=G_z \times y-G_y \times z\\ M_{gy}=G_x \times z-G_z \times x\\ M_ {gz}=G_y \times x-G_x \times y \end{array} \right。 MGX=Gz×yGはい×zMジー_=G××zGz×バツMジーズ_=Gはい×バツG××はい
6次元力覚センサで直接測定した3方向の力成分とトルク成分をそれぞれ(F x, F y, F z)(F_x, F_y, F_z)として記録します。( F×FはいFz)( M x , M y , M z ) (M_x,M_y,M_z)( M×MはいMz

校正中にエンドホルダーに外力がかからないと仮定すると、力センサーで測定される力とモーメントは荷重の重力とゼロ点で構成され、{
F x = G x + F x 0 F y = G y + F y 0 F z = G z + F z 0 \left\{ \begin{array}{c} F_x=G_x+F_{x0}\\ F_y=G_y+F_{y0}\\ F_z=G_z+F_ { z0} \end{配列} \right。 F×=G×+F× 0Fはい=Gはい+Fy0 _Fz=Gz+Fz0 _

{ M x = M gx + M x 0 M y = M gy + M y 0 M z = M gz + M z 0 \left\{ \begin{array}{c} M_x=M_{gx}+M_{x0 }\\ M_y=M_{gy}+M_{y0}\\ M_z=M_{gz}+M_{z0} \end{array} \right。 M×=MGX+M× 0Mはい=Mジー_+My0 _Mz=Mジーズ_+Mz0 _

联立得:
{ M x = ( F z − F z 0 ) × y − ( F y − F y 0 ) × z + M x 0 M y = ( F x − F x 0 ) × z − ( F z − F z 0 ) × x + M y 0 M z = ( F y − F y 0 ) × x − ( F x − F x 0 ) × y + M z 0 \left\{ \begin{array}{c } M_x=(F_z-F_{z0}) \times y-(F_y-F_{y0}) \times z+M_{x0}\\ M_y=(F_x-F_{x0}) \times z-(F_z- F_{z0}) \times x+M_{y0}\\ M_z=(F_y-F_{y0}) \times x-(F_x-F_{x0}) \times y+M_{z0} \end{array} \右。 M×=( FzFz0 _)×y( FはいFy0 _)×z+M× 0Mはい=( F×F× 0)×z( FzFz0 _)×バツ+My0 _Mz=( FはいFy0 _)×バツ( F×F× 0)×y+Mz0 _

{ M x = F z × y − F y × z + M x 0 + F y 0 × z − F z 0 × y M y = F x × z − F z × x + M y 0 + F z 0 × x − F x 0 × z M z = F y × x − F x × y + M z 0 + F x 0 × y − F y 0 × x \left\{ \begin{array}{c} M_x=F_z \times y - F_y \times z + M_{x0} + F_{y0} \times z -F_{z0} \times y \\ M_y=F_x \times z - F_z \times x + M_{y0} + F_{ z0} \times x -F_{x0} \times z \\ M_z=F_y \times x - F_x \times y + M_{z0} + F_{x0} \times y -F_{y0} \times x \end{配列} \右。 M×=Fz×yFはい×z+M× 0+Fy0 _×zFz0 _×yMはい=F××zFz×バツ+My0 _+Fz0 _×バツF× 0×zMz=Fはい×バツF××y+Mz0 _+F× 0×yFy0 _××

この中のF x 0 、 F y 0 、 F z 0 、 M x 0 、 M y 0 、 M z 0 、 x 、 y 、 z F_{x0},F_{y0},F_{z0},M_{x0} ,M_{y0},M_{z0},x,y,zF× 0Fy0 _Fz0 _M× 0My0 _Mz0 _× zは固定値の定数です(力センサーデータの変動は無視し、先端工具は交換しません)

2. 最小二乗法を使用してパラメータを解く

2.1 モーメント方程式


{ k 1 = M x 0 + F y 0 × z − F z 0 × yk 2 = M y 0 + F z 0 × x − F x 0 × zk 3 = M z 0 + F x 0 × y − F y 0 × x \left\{ \begin{array}{c} k_1=M_{x0} + F_{y0} \times z -F_{z0} \times y\\ k_2=M_{y0} + F_{z0 } \times x -F_{x0} \times z\\ k_3=M_{z0} + F_{x0} \times y -F_{y0} \times x \end{array} \right。 k1=M× 0+Fy0 _×zFz0 _×yk2=My0 _+Fz0 _×バツF× 0×zk3=Mz0 _+F× 0×yFy0 _××
例:
[ M x M y M z ] = [ 0 F z − F y 1 0 0 − F z 0 F x 0 1 0 F y − F x 0 0 0 1 ] [ xyzk 1 k 2 k 3 ] \begin {方程式} \left[ \begin{array}{c} M_x \\ M_y \\ M_z \end{array} \right]= \left[ \begin{array}{ccc} 0 & F_z & -F_y & 1 & 0 & 0 \\ -F_z & 0 & F_x & 0 & 1 & 0 \\ F_y & -F_x & 0 & 0 & 0 & 1 \end{array} \right] \left[ \begin{array}{c} x \\ y \\ z \\ k1 \\ k2 \\ k3 \end{配列} \right] \end{式} M×MはいMz = 0−F _zFはいFz0−F _×−F _はいF×0100010001 バツyzk1 _k2_ _k3 _

ロボットアームの先端にあるグリッパーの姿勢を制御し、N の異なる姿勢を取ります (N ≥ \geq 3、少なくとも 3 つの姿勢におけるロボット アームのエンド グリッパーの指示ベクトルが同一平面上にないことが必要)、N セットの 6 次元力データ センサー データが取得され、

M = F ⋅ AM=F \cdot AM=FA,その中A = [ x , y , z , k 1 , k 2 , k 3 ] TA=[x,y,z,k_1,k_2,k_3]^\mathrm{T}=[ × z k1k2k3Tの場合、行列の最小二乗解はA = ( FTF ) − 1 ⋅ FT ⋅ MA=(F^\mathrm{T}F)^{-1}\cdot F^{\mathrm{T} となります。 }\cdot M=( FTF_1FT

複数のデータから、 6次元力覚センサ座標系における荷重重心の座標(x,y,z)(x,y,z)を求めることができます。( x ,z )と定数( k 1 、 k 2 、 k 3 ) (k_1、k_2、k_3)( k1k2k3)値。

2.2 力の方程式

ロボットの設置と固定のプロセス中、設置プラットフォームには一定の傾斜があるため、ロボットのベース座標系と世界座標系には一定の角度があり、これによりロボットの測定値との間に一定の偏差が生じます。センサーと実際の値が異なるため、傾き角度の計算が必要となります。

世界座標系をO {O}とします。O、基本座標系はBBB、フランジ座標系はWWW、力センサー座標系はC {C}Cの場合、ベース座標系からワールド座標系への姿勢変換行列は次のようになります。
BOR = [ 1 0 0 0 cos U sin U 0 sin U cos U ] [ cos V 0 sin V 0 1 0 − sin V 0 cos V ] \begin{equation} ^O_BR= \left[ \begin{array}{ccc} 1 & 0 & 0 \\ 0 & cosU & sinU \\ 0 & sinU & cosU \end{array} \right] \left [ \ begin{array}{ccc} cosV & 0 &sinV\\ 0 & 1 & 0\\ -sinV & 0 & cosV \\ \end{array} \right] \end{equation}BああR= 1000cos UUある0アメリカあるcos U バスケットV0s inV010sinV _0バスケットV
其中 U U Uは世界座標系xxX軸の回転角度VVV はベース座標系の周りのyyy軸の回転角度

エンドフランジからベース座標系への姿勢変換行列は次のとおりです。
WBR = R z ( A ) R y ( B ) R x ( C ) ^B_WR=R_z(A) R_y(B) R_x(C)WBR=Rz( A ) Rはい( B ) R×( C )
ABCABCA BCの値はロボットのティーチングペンダントから読み取ることができます。

最後に力覚センサーを取り付けるとZZがあるのでZ軸上のα \alphaα (ロボット基準座標系を変更することで手動で一致させることができます。つまり、たわみ角が 0 になります) 力覚センサからフランジ座標系への姿勢変換行列は、 CWR = [ cos α − sin α 0 sin α cos
α 0 0 0 1 ] \begin{equation} ^W_CR= \left[ \begin{array}{ccc} cos\alpha & -sin\alpha & 0 \\ sin\alpha & cos\alpha & 0 \\ 0 & 0 & 1 \end{配列} \right] \end{式}CWR= cosα_ _α_0αscosα_ _0001
このとき、世界座標系から 6 次元力覚センサ座標系への姿勢変換行列は
0 CR = WCR ⋅ BWR ⋅ OBR = CWRT ⋅ WBRT ⋅ BORT {^C_0R} = {^C_WR} \cdot {^W_BR} \ cdot {^B_OR} = {^W_CR}^\mathrm{T} \cdot {^B_WR}^\mathrm{T} \cdot {^O_BR}^\mathrm{T}0CR=WCRBWRBR=CWRTWBRTBああR
世界座標系O {O}におけるT重力Oの式はOG = [ 0 , 0 , − g ] T {^{O}G=[0,0,-g]^\mathrm{T}} です。そしてG=[ 0 ,0 −g ] _

座標変換により、重力は力センサー座標系C {C}に分解されます。C得られる
CG = OCR ⋅ OG = WCR ⋅ BWR ⋅ OBR ⋅ OG = CWRT ⋅ WBRT ⋅ BORT ⋅ OG = CWRT ⋅ WBRT ⋅ [ cos U sin V ∗ g − sin U ∗ g − cos U cos V ∗ g ] ^{ C}G=^C_OR \cdot {^{O}G}= {^C_WR} \cdot {^W_BR} \cdot {^B_OR} \cdot {^{O}G} ={^W_CR}^\mathrm{ T} \cdot {^B_WR}^\mathrm{T} \cdot {^O_BR}^\mathrm{T} \cdot {^{O}G} \\ ={^W_CR}^\mathrm{T} \cdot {^B_WR}^\mathrm{T} \cdot \left[ \begin{array}{c} cosUsinV * g \\ -sinU * g \\ -cosUcosV * g \end{array} \right]CG _=CRそしてG=WCRBWRBRそしてG=CWRTWBRTBああRTそしてG=CWRTWBRT cos U s inVg- Usgcos U cos Vg

例:
[ F x , F y , F z ] T = [ G x , G y , G z ] T + [ F x 0 , F y 0 , F z 0 ] T = OCR ⋅ OG + [ F x 0 , F y 0 , F z 0 ] T [F_x,F_y,F_z]^{\mathrm{T}}=[G_x,G_y,G_z]^{\mathrm{T}}+[F_{x0},F_{y0 },F_{z0}]^{\mathrm{T}}=^C_OR \cdot {^{O}G}+[F_{x0},F_{y0},F_{z0}]^{\mathrm{T }}[ F×FはいFzT=[ G×GはいGzT+[ F× 0Fy0 _Fz0 _T=CRそしてG+[ F× 0Fy0 _Fz0 _T

[ F x F y F z ] = [ CWRT ⋅ WBRTI ] [ cos U sin V ∗ g − sin U ∗ g − cos U cos V ∗ g F x 0 F y 0 F z 0 ] \begin{equation} \left [ \begin{array}{c} F_x \\ F_y \\ F_z \end{array} \right]= \left[ \begin{array}{ccc} {^W_CR}^\mathrm{T} \cdot {^ B_WR}^\mathrm{T} & I \end{array} \right] \left[ \begin{array}{c} cosUsinV * g \\ -sinU * g \\ -cosUcosV * g \\ F_{x0} \\ F_{y0} \\ F_{z0} \end{配列} \right] \end{式} F×FはいFz =[CWRTWBRT cos U s inVg- Usgcos U cos VgF× 0Fy0 _Fz0 _
令:
{ L x = cos U sin V ∗ g L y = − sin U ∗ g L z = − cos U cos V ∗ g \left\{ \begin{array}{c} L_x=cosUsinV * g\\ L_y =-sinU * g\\ L_z= -cosUcosV * g \end{array} \right。 L×=cos U s inVgLはい=- UsgLz=cos U cos Vg
これは次のように表すことができます:
[ F x F y F z ] = [ CWRT ⋅ WBRTI ] [ L x L y L z F x 0 F y 0 F z 0 ] \begin{equation} \left[ \begin{array}{ c} F_x \\ F_y \\ F_z \end{array} \right]= \left[ \begin{array}{ccc} {^W_CR}^\mathrm{T} \cdot {^B_WR}^\mathrm{T } & I \end{array} \right] \left[ \begin{array}{c} L_x \\ L_y \\ L_z\\ F_{x0} \\ F_{y0} \\ F_{z0} \end{配列} \right] \end{式} F×FはいFz =[CWRTWBRT L×LはいLzF× 0Fy0 _Fz0 _

同様に、N 個の異なる姿勢をとることにより、N 個の 6 次元力覚センサーデータが取得されます。

f = R ⋅ B f=R \cdot Bf=RB,その中B = [ L x , L y , L z , F x 0 , F y 0 , F z 0 ] TB=[L_x,L_y,L_z,F_{x0},F_{y0},F_{z0} ]^{\mathrm{T}}B=[ L×LはいLzF× 0Fy0 _Fz0 _Tの場合、行列の最小二乗解はB = ( RTR ) − 1 ⋅ RT ⋅ f B=(R^\mathrm{T}R)^{-1} \cdot R^\mathrm{T} となります。 \cdot fB=( RTR_1RT

力覚センサーのゼロ点値(F x 0 、F y 0 、F z 0 ) (F_{x0},F_{y0},F_{z0}) を複数のデータから求めることができます。( F× 0Fy0 _Fz0 _)、取付傾斜角U、VU、VVグラビティggグラムサイズ。
g = L x 2 + L y 2 + L z 2 g=\sqrt{ {L_x}^2 + {L_y}^2 + {L_z}^2}\\g=L×2+Lはい2+Lz2

U = arcsin ( − L yg ) U = arcsin(\frac{-L_y}{g})U=(rcs )gはい)

V = arctan (− L x L z ) V = arctan(\frac{-L_x}{L_z})V=アークタン_ _ _Lz×)

3. 外部接触力の計算

外部接触力は次のように結論付けることができます:
{ F ex = F x − F x 0 − G x F ey = F y − F y 0 − G y F ez = F z − F z 0 − G z \left \ { \begin{array}{c} F_{ex}=F_x-F_{x0}-G_x\\ F_{ey}=F_y-F_{y0}-G_y\\ F_{ez}=F_z-F_{z0 } -G_z \end{配列} \right。 Fエックス_=F×F× 0G×Fええ=FはいFy0 _GはいFいいえ=FzFz0 _Gz

[ F ex F ey F ez ] = [ F x F y F z ] − [ OCRI ] [ 0 0 − g F x 0 F y 0 F z 0 ] \begin{equation} \left[ \begin{array}{ c} F_{ex} \\ F_{ey} \\ F_{ez} \end{array} \right]= \left[ \begin{array}{c} F_{x} \\ F_{y} \\ F_{z} \end{array} \right]- \left[ \begin{array}{ccc} ^C_OR & I \end{array} \right] \left[ \begin{array}{c} 0 \\ 0 \\ -g \\ F_{x0} \\ F_{y0} \\ F_{z0} \end{array} \right] \end{equation} Fエックス_FええFいいえ = F×FはいFz [CR 00−g _F× 0Fy0 _Fz0 _
又:
{ M x 0 = k 1 − F y 0 × z + F z 0 × y M y 0 = k 2 − F z 0 × x + F x 0 × z M z 0 = k 3 − F x 0 × y + F y 0 × x \left\{ \begin{array}{c} M_{x0}=k_1 - F_{y0} \times z +F_{z0} \times y \\ M_{y0}=k_2 - F_{z0} \times x +F_{x0} \times z\\ M_{z0}=k_3 - F_{x0} \times y +F_{y0} \times x \end{array} \right。 M× 0=k1Fy0 _×z+Fz0 _×yMy0 _=k2Fz0 _×バツ+F× 0×zMz0 _=k3F× 0×y+Fy0 _××

CG = OCR ⋅ OG = [ G x , G y , G z ] T ^{C}G=^C_OR \cdot {^{O}G} = [G_x,G_y,G_z]^\mathrm{T}CG _=CRそしてG=[ G×GはいGzT

{ M gx = G z × y − G y × z M gy = G x × z − G z × x M gz = G y × x − G x × y \left\{ \begin{array}{c} M_ {gx}=G_z \times y-G_y \times z\\ M_{gy}=G_x \times z-G_z \times x\\ M_{gz}=G_y \times x-G_x \times y \end{array} \右。 MGX=Gz×yGはい×zMジー_=G××zGz×バツMジーズ_=Gはい×バツG××はい

つまり:
[ M gx M gy M gz ] = [ 0 − zyz 0 − x − yx 0 ] [ G x G y G z ] = [ 0 − zyz 0 − x − yx 0 ] ⋅ OCR ⋅ [ 0 0 − g ] \begin{方程式} \left[ \begin{array}{c} M_{gx} \\ M_{gy} \\ M_{gz} \end{array} \right]= \left[ \begin{array} {ccc} 0 & -z & y\\ z & 0 &-x \\ -y & x & 0 \end{array} \right] \left[ \begin{array}{c} G_x \\ G_y \\ G_z \end{配列} \right]= \left[ \begin{配列}{ccc} 0 & -z & y\\ z & 0 &-x \\ -y & x & 0 \end{配列} \right ] \cdot ^C_OR \cdot \left[ \begin{array}{ccc} 0 \\ 0 \\ -g \end{array} \right] \end{equation} MGXMジー_Mジーズ_ = 0z y−z _0×y×0 G×GはいGz = 0z y−z _0×y×0 CR 00 g
外部接触モーメントは次のとおりです。
{ M ex = M x − M x 0 − M gx M ey = M y − M y 0 − M gy M ez = M z − MZ 0 − M gz \left\{ \begin{ array }{c} M_{ex}=M_x-M_{x0}-M_{gx}\\ M_{ey}=M_y-M_{y0}-M_{gy}\\ M_{ez}=M_z-M_{ Z0 }-M_{gz} \end{array} \right。 Mエックス_=M×M× 0MGXMええ=MはいMy0 _Mジー_Mいいえ=MzMZ0 _Mジーズ_

[1] Gao Peiyang. 力センサーに基づく産業用ロボットの定力研削および研磨システムの研究 [D]. 華中科技大学、2019. [2] Zhang Lijian、Hu Ruiqin、Yi Wangmin. Force on the
end 6 次元の力センサーに基づく産業用ロボットの負荷 Perception Research[J]. Journal of Automation, 2017, 43(03):439-447.DOI:10.16383/j.aas.2017.c150753. [3]Dong Hao
.軸穴組立産業用ロボットのコンプライアンス制御アルゴリズムの研究[D] .河南科学技術大学、2018.

コードは以下のように表示されます:

from numpy import *
import numpy as np
'''
Made by 水木皆Ming
重力补偿计算
'''
class GravityCompensation:
    M = np.empty((0, 0))
    F = np.empty((0, 0))
    f = np.empty((0, 0))
    R = np.empty((0, 0))

    x = 0
    y = 0
    z = 0
    k1 = 0
    k2 = 0
    k3 = 0

    U = 0
    V = 0
    g = 0

    F_x0 = 0
    F_y0 = 0
    F_z0 = 0

    M_x0 = 0
    M_y0 = 0
    M_z0 = 0

    F_ex = 0
    F_ey = 0
    F_ez = 0

    M_ex = 0
    M_ey = 0
    M_ez = 0

    def Update_M(self, torque_data):
        M_x = torque_data[0]
        M_y = torque_data[1]
        M_z = torque_data[2]

        if (any(self.M)):
            M_1 = matrix([M_x, M_y, M_z]).transpose()
            self.M = vstack((self.M, M_1))
        else:
            self.M = matrix([M_x, M_y, M_z]).transpose()

    def Update_F(self, force_data):
        F_x = force_data[0]
        F_y = force_data[1]
        F_z = force_data[2]

        if (any(self.F)):
            F_1 = matrix([[0, F_z, -F_y, 1, 0, 0],
                          [-F_z, 0, F_x, 0, 1, 0],
                          [F_y, -F_x, 0, 0, 0, 1]])
            self.F = vstack((self.F, F_1))
        else:
            self.F = matrix([[0, F_z, -F_y, 1, 0, 0],
                             [-F_z, 0, F_x, 0, 1, 0],
                             [F_y, -F_x, 0, 0, 0, 1]])

    def Solve_A(self):
        A = dot(dot(linalg.inv(dot(self.F.transpose(), self.F)), self.F.transpose()), self.M)

        self.x = A[0, 0]
        self.y = A[1, 0]
        self.z = A[2, 0]
        self.k1 = A[3, 0]
        self.k2 = A[4, 0]
        self.k3 = A[5, 0]
        # print("A= \n" , A)
        print("x= ", self.x)
        print("y= ", self.y)
        print("z= ", self.z)
        print("k1= ", self.k1)
        print("k2= ", self.k2)
        print("k3= ", self.k3)

    def Update_f(self, force_data):
        F_x = force_data[0]
        F_y = force_data[1]
        F_z = force_data[2]

        if (any(self.f)):
            f_1 = matrix([F_x, F_y, F_z]).transpose()
            self.f = vstack((self.f, f_1))
        else:
            self.f = matrix([F_x, F_y, F_z]).transpose()

    def Update_R(self, euler_data):
        # 机械臂末端到基坐标的旋转矩阵
        R_array = self.eulerAngles2rotationMat(euler_data)

        alpha = (0) * 180 / np.pi

        # 力传感器到末端的旋转矩阵
        R_alpha = np.array([[math.cos(alpha), -math.sin(alpha), 0],
                            [math.sin(alpha), math.cos(alpha), 0],
                            [0, 0, 1]
                            ])

        R_array = np.dot(R_alpha, R_array.transpose())

        if (any(self.R)):
            R_1 = hstack((R_array, np.eye(3)))
            self.R = vstack((self.R, R_1))
        else:
            self.R = hstack((R_array, np.eye(3)))

    def Solve_B(self):
        B = dot(dot(linalg.inv(dot(self.R.transpose(), self.R)), self.R.transpose()), self.f)

        self.g = math.sqrt(B[0] * B[0] + B[1] * B[1] + B[2] * B[2])
        self.U = math.asin(-B[1] / self.g)
        self.V = math.atan(-B[0] / B[2])

        self.F_x0 = B[3, 0]
        self.F_y0 = B[4, 0]
        self.F_z0 = B[5, 0]

        # print("B= \n" , B)
        print("g= ", self.g / 9.81)
        print("U= ", self.U * 180 / math.pi)
        print("V= ", self.V * 180 / math.pi)
        print("F_x0= ", self.F_x0)
        print("F_y0= ", self.F_y0)
        print("F_z0= ", self.F_z0)

    def Solve_Force(self, force_data, euler_data):
        Force_input = matrix([force_data[0], force_data[1], force_data[2]]).transpose()

        my_f = matrix([cos(self.U)*sin(self.V)*self.g, -sin(self.U)*self.g, -cos(self.U)*cos(self.V)*self.g, self.F_x0, self.F_y0, self.F_z0]).transpose()

        R_array = self.eulerAngles2rotationMat(euler_data)
        R_array = R_array.transpose()
        R_1 = hstack((R_array, np.eye(3)))

        Force_ex = Force_input - dot(R_1, my_f)
        print('接触力:\n', Force_ex)

    def Solve_Torque(self, torque_data, euler_data):
        Torque_input = matrix([torque_data[0], torque_data[1], torque_data[2]]).transpose()
        M_x0 = self.k1 - self.F_y0 * self.z + self.F_z0 * self.y
        M_y0 = self.k2 - self.F_z0 * self.x + self.F_x0 * self.z
        M_z0 = self.k3 - self.F_x0 * self.y + self.F_y0 * self.x

        Torque_zero = matrix([M_x0, M_y0, M_z0]).transpose()

        Gravity_param = matrix([[0, -self.z, self.y],
                                [self.z, 0, -self.x],
                                [-self.y, self.x, 0]])

        Gravity_input = matrix([cos(self.U)*sin(self.V)*self.g, -sin(self.U)*self.g, -cos(self.U)*cos(self.V)*self.g]).transpose()

        R_array = self.eulerAngles2rotationMat(euler_data)
        R_array = R_array.transpose()

        Torque_ex = Torque_input - Torque_zero - dot(dot(Gravity_param, R_array), Gravity_input)

        print('接触力矩:\n', Torque_ex)

    def eulerAngles2rotationMat(self, theta):
        theta = [i * math.pi / 180.0 for i in theta]  # 角度转弧度

        R_x = np.array([[1, 0, 0],
                        [0, math.cos(theta[0]), -math.sin(theta[0])],
                        [0, math.sin(theta[0]), math.cos(theta[0])]
                        ])

        R_y = np.array([[math.cos(theta[1]), 0, math.sin(theta[1])],
                        [0, 1, 0],
                        [-math.sin(theta[1]), 0, math.cos(theta[1])]
                        ])

        R_z = np.array([[math.cos(theta[2]), -math.sin(theta[2]), 0],
                        [math.sin(theta[2]), math.cos(theta[2]), 0],
                        [0, 0, 1]
                        ])

        # 第一个角为绕X轴旋转,第二个角为绕Y轴旋转,第三个角为绕Z轴旋转
        R = np.dot(R_x, np.dot(R_y, R_z))
        return R


def main():
    #
    force_data = [-6.349214527290314e-05, 0.0016341784503310919, -24.31537437438965]
    torque_data= [-0.25042885541915894, 0.32582423090934753, 2.255179606436286e-05]
    euler_data = [-80.50866918099089, 77.83705434751874, -9.294185889510375 + 12]

    force_data1 = [-7.469202995300293, 2.3709897994995117, -23.0179500579834]
    torque_data1= [-0.2169264256954193, 0.3719269931316376, 0.10870222747325897]
    euler_data1 = [-105.99038376663763, 60.89987226261212, -10.733422007074305 + 12]

    force_data2 = [-14.45930004119873, 0.995974063873291, -19.523677825927734]
    torque_data2= [-0.19262456893920898, 0.3845194876194, 0.1622740775346756]
    euler_data2 = [-114.24258417090118, 43.78913507089547, -19.384088817327235 + 12]


    compensation = GravityCompensation()

    compensation.Update_F(force_data)
    compensation.Update_F(force_data1)
    compensation.Update_F(force_data2)

    compensation.Update_M(torque_data)
    compensation.Update_M(torque_data1)
    compensation.Update_M(torque_data2)

    compensation.Solve_A()

    compensation.Update_f(force_data)
    compensation.Update_f(force_data1)
    compensation.Update_f(force_data2)

    compensation.Update_R(euler_data)
    compensation.Update_R(euler_data1)
    compensation.Update_R(euler_data2)

    compensation.Solve_B()

    # compensation.Solve_Force(force_data, euler_data)
    # compensation.Solve_Force(force_data1, euler_data1)
    # compensation.Solve_Force(force_data2, euler_data2)
    #
    # compensation.Solve_Torque(torque_data, euler_data)
    # compensation.Solve_Torque(torque_data1, euler_data1)
    # compensation.Solve_Torque(torque_data2, euler_data2)


if __name__ == '__main__':
    main()

Made by 水木皆Ming

おすすめ

転載: blog.csdn.net/zhang1079528541/article/details/129503851