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
106 : parent(parent), child(child), param_({parent2this, this2child, axis, 1.0})
107 {
108 runtime_.inertia = Eigen::Matrix<Scalar, 3, 3>::Zero();
109 auto link = new typename Object<Scalar>::Link(this);
110 parent->joints.Add(*link);
111 child->parent = this;
112 }
113
123 void SetState(Scalar state)
124 {
125 if (state > M_PI)
126 {
127 state -= 2 * M_PI;
128 }
129 if (state < -M_PI)
130 {
131 state += 2 * M_PI;
132 }
133 runtime_.state_angle.angle() = state;
135 }
136
146 void SetTarget(Scalar target)
147 {
148 if (target > M_PI)
149 {
150 target -= 2 * M_PI;
151 }
152 if (target < -M_PI)
153 {
154 target += 2 * M_PI;
155 }
156 runtime_.target_angle.angle() = target;
158 }
159
170 void SetBackwardMult(Scalar mult) { param_.ik_mult = mult; }
171};
172
184template <typename Scalar>
186{
187 public:
189
194 typedef struct
195 {
196 Inertia<Scalar> inertia;
197 } Param;
198
203 typedef struct
204 {
209 } Runtime;
210
212
214
217
224 Object(Inertia<Scalar> &inertia) : param_({inertia}) {}
225
237 void SetPosition(const Position<Scalar> &pos) { runtime_.state = pos; }
238
250 void SetQuaternion(const Quaternion<Scalar> &quat) { runtime_.state = quat; }
251
252 virtual void CalcBackward() {}
253};
254
269template <typename Scalar>
270class EndPoint : public Object<Scalar>
271{
272 private:
273 Eigen::Matrix<Scalar, 6, Eigen::Dynamic> *jacobian_matrix_ =
274 nullptr;
276 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> *delta_theta_ =
277 nullptr;
278 Eigen::Matrix<Scalar, 6, 1> err_weight_ =
279 Eigen::Matrix<Scalar, 6, 1>::Constant(1);
280 int joint_num_ = 0;
282
286 -1.0;
288 Scalar max_line_velocity_ = -1.0;
290
291 public:
298 EndPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
299
307
315
326 void SetErrorWeight(const Eigen::Matrix<Scalar, 6, 1> &weight) { err_weight_ = weight; }
327
338 void SetMaxAngularVelocity(Scalar velocity) { max_angular_velocity_ = velocity; }
339
350 Eigen::Matrix<Scalar, 3, 1> GetPositionError()
351 {
352 return target_pos_ - Object<Scalar>::runtime_.target.translation;
353 }
354
364 Eigen::Quaternion<Scalar> GetQuaternionError()
365 {
366 return Object<Scalar>::runtime_.target.rotation / target_quat_;
367 }
368
379 void SetMaxLineVelocity(Scalar velocity) { max_line_velocity_ = velocity; }
380
399 Eigen::Matrix<Scalar, 6, 1> CalcBackward(Scalar dt, int max_step = 10,
400 Scalar max_err = 1e-3, Scalar step_size = 1.0)
401 {
402 Eigen::Matrix<Scalar, 6, 1> error;
403
404 /* Initialize */
405 if (jacobian_matrix_ == nullptr)
406 {
407 Object<Scalar> *tmp = this;
408 for (int i = 0;; i++)
409 {
410 if (tmp->parent == nullptr)
411 {
412 joint_num_ = i;
413 break;
414 }
415 tmp = tmp->parent->parent;
416 }
417
418 jacobian_matrix_ = new Eigen::Matrix<Scalar, 6, Eigen::Dynamic>(6, joint_num_);
419
420 delta_theta_ = new Eigen::Matrix<Scalar, Eigen::Dynamic, 1>(joint_num_);
421 }
422
423 /* Apply Limition */
424 Position<Scalar> target_pos = target_pos_;
425 Quaternion<Scalar> target_quat = target_quat_;
427 {
428 Scalar max_pos_delta = max_angular_velocity_ * dt;
429 Scalar max_angle_delta = max_line_velocity_ * dt;
430
431 Position<Scalar> pos_err =
433 Eigen::AngleAxis<Scalar> angle_err(
435
436 Scalar pos_err_norm = pos_err.norm();
437
438 if (pos_err_norm > max_pos_delta)
439 {
440 pos_err = (max_pos_delta / pos_err_norm) * pos_err;
441 target_pos = this->runtime_.target.translation + pos_err;
442 }
443 else
444 {
445 target_pos = target_pos_;
446 }
447
448 if (angle_err.angle() > max_angle_delta)
449 {
450 angle_err.angle() = max_angle_delta;
451 target_quat = this->runtime_.target.rotation * angle_err;
452 }
453 else
454 {
455 target_quat = target_quat_;
456 }
457 }
458
459 for (int step = 0; step < max_step; ++step)
460 {
461 /* Calculate Error */
462 error.template head<3>() = target_pos - this->runtime_.target.translation;
463 error.template tail<3>() =
464 (Eigen::Quaternion<Scalar>(this->runtime_.target.rotation).conjugate() *
465 target_quat)
466 .vec();
467
468 error = err_weight_.array() * error.array();
469
470 auto err_norm = error.norm();
471
472 if (err_norm < max_err)
473 {
474 break;
475 }
476
477 /* Calculate Jacobian */
478 do
479 {
480 Joint<Scalar> *joint = this->parent;
481 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
482 {
483 /* J = [translation[3], rotation[3]] */
484 Eigen::Matrix<Scalar, 6, 1> d_transform;
485 d_transform.template head<3>() = joint->runtime_.target_axis.cross(
486 this->runtime_.target.translation - joint->runtime_.target.translation);
487
488 d_transform.template tail<3>() = joint->runtime_.target_axis;
489
490 jacobian_matrix_->col(joint_index) = d_transform;
491
492 joint = joint->parent->parent;
493 }
494 } while (0);
495
496 /* Calculate delta_theta: delta_theta = J^+ * error */
497 *delta_theta_ =
498 jacobian_matrix_->completeOrthogonalDecomposition().pseudoInverse() * error *
499 step_size / std::sqrt(err_norm);
500
501 /* Update Joint Angle */
502 do
503 {
504 Joint<Scalar> *joint = this->parent;
505
506 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
507 {
508 Eigen::AngleAxis<Scalar> target_angle_axis_delta((*delta_theta_)(joint_index),
509 joint->runtime_.target_axis);
510
511 target_angle_axis_delta =
512 Quaternion<Scalar>(Eigen::Quaternion<Scalar>(target_angle_axis_delta)) /
513 joint->runtime_.target.rotation;
514
515 joint->SetTarget(joint->runtime_.target_angle.angle() +
516 (*delta_theta_)(joint_index)*joint->param_.ik_mult);
517
518 joint = joint->parent->parent;
519 }
520 } while (0);
521
522 /* Recalculate Forward Kinematics */
523 do
524 {
525 Joint<Scalar> *joint = this->parent;
526
527 for (int joint_index = 0; joint_index < joint_num_; joint_index++)
528 {
529 if (joint_index == joint_num_ - 1)
530 {
531 auto start_point = reinterpret_cast<StartPoint<Scalar> *>(joint->parent);
532 start_point->CalcTargetForward();
533 break;
534 }
535
536 joint = joint->parent->parent;
537 }
538 } while (0);
539 }
540
541 return error;
542 }
543};
544
559template <typename Scalar>
560class StartPoint : public Object<Scalar>
561{
562 public:
564
571 StartPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
572
582 {
583 this->runtime_.target = this->runtime_.state;
584 auto fun = [&](Joint<Scalar> *joint) { return ForwardForeachFunLoop(joint, *this); };
585 this->joints.template Foreach<Joint<Scalar> *>(fun);
586 }
587
597 {
598 this->runtime_.target = this->runtime_.state;
599 auto fun = [&](Joint<Scalar> *joint)
600 { return TargetForwardForeachFunLoop(joint, *this); };
601 this->joints.template Foreach<Joint<Scalar> *>(fun);
602 }
603
613 {
614 Joint<Scalar> *res = nullptr;
615 auto fun = [&](Joint<Scalar> *joint)
616 { return InertiaForeachFunLoopStart(joint, res); };
617 this->joints.template Foreach<Joint<Scalar> *>(fun);
618 }
619
629 {
630 this->cog = CenterOfMass<Scalar>(this->param_.inertia, this->runtime_.state);
632 }
633
639 {
640 UNUSED(parent);
641 joint->runtime_.inertia = joint->child->param_.inertia
642 .Translate(joint->runtime_.state.translation -
643 joint->child->runtime_.state.translation)
644 .Rotate(joint->child->runtime_.state.rotation /
645 joint->runtime_.state.rotation);
646
647 joint->runtime_.inertia = Inertia<Scalar>::Rotate(
648 joint->runtime_.inertia, Eigen::Quaternion<Scalar>(joint->runtime_.state_angle));
649
650 auto fun_loop = [&](Joint<Scalar> *child_joint)
651 { return InertiaForeachFunLoop(child_joint, joint); };
652
653 auto fun_start = [&](Joint<Scalar> *child_joint)
654 { return InertiaForeachFunLoopStart(child_joint, joint); };
655
656 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
657 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_start);
658
659 return ErrorCode::OK;
660 }
661
667 {
668 auto new_inertia =
669 joint->child->param_.inertia
670 .Translate(parent->runtime_.state.translation -
671 joint->child->runtime_.state.translation)
672 .Rotate(parent->runtime_.state.rotation / joint->runtime_.state.rotation);
673
674 parent->runtime_.inertia = new_inertia + parent->runtime_.inertia;
675
676 auto fun_loop = [&](Joint<Scalar> *child_joint)
677 { return InertiaForeachFunLoop(child_joint, joint); };
678
679 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
680
681 return ErrorCode::OK;
682 }
683
689 {
690 Transform<Scalar> t_joint(joint->parent->runtime_.state + joint->param_.parent2this);
691
692 joint->runtime_.state = t_joint;
693
694 Transform<Scalar> t_child(
695 joint->runtime_.state.rotation * joint->runtime_.state_angle,
696 joint->runtime_.state.translation);
697
698 t_child = t_child + joint->param_.this2child;
699
700 joint->child->runtime_.state = t_child;
701 joint->runtime_.state_axis = joint->runtime_.state.rotation * joint->param_.axis;
702 joint->runtime_.target_axis = joint->runtime_.state_axis;
703
704 joint->runtime_.target = joint->runtime_.state;
705 joint->runtime_.target_angle = joint->runtime_.state_angle;
706 joint->child->runtime_.target = joint->child->runtime_.state;
707
708 auto fun = [&](Joint<Scalar> *child_joint)
709 { return ForwardForeachFunLoop(child_joint, start); };
710
711 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
712
713 return ErrorCode::OK;
714 }
715
721 StartPoint<Scalar> &start)
722 {
723 Transform<Scalar> t_joint(joint->parent->runtime_.target + joint->param_.parent2this);
724
725 joint->runtime_.target = t_joint;
726
727 Transform<Scalar> t_child(
728 joint->runtime_.target.rotation * joint->runtime_.target_angle,
730
731 t_child = t_child + joint->param_.this2child;
732 joint->child->runtime_.target = t_child;
733
734 joint->runtime_.target_axis = joint->runtime_.target.rotation * joint->param_.axis;
735
736 auto fun = [&](Joint<Scalar> *child_joint)
737 { return TargetForwardForeachFunLoop(child_joint, start); };
738
739 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
740
741 return ErrorCode::OK;
742 }
743
749 StartPoint<Scalar> &start)
750 {
751 CenterOfMass<Scalar> child_cog(joint->child->param_.inertia,
752 joint->child->runtime_.state);
753
754 start.cog += child_cog;
755
756 joint->child->joints.Foreach(TargetForwardForeachFunLoop, start);
757
758 return ErrorCode::OK;
759 }
760};
761
762} // namespace Kinematic
763
764} // namespace LibXR
765
766#endif
三维坐标轴类,继承自 Eigen::Matrix<Scalar, 3, 1>。 A 3D axis class, inheriting from Eigen::Matrix<Scalar,...
质心信息表示类。Represents the center of mass information.
Definition inertia.hpp:229
表示刚体的惯性张量和质量信息的类。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:170
机器人末端点(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 命名空间
关节参数结构体。 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.