libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
kinematic.hpp
1#pragma once
2
3#ifndef LIBXR_NO_EIGEN
4
5#include <Eigen/Core>
6#include <Eigen/Dense>
7
8#include "Eigen/src/Core/Matrix.h"
9#include "Eigen/src/Geometry/Quaternion.h"
10#include "inertia.hpp"
11#include "list.hpp"
12#include "transform.hpp"
13
14namespace LibXR
15{
16
17using DefaultScalar = LIBXR_DEFAULT_SCALAR;
18
19namespace Kinematic
20{
32template <typename Scalar = DefaultScalar>
33class Joint;
34template <typename Scalar = DefaultScalar>
35class Object;
36template <typename Scalar = DefaultScalar>
37class EndPoint;
38template <typename Scalar = DefaultScalar>
39class StartPoint;
40
41template <typename Scalar>
42class Joint
43{
44 public:
59
64 typedef struct Runtime
65 {
66 Eigen::AngleAxis<Scalar>
68 Eigen::AngleAxis<Scalar>
70
71 Eigen::Matrix<Scalar, 3, 3>
73
76
82
84
86 Object<Scalar> *child = nullptr;
88
103 : parent(parent), child(child), param_({parent2this, this2child, axis, 1.0})
104 {
105 runtime_.inertia = Eigen::Matrix<Scalar, 3, 3>::Zero();
106 auto link = new typename Object<Scalar>::Link(this);
107 parent->joints.Add(*link);
108 child->parent = this;
109 }
110
120 void SetState(Scalar state)
121 {
122 if (state > M_PI)
123 {
124 state -= 2 * M_PI;
125 }
126 if (state < -M_PI)
127 {
128 state += 2 * M_PI;
129 }
130 runtime_.state_angle.angle() = state;
132 }
133
143 void SetTarget(Scalar target)
144 {
145 if (target > M_PI)
146 {
147 target -= 2 * M_PI;
148 }
149 if (target < -M_PI)
150 {
151 target += 2 * M_PI;
152 }
153 runtime_.target_angle.angle() = target;
155 }
156
167 void SetBackwardMult(Scalar mult) { param_.ik_mult = mult; }
168};
169
181template <typename Scalar>
183{
184 public:
186
191 typedef struct
192 {
193 Inertia<Scalar> inertia;
194 } Param;
195
200 typedef struct
201 {
206 } Runtime;
207
209
211
214
221 Object(Inertia<Scalar> &inertia) : param_({inertia}) {}
222
234 void SetPosition(const Position<Scalar> &pos) { runtime_.state = pos; }
235
247 void SetQuaternion(const Quaternion<Scalar> &quat) { runtime_.state = quat; }
248
249 virtual void CalcBackward() {}
250};
251
266template <typename Scalar>
267class EndPoint : public Object<Scalar>
268{
269 private:
270 Eigen::Matrix<Scalar, 6, Eigen::Dynamic> *jacobian_matrix_ =
271 nullptr;
273 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> *delta_theta_ =
274 nullptr;
275 Eigen::Matrix<Scalar, 6, 1> err_weight_ =
276 Eigen::Matrix<Scalar, 6, 1>::Constant(1);
277 int joint_num_ = 0;
279
283 -1.0;
285 Scalar max_line_velocity_ = -1.0;
287
288 public:
295 EndPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
296
304
312
323 void SetErrorWeight(const Eigen::Matrix<Scalar, 6, 1> &weight) { err_weight_ = weight; }
324
335 void SetMaxAngularVelocity(Scalar velocity) { max_angular_velocity_ = velocity; }
336
347 Eigen::Matrix<Scalar, 3, 1> GetPositionError()
348 {
349 return target_pos_ - Object<Scalar>::runtime_.target.translation;
350 }
351
361 Eigen::Quaternion<Scalar> GetQuaternionError()
362 {
363 return Object<Scalar>::runtime_.target.rotation / target_quat_;
364 }
365
376 void SetMaxLineVelocity(Scalar velocity) { max_line_velocity_ = velocity; }
377
393 Eigen::Matrix<Scalar, 6, 1> CalcBackward(Scalar dt, int max_step = 10,
394 Scalar max_err = 1e-3, Scalar step_size = 1.0)
395 {
396 Eigen::Matrix<Scalar, 6, 1> error;
397
398 /* Initialize */
399 if (jacobian_matrix_ == nullptr)
400 {
401 Object<Scalar> *tmp = this;
402 for (int i = 0;; i++)
403 {
404 if (tmp->parent == nullptr)
405 {
406 joint_num_ = i;
407 break;
408 }
409 tmp = tmp->parent->parent;
410 }
411
412 jacobian_matrix_ = new Eigen::Matrix<Scalar, 6, Eigen::Dynamic>(6, joint_num_);
413
414 delta_theta_ = new Eigen::Matrix<Scalar, Eigen::Dynamic, 1>(joint_num_);
415 }
416
417 /* Apply Limition */
418 Position<Scalar> target_pos = target_pos_;
419 Quaternion<Scalar> target_quat = target_quat_;
421 {
422 Scalar max_pos_delta = max_angular_velocity_ * dt;
423 Scalar max_angle_delta = max_line_velocity_ * dt;
424
425 Position<Scalar> pos_err =
427 Eigen::AngleAxis<Scalar> angle_err(
429
430 Scalar pos_err_norm = pos_err.norm();
431
432 if (pos_err_norm > max_pos_delta)
433 {
434 pos_err = (max_pos_delta / pos_err_norm) * pos_err;
435 target_pos = this->runtime_.target.translation + pos_err;
436 }
437 else
438 {
439 target_pos = target_pos_;
440 }
441
442 if (angle_err.angle() > max_angle_delta)
443 {
444 angle_err.angle() = max_angle_delta;
445 target_quat = this->runtime_.target.rotation * angle_err;
446 }
447 else
448 {
449 target_quat = target_quat_;
450 }
451 }
452
453 for (int step = 0; step < max_step; ++step)
454 {
455 /* Calculate Error */
456 error.template head<3>() = target_pos - this->runtime_.target.translation;
457 error.template tail<3>() =
458 (Eigen::Quaternion<Scalar>(this->runtime_.target.rotation).conjugate() *
459 target_quat)
460 .vec();
461
462 error = err_weight_.array() * error.array();
463
464 auto err_norm = error.norm();
465
466 if (err_norm < max_err)
467 {
468 break;
469 }
470
471 /* Calculate Jacobian */
472 do
473 {
474 Joint<Scalar> *joint = this->parent;
475 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
476 {
477 /* J = [translation[3], rotation[3]] */
478 Eigen::Matrix<Scalar, 6, 1> d_transform;
479 d_transform.template head<3>() = joint->runtime_.target_axis.cross(
480 this->runtime_.target.translation - joint->runtime_.target.translation);
481
482 d_transform.template tail<3>() = joint->runtime_.target_axis;
483
484 jacobian_matrix_->col(joint_index) = d_transform;
485
486 joint = joint->parent->parent;
487 }
488 } while (0);
489
490 /* Calculate delta_theta: delta_theta = J^+ * error */
491 *delta_theta_ =
492 jacobian_matrix_->completeOrthogonalDecomposition().pseudoInverse() * error *
493 step_size / std::sqrt(err_norm);
494
495 /* Update Joint Angle */
496 do
497 {
498 Joint<Scalar> *joint = this->parent;
499
500 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
501 {
502 Eigen::AngleAxis<Scalar> target_angle_axis_delta((*delta_theta_)(joint_index),
503 joint->runtime_.target_axis);
504
505 target_angle_axis_delta =
506 Quaternion<Scalar>(Eigen::Quaternion<Scalar>(target_angle_axis_delta)) /
507 joint->runtime_.target.rotation;
508
509 joint->SetTarget(joint->runtime_.target_angle.angle() +
510 (*delta_theta_)(joint_index)*joint->param_.ik_mult);
511
512 joint = joint->parent->parent;
513 }
514 } while (0);
515
516 /* Recalculate Forward Kinematics */
517 do
518 {
519 Joint<Scalar> *joint = this->parent;
520
521 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
522 {
523 if (joint_index == joint_num_ - 1)
524 {
525 auto start_point = reinterpret_cast<StartPoint<Scalar> *>(joint->parent);
526 start_point->CalcTargetForward();
527 break;
528 }
529
530 joint = joint->parent->parent;
531 }
532 } while (0);
533 }
534
535 return error;
536 }
537};
538
553template <typename Scalar>
554class StartPoint : public Object<Scalar>
555{
556 public:
558
565 StartPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
566
576 {
577 this->runtime_.target = this->runtime_.state;
578 auto fun = [&](Joint<Scalar> *joint) { return ForwardForeachFunLoop(joint, *this); };
579 this->joints.template Foreach<Joint<Scalar> *>(fun);
580 }
581
591 {
592 this->runtime_.target = this->runtime_.state;
593 auto fun = [&](Joint<Scalar> *joint)
594 { return TargetForwardForeachFunLoop(joint, *this); };
595 this->joints.template Foreach<Joint<Scalar> *>(fun);
596 }
597
607 {
608 Joint<Scalar> *res = nullptr;
609 auto fun = [&](Joint<Scalar> *joint)
610 { return InertiaForeachFunLoopStart(joint, res); };
611 this->joints.template Foreach<Joint<Scalar> *>(fun);
612 }
613
623 {
624 this->cog = CenterOfMass<Scalar>(this->param_.inertia, this->runtime_.state);
626 }
627
633 {
634 UNUSED(parent);
635 joint->runtime_.inertia = joint->child->param_.inertia
636 .Translate(joint->runtime_.state.translation -
637 joint->child->runtime_.state.translation)
638 .Rotate(joint->child->runtime_.state.rotation /
639 joint->runtime_.state.rotation);
640
641 joint->runtime_.inertia = Inertia<Scalar>::Rotate(
642 joint->runtime_.inertia, Eigen::Quaternion<Scalar>(joint->runtime_.state_angle));
643
644 auto fun_loop = [&](Joint<Scalar> *child_joint)
645 { return InertiaForeachFunLoop(child_joint, joint); };
646
647 auto fun_start = [&](Joint<Scalar> *child_joint)
648 { return InertiaForeachFunLoopStart(child_joint, joint); };
649
650 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
651 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_start);
652
653 return ErrorCode::OK;
654 }
655
661 {
662 auto new_inertia =
663 joint->child->param_.inertia
664 .Translate(parent->runtime_.state.translation -
665 joint->child->runtime_.state.translation)
666 .Rotate(parent->runtime_.state.rotation / joint->runtime_.state.rotation);
667
668 parent->runtime_.inertia = new_inertia + parent->runtime_.inertia;
669
670 auto fun_loop = [&](Joint<Scalar> *child_joint)
671 { return InertiaForeachFunLoop(child_joint, joint); };
672
673 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
674
675 return ErrorCode::OK;
676 }
677
683 {
684 Transform<Scalar> t_joint(joint->parent->runtime_.state + joint->param_.parent2this);
685
686 joint->runtime_.state = t_joint;
687
688 Transform<Scalar> t_child(
689 joint->runtime_.state.rotation * joint->runtime_.state_angle,
690 joint->runtime_.state.translation);
691
692 t_child = t_child + joint->param_.this2child;
693
694 joint->child->runtime_.state = t_child;
695 joint->runtime_.state_axis = joint->runtime_.state.rotation * joint->param_.axis;
696 joint->runtime_.target_axis = joint->runtime_.state_axis;
697
698 joint->runtime_.target = joint->runtime_.state;
699 joint->runtime_.target_angle = joint->runtime_.state_angle;
700 joint->child->runtime_.target = joint->child->runtime_.state;
701
702 auto fun = [&](Joint<Scalar> *child_joint)
703 { return ForwardForeachFunLoop(child_joint, start); };
704
705 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
706
707 return ErrorCode::OK;
708 }
709
715 StartPoint<Scalar> &start)
716 {
717 Transform<Scalar> t_joint(joint->parent->runtime_.target + joint->param_.parent2this);
718
719 joint->runtime_.target = t_joint;
720
721 Transform<Scalar> t_child(
722 joint->runtime_.target.rotation * joint->runtime_.target_angle,
724
725 t_child = t_child + joint->param_.this2child;
726 joint->child->runtime_.target = t_child;
727
728 joint->runtime_.target_axis = joint->runtime_.target.rotation * joint->param_.axis;
729
730 auto fun = [&](Joint<Scalar> *child_joint)
731 { return TargetForwardForeachFunLoop(child_joint, start); };
732
733 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
734
735 return ErrorCode::OK;
736 }
737
743 StartPoint<Scalar> &start)
744 {
745 CenterOfMass<Scalar> child_cog(joint->child->param_.inertia,
746 joint->child->runtime_.state);
747
748 start.cog += child_cog;
749
750 joint->child->joints.Foreach(TargetForwardForeachFunLoop, start);
751
752 return ErrorCode::OK;
753 }
754};
755
756} // namespace Kinematic
757
758} // namespace LibXR
759
760#endif
三维坐标轴类,继承自 Eigen::Matrix<Scalar, 3, 1>。 A 3D axis class, inheriting from Eigen::Matrix<Scalar,...
质心信息表示类。Represents the center of mass information.
Definition inertia.hpp:221
表示刚体的惯性张量和质量信息的类。Provides a class to represent the inertia tensor and mass of a rigid body.
Definition inertia.hpp:25
Inertia Rotate(const Eigen::Matrix< Scalar, 3, 3 > &R) const
旋转惯性张量。Rotates the inertia tensor.
Definition inertia.hpp:162
机器人末端点(EndPoint)类,继承自 Object。 EndPoint class representing the end effector of a robotic system,...
Eigen::Matrix< Scalar, 3, 1 > GetPositionError()
获取末端点位置误差。 Gets the position error of the end effector.
void SetMaxAngularVelocity(Scalar velocity)
设置最大角速度。 Sets the maximum angular velocity.
Eigen::Matrix< Scalar, 6, 1 > err_weight_
误差权重矩阵。 Error weight matrix.
Quaternion< Scalar > target_quat_
目标四元数方向。 Target quaternion orientation.
void SetTargetQuaternion(const Quaternion< Scalar > &quat)
设置目标四元数方向。 Sets the target quaternion orientation.
Eigen::Matrix< Scalar, 6, Eigen::Dynamic > * jacobian_matrix_
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > * delta_theta_
关节角度调整量。 Joint angle adjustments.
void SetTargetPosition(const Position< Scalar > &pos)
设置目标位置。 Sets the target position.
Eigen::Matrix< Scalar, 6, 1 > CalcBackward(Scalar dt, int max_step=10, Scalar max_err=1e-3, Scalar step_size=1.0)
计算逆运动学(IK),调整关节角度以达到目标位置和方向。 Computes inverse kinematics (IK) to adjust joint angles for reaching the...
Eigen::Quaternion< Scalar > GetQuaternionError()
获取末端点方向误差。 Gets the orientation error of the end effector.
void SetErrorWeight(const Eigen::Matrix< Scalar, 6, 1 > &weight)
设置误差权重矩阵。 Sets the error weight matrix.
Position< Scalar > target_pos_
目标位置。 Target position.
void SetMaxLineVelocity(Scalar velocity)
设置最大线速度。 Sets the maximum linear velocity.
EndPoint(Inertia< Scalar > &inertia)
构造 EndPoint 末端点对象。 Constructs an EndPoint object.
关节(Joint)类,表示机器人连杆间的旋转关节。 Joint class representing a rotational joint between robot links.
Definition kinematic.hpp:43
Object< Scalar > * parent
指向父物体的指针。 Pointer to the parent object.
Definition kinematic.hpp:85
Object< Scalar > * child
指向子物体的指针。 Pointer to the child object.
Definition kinematic.hpp:86
Joint(Axis< Scalar > axis, Object< Scalar > *parent, Transform< Scalar > &parent2this, Object< Scalar > *child, Transform< Scalar > &this2child)
构造 Joint 关节对象。 Constructs a Joint object.
struct LibXR::Kinematic::Joint::Runtime Runtime
关节运行时状态结构体。 Structure containing runtime state of the joint.
void SetBackwardMult(Scalar mult)
设置逆向运动学计算的步长系数。 Sets the step size coefficient for inverse kinematics calculations.
Param param_
关节的参数配置。 Parameters of the joint.
Definition kinematic.hpp:87
Runtime runtime_
关节的运行时数据。 Runtime data of the joint.
Definition kinematic.hpp:83
void SetState(Scalar state)
设置关节当前状态角度。 Sets the current state angle of the joint.
struct LibXR::Kinematic::Joint::Param Param
关节参数结构体。 Structure containing joint parameters.
void SetTarget(Scalar target)
设置关节的目标角度。 Sets the target angle of the joint.
机器人中的物体(Object)类。 Object class representing an entity in the robot.
void SetPosition(const Position< Scalar > &pos)
设置物体的位置信息。 Sets the position of the object.
Object(Inertia< Scalar > &inertia)
使用惯性参数构造 Object 对象。 Constructs an Object using inertia parameters.
Runtime runtime_
物体运行时状态。 Object runtime data.
Joint< Scalar > * parent
指向父关节的指针。 Pointer to the parent joint.
Param param_
物体参数。 Object parameters.
List joints
物体的关节列表。 List of joints associated with the object.
List::Node< Joint< Scalar > * > Link
关节链接类型。 Type for linking joints.
void SetQuaternion(const Quaternion< Scalar > &quat)
设置物体的旋转信息(四元数表示)。 Sets the rotation of the object using a quaternion.
机器人起始点(StartPoint)类,继承自 Object。 StartPoint class representing the base or root of a robotic kinematic...
void CalcInertia()
计算机器人系统的惯性分布。 Computes the inertia distribution of the robotic system.
StartPoint(Inertia< Scalar > &inertia)
构造 StartPoint 物体对象。 Constructs a StartPoint object.
static ErrorCode ForwardForeachFunLoop(Joint< Scalar > *joint, StartPoint< Scalar > &start)
计算当前状态的前向运动学(FK)。 Computes forward kinematics (FK) for the current state.
void CalcForward()
计算当前状态的前向运动学(FK)。 Computes forward kinematics (FK) for the current state.
static ErrorCode InertiaForeachFunLoopStart(Joint< Scalar > *joint, Joint< Scalar > *parent)
计算起始点惯性(首次遍历)。 Computes the inertia of the start point (first traversal).
void CalcCenterOfMass()
计算机器人系统的质心。 Computes the center of mass (CoM) of the robotic system.
void CalcTargetForward()
计算目标状态的前向运动学(FK)。 Computes forward kinematics (FK) for the target state.
static ErrorCode InertiaForeachFunLoop(Joint< Scalar > *joint, Joint< Scalar > *parent)
计算机器人系统的惯性(后续遍历)。 Computes the inertia of the robotic system (subsequent traversal).
static ErrorCode CenterOfMassForeachFunLoop(Joint< Scalar > *joint, StartPoint< Scalar > &start)
计算系统的质心。 Computes the center of mass of the system.
CenterOfMass< Scalar > cog
机器人质心。 The center of mass of the robot.
static ErrorCode TargetForwardForeachFunLoop(Joint< Scalar > *joint, StartPoint< Scalar > &start)
计算目标状态的前向运动学(FK)。 Computes forward kinematics (FK) for the target state.
数据节点模板,继承自 BaseNode,用于存储具体数据类型。 Template data node that inherits from BaseNode to store specific data...
Definition list.hpp:60
链表实现,用于存储和管理数据节点。 A linked list implementation for storing and managing data nodes.
Definition list.hpp:23
ErrorCode Foreach(Func func)
遍历链表中的每个节点,并应用回调函数。 Iterates over each node in the list and applies a callback function.
Definition list.hpp:172
三维空间中的位置向量 / 3D position vector
Definition transform.hpp:39
四元数表示与运算,继承自 Eigen::Quaternion / Quaternion representation and operations, inheriting from Eigen::Qua...
表示三维空间中的刚体变换,包括旋转和位移。Represents rigid body transformations in 3D space, including rotation and transl...
Quaternion< Scalar > rotation
Position< Scalar > translation
LibXR 命名空间
Definition ch32_gpio.hpp:9
关节参数结构体。 Structure containing joint parameters.
Definition kinematic.hpp:50
Axis< Scalar > axis
关节旋转轴。 Rotation axis of the joint.
Definition kinematic.hpp:55
Transform< Scalar > this2child
Definition kinematic.hpp:53
Scalar ik_mult
逆向运动学步长系数。 Step size coefficient for inverse kinematics.
Definition kinematic.hpp:57
Transform< Scalar > parent2this
Definition kinematic.hpp:51
关节运行时状态结构体。 Structure containing runtime state of the joint.
Definition kinematic.hpp:65
Eigen::Matrix< Scalar, 3, 3 > inertia
关节的惯性矩阵。 Inertia matrix of the joint.
Definition kinematic.hpp:72
Transform< Scalar > target
目标状态的变换矩阵。 Transformation matrix of the target state.
Definition kinematic.hpp:80
Axis< Scalar > target_axis
目标关节轴向。 Target axis orientation.
Definition kinematic.hpp:75
Eigen::AngleAxis< Scalar > state_angle
当前关节角度状态。 Current joint angle state.
Definition kinematic.hpp:67
Axis< Scalar > state_axis
当前关节轴向。 Current axis orientation.
Definition kinematic.hpp:74
Eigen::AngleAxis< Scalar > target_angle
目标关节角度状态。 Target joint angle state.
Definition kinematic.hpp:69
Transform< Scalar > state
当前状态的变换矩阵。 Transformation matrix of the current state.
Definition kinematic.hpp:78
物体参数结构体,存储物体的惯性参数。 Structure storing inertia parameters of the object.
物体运行时状态结构体,存储物体的变换信息。 Structure storing runtime transformation data of the object.
Transform< Scalar > target
物体的目标状态变换矩阵。 Transformation matrix of the target state.
Transform< Scalar > state
物体的当前状态变换矩阵。 Transformation matrix of the current state.