@@ -45,6 +45,7 @@ export near_zero,
4545 gravity_forces,
4646 end_effector_forces,
4747 forward_dynamics_aba,
48+ forward_dynamics_aba!,
4849 forward_dynamics_crba,
4950 forward_dynamics_rnea,
5051 euler_step,
@@ -1379,6 +1380,8 @@ function inverse_dynamics_rnea!(
13791380 Fi = SVector {6} (tip_wrench)
13801381 for i = n: - 1 : 1
13811382 Gi = SMatrix {6,6} (spatial_inertias[i])
1383+ # The -ad(V)'*G*V term is Featherstone's v ×* (Iv): the force cross product
1384+ # is the negative transpose of the motion cross product (twist/wrench duality).
13821385 Fi = AdTi[i+ 1 ]' * Fi + Gi * Vdi[i+ 1 ] - ad (Vi[i+ 1 ])' * Gi * Vi[i+ 1 ]
13831386 joint_torques[i] = Fi' * Ai[i]
13841387 end
@@ -1911,16 +1914,69 @@ function forward_dynamics_aba(
19111914 screw_axes:: AbstractMatrix ,
19121915)
19131916 n = length (joint_positions)
1914-
1915- # Pass 1 (outward): velocities, bias accelerations, bias forces
1916- Mi = SMatrix {4,4,Float64} (LA. I)
1917+ ddq = zeros (n)
19171918 Ai = Vector {SVector{6,Float64}} (undef, n)
19181919 AdTi = Vector {SMatrix{6,6,Float64,36}} (undef, n + 1 )
19191920 Vi = Vector {SVector{6,Float64}} (undef, n + 1 )
19201921 ci = Vector {SVector{6,Float64}} (undef, n)
19211922 IA = Vector {SMatrix{6,6,Float64,36}} (undef, n)
19221923 pA = Vector {SVector{6,Float64}} (undef, n)
1924+ U = Vector {SVector{6,Float64}} (undef, n)
1925+ D = Vector {Float64} (undef, n)
1926+ u = Vector {Float64} (undef, n)
1927+ forward_dynamics_aba! (
1928+ ddq,
1929+ joint_positions,
1930+ joint_velocities,
1931+ joint_torques,
1932+ gravity,
1933+ tip_wrench,
1934+ link_frames,
1935+ spatial_inertias,
1936+ screw_axes,
1937+ Ai,
1938+ AdTi,
1939+ Vi,
1940+ ci,
1941+ IA,
1942+ pA,
1943+ U,
1944+ D,
1945+ u,
1946+ )
1947+ end
1948+
1949+ """
1950+ forward_dynamics_aba!(ddq, joint_positions, joint_velocities, joint_torques, gravity, tip_wrench, link_frames, spatial_inertias, screw_axes, Ai, AdTi, Vi, ci, IA, pA, U, D, u)
19231951
1952+ In-place version of [`forward_dynamics_aba`](@ref). Writes the result into `ddq`.
1953+ The workspace vectors must be pre-allocated: `Ai` (n), `AdTi` (n+1), `Vi` (n+1),
1954+ `ci` (n), `IA` (n), `pA` (n), `U` (n), `D` (n), `u` (n).
1955+ """
1956+ function forward_dynamics_aba! (
1957+ ddq:: AbstractVector ,
1958+ joint_positions:: AbstractVector ,
1959+ joint_velocities:: AbstractVector ,
1960+ joint_torques:: AbstractVector ,
1961+ gravity:: AbstractVector ,
1962+ tip_wrench:: AbstractVector ,
1963+ link_frames:: AbstractVector ,
1964+ spatial_inertias:: AbstractVector ,
1965+ screw_axes:: AbstractMatrix ,
1966+ Ai:: AbstractVector{SVector{6,Float64}} ,
1967+ AdTi:: AbstractVector{SMatrix{6,6,Float64,36}} ,
1968+ Vi:: AbstractVector{SVector{6,Float64}} ,
1969+ ci:: AbstractVector{SVector{6,Float64}} ,
1970+ IA:: AbstractVector{SMatrix{6,6,Float64,36}} ,
1971+ pA:: AbstractVector{SVector{6,Float64}} ,
1972+ U:: AbstractVector{SVector{6,Float64}} ,
1973+ D:: AbstractVector{Float64} ,
1974+ u:: AbstractVector{Float64} ,
1975+ )
1976+ n = length (joint_positions)
1977+
1978+ # Pass 1 (outward): velocities, bias accelerations, bias forces
1979+ Mi = SMatrix {4,4,Float64} (LA. I)
19241980 Vi[1 ] = @SVector zeros (6 )
19251981 AdTi[n+ 1 ] = adjoint_representation (transform_inv (link_frames[n+ 1 ]))
19261982
@@ -1946,10 +2002,6 @@ function forward_dynamics_aba(
19462002 pA[n] = pA[n] + AdTi[n+ 1 ]' * SVector {6} (tip_wrench)
19472003
19482004 # Pass 2 (inward): articulated body inertias and bias forces
1949- U = Vector {SVector{6,Float64}} (undef, n)
1950- D = Vector {Float64} (undef, n)
1951- u = Vector {Float64} (undef, n)
1952-
19532005 for i = n: - 1 : 1
19542006 U[i] = IA[i] * Ai[i]
19552007 D[i] = Ai[i]' * U[i]
@@ -1963,7 +2015,6 @@ function forward_dynamics_aba(
19632015 end
19642016
19652017 # Pass 3 (outward): joint accelerations
1966- ddq = zeros (n)
19672018 a0 = SA[0.0 , 0.0 , 0.0 , - gravity[1 ], - gravity[2 ], - gravity[3 ]]
19682019 a = AdTi[1 ] * a0
19692020
0 commit comments