KDL based robot model

This commit is contained in:
Michel Breyer 2021-03-12 14:55:42 +01:00
parent c28929dec1
commit 996264e125
5 changed files with 79 additions and 20 deletions

View File

@ -4,16 +4,17 @@ import numpy as np
class CartesianPoseController: class CartesianPoseController:
def __init__(self, model): def __init__(self, model):
self.model = model self.model = model
# self.x_d = x0
def set_target(self, pose): def set_target(self, pose):
self.target = pose.translation self.x_d = pose.translation
def update(self, q, dq): def update(self, q, dq):
t = self.model.pose().translation t = self.model.pose(q).translation
J = self.model.jacobian(q) J = self.model.jacobian(q)[:3, :]
J_pinv = np.linalg.pinv(J) J_pinv = np.linalg.pinv(J)
err = 2.0 * (self.target - t) err = 2.0 * (self.x_d - t)
cmd = np.dot(J_pinv, err) cmd = np.dot(J_pinv, err)
return cmd return cmd

38
model.py Normal file
View File

@ -0,0 +1,38 @@
import numpy as np
import kdl_parser_py.urdf as kdl_parser
import PyKDL as kdl
import utils
class Model(object):
def __init__(self, root_frame_id, tip_frame_id):
_, tree = kdl_parser.treeFromFile("assets/urdfs/panda/panda_arm_hand.urdf")
chain = tree.getChain(root_frame_id, tip_frame_id)
self.nr_joints = chain.getNrOfJoints()
self.fk_pos_solver = kdl.ChainFkSolverPos_recursive(chain)
self.fk_vel_solver = kdl.ChainFkSolverVel_recursive(chain)
self.jac_solver = kdl.ChainJntToJacSolver(chain)
return
def pose(self, q):
jnt_array = utils.to_kdl_jnt_array(q)
frame = kdl.Frame()
self.fk_pos_solver.JntToCart(jnt_array, frame)
return utils.Transform.from_kdl(frame)
def velocities(self, q, dq):
jnt_array_vel = kdl.JntArrayVel(
utils.to_kdl_jnt_array(q), utils.to_kdl_jnt_array(dq)
)
twist = kdl.FrameVel()
self.fk_vel_solver.JntToCart(jnt_array_vel, twist)
d = twist.deriv()
linear, angular = np.r_[d[0], d[1], d[2]], np.r_[d[3], d[4], d[5]]
return linear, angular
def jacobian(self, q):
jnt_array = utils.to_kdl_jnt_array(q)
J = kdl.Jacobian(self.nr_joints)
self.jac_solver.JntToJac(jnt_array, J)
return utils.kdl_to_mat(J)

View File

@ -48,18 +48,6 @@ class PandaArm(object):
self.uid, i, p.VELOCITY_CONTROL, targetVelocity=velocity self.uid, i, p.VELOCITY_CONTROL, targetVelocity=velocity
) )
def pose(self):
result = p.getLinkState(self.uid, self.ee_link_id, computeForwardKinematics=1)
_, _, _, _, frame_pos, frame_quat = result
T_world_ee = Transform(Rotation.from_quat(frame_quat), np.array(frame_pos))
return self.T_world_base.inverse() * T_world_ee
def jacobian(self, q):
q = np.r_[q, 0.0, 0.0].tolist()
q_dot, q_ddot = np.zeros(9).tolist(), np.zeros(9).tolist()
linear, _ = p.calculateJacobian(self.uid, 7, [0.0, 0.0, 0.0], q, q_dot, q_ddot)
return np.asarray(linear)[:, :7]
class PandaGripper(object): class PandaGripper(object):
def move(self, width): def move(self, width):

View File

@ -1,7 +1,8 @@
import rospy import rospy
from controllers import * from controllers import *
from simulation import * from model import *
from robot_sim import *
from utils import * from utils import *
@ -12,11 +13,11 @@ dt = 1.0 / 60.0
rospy.init_node("demo") rospy.init_node("demo")
env = SimPandaEnv(gui) env = SimPandaEnv(gui)
model = env.arm model = Model("panda_link0", "panda_link8")
controller = CartesianPoseController(model) controller = CartesianPoseController(model)
init_ee_pose = env.arm.pose() q, dq = env.arm.get_state()
marker = InteractiveMarkerWrapper("target", "panda_link0", init_ee_pose) marker = InteractiveMarkerWrapper("target", "panda_link0", model.pose(q))
# run the control loop # run the control loop
while True: while True:
@ -24,4 +25,5 @@ while True:
q, dq = env.arm.get_state() q, dq = env.arm.get_state()
cmd = controller.update(q, dq) cmd = controller.update(q, dq)
env.arm.set_desired_joint_velocities(cmd) env.arm.set_desired_joint_velocities(cmd)
env.forward(dt) env.forward(dt)

View File

@ -1,5 +1,6 @@
import numpy as np import numpy as np
from scipy.spatial.transform import Rotation from scipy.spatial.transform import Rotation
import PyKDL as kdl
from interactive_markers.interactive_marker_server import * from interactive_markers.interactive_marker_server import *
from interactive_markers.menu_handler import * from interactive_markers.menu_handler import *
@ -109,3 +110,32 @@ class Transform(object):
rotation = Rotation.from_quat(list[:4]) rotation = Rotation.from_quat(list[:4])
translation = list[4:] translation = list[4:]
return cls(rotation, translation) return cls(rotation, translation)
@classmethod
def from_kdl(cls, f):
rotation = Rotation.from_matrix(
np.array(
[
[f.M[0, 0], f.M[0, 1], f.M[0, 2]],
[f.M[1, 0], f.M[1, 1], f.M[1, 2]],
[f.M[2, 0], f.M[2, 1], f.M[2, 2]],
]
)
)
translation = np.r_[f.p[0], f.p[1], f.p[2]]
return cls(rotation, translation)
def to_kdl_jnt_array(q):
jnt_array = kdl.JntArray(len(q))
for i, q_i in enumerate(q):
jnt_array[i] = q_i
return jnt_array
def kdl_to_mat(m):
mat = np.zeros((m.rows(), m.columns()))
for i in range(m.rows()):
for j in range(m.columns()):
mat[i, j] = m[i, j]
return mat