libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
kinematic.hpp
1#pragma once
2
3#include <Eigen/Core>
4#include <Eigen/Dense>
5
6#include "Eigen/src/Core/Matrix.h"
7#include "Eigen/src/Geometry/Quaternion.h"
8#include "inertia.hpp"
9#include "list.hpp"
10#include "transform.hpp"
11
12namespace LibXR
13{
14
15using DefaultScalar = LIBXR_DEFAULT_SCALAR;
16
17namespace Kinematic
18{
30template <typename Scalar = DefaultScalar>
31class Joint;
32template <typename Scalar = DefaultScalar>
33class Object;
34template <typename Scalar = DefaultScalar>
35class EndPoint;
36template <typename Scalar = DefaultScalar>
37class StartPoint;
38
39template <typename Scalar>
40class Joint
41{
42 public:
57
62 typedef struct Runtime
63 {
64 Eigen::AngleAxis<Scalar>
66 Eigen::AngleAxis<Scalar>
68
69 Eigen::Matrix<Scalar, 3, 3>
71
74
79 } Runtime;
80
82
84 Object<Scalar> *child = nullptr;
86
101 : parent(parent), child(child), param_({parent2this, this2child, axis, 1.0})
102 {
103 runtime_.inertia = Eigen::Matrix<Scalar, 3, 3>::Zero();
104 auto link = new typename Object<Scalar>::Link(this);
105 parent->joints.Add(*link);
106 child->parent = this;
107 }
108
118 void SetState(Scalar state)
119 {
120 if (state > M_PI)
121 {
122 state -= 2 * M_PI;
123 }
124 if (state < -M_PI)
125 {
126 state += 2 * M_PI;
127 }
128 runtime_.state_angle.angle() = state;
130 }
131
141 void SetTarget(Scalar target)
142 {
143 if (target > M_PI)
144 {
145 target -= 2 * M_PI;
146 }
147 if (target < -M_PI)
148 {
149 target += 2 * M_PI;
150 }
151 runtime_.target_angle.angle() = target;
153 }
154
166};
167
179template <typename Scalar>
181{
182 public:
184
189 typedef struct
190 {
191 Inertia<Scalar> inertia;
192 } Param;
193
198 typedef struct
199 {
204 } Runtime;
205
207
209
212
219 Object(Inertia<Scalar> &inertia) : param_({inertia}) {}
220
233
246
247 virtual void CalcBackward() {}
248};
249
264template <typename Scalar>
265class EndPoint : public Object<Scalar>
266{
267 private:
268 Eigen::Matrix<Scalar, 6, Eigen::Dynamic> *jacobian_matrix_ =
269 nullptr;
271 Eigen::Matrix<Scalar, Eigen::Dynamic, 1> *delta_theta_ =
272 nullptr;
273 Eigen::Matrix<Scalar, 6, 1> err_weight_ =
274 Eigen::Matrix<Scalar, 6, 1>::Constant(1);
275 int joint_num_ = 0;
277
281 -1.0;
285
286 public:
293 EndPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
294
302
310
321 void SetErrorWeight(const Eigen::Matrix<Scalar, 6, 1> &weight) { err_weight_ = weight; }
322
334
345 Eigen::Matrix<Scalar, 3, 1> GetPositionError()
346 {
347 return target_pos_ - Object<Scalar>::runtime_.target.translation;
348 }
349
359 Eigen::Quaternion<Scalar> GetQuaternionError()
360 {
361 return Object<Scalar>::runtime_.target.rotation / target_quat_;
362 }
363
375
391 Eigen::Matrix<Scalar, 6, 1> CalcBackward(Scalar dt, int max_step = 10,
392 Scalar max_err = 1e-3, Scalar step_size = 1.0)
393 {
394 Eigen::Matrix<Scalar, 6, 1> error;
395
396 /* Initialize */
397 if (jacobian_matrix_ == nullptr)
398 {
399 Object<Scalar> *tmp = this;
400 for (int i = 0;; i++)
401 {
402 if (tmp->parent == nullptr)
403 {
404 joint_num_ = i;
405 break;
406 }
407 tmp = tmp->parent->parent;
408 }
409
410 jacobian_matrix_ = new Eigen::Matrix<Scalar, 6, Eigen::Dynamic>(6, joint_num_);
411
412 delta_theta_ = new Eigen::Matrix<Scalar, Eigen::Dynamic, 1>(joint_num_);
413 }
414
415 /* Apply Limition */
419 {
422
425 Eigen::AngleAxis<Scalar> angle_err(
427
428 Scalar pos_err_norm = pos_err.norm();
429
431 {
433 target_pos = this->runtime_.target.translation + pos_err;
434 }
435 else
436 {
438 }
439
440 if (angle_err.angle() > max_angle_delta)
441 {
442 angle_err.angle() = max_angle_delta;
443 target_quat = this->runtime_.target.rotation * angle_err;
444 }
445 else
446 {
448 }
449 }
450
451 for (int step = 0; step < max_step; ++step)
452 {
453 /* Calculate Error */
454 error.template head<3>() = target_pos - this->runtime_.target.translation;
455 error.template tail<3>() =
456 (Eigen::Quaternion<Scalar>(this->runtime_.target.rotation).conjugate() *
458 .vec();
459
460 error = err_weight_.array() * error.array();
461
462 auto err_norm = error.norm();
463
464 if (err_norm < max_err)
465 {
466 break;
467 }
468
469 /* Calculate Jacobian */
470 do
471 {
472 Joint<Scalar> *joint = this->parent;
474 {
475 /* J = [translation[3], rotation[3]] */
476 Eigen::Matrix<Scalar, 6, 1> d_transform;
477 d_transform.template head<3>() = joint->runtime_.target_axis.cross(
478 this->runtime_.target.translation - joint->runtime_.target.translation);
479
480 d_transform.template tail<3>() = joint->runtime_.target_axis;
481
483
484 joint = joint->parent->parent;
485 }
486 } while (0);
487
488 /* Calculate delta_theta: delta_theta = J^+ * error */
489 *delta_theta_ =
490 jacobian_matrix_->completeOrthogonalDecomposition().pseudoInverse() * error *
491 step_size / std::sqrt(err_norm);
492
493 /* Update Joint Angle */
494 do
495 {
496 Joint<Scalar> *joint = this->parent;
497
499 {
500 Eigen::AngleAxis<Scalar> target_angle_axis_delta((*delta_theta_)(joint_index),
501 joint->runtime_.target_axis);
502
504 Quaternion<Scalar>(Eigen::Quaternion<Scalar>(target_angle_axis_delta)) /
505 joint->runtime_.target.rotation;
506
507 joint->SetTarget(joint->runtime_.target_angle.angle() +
508 (*delta_theta_)(joint_index)*joint->param_.ik_mult);
509
510 joint = joint->parent->parent;
511 }
512 } while (0);
513
514 /* Recalculate Forward Kinematics */
515 do
516 {
517 Joint<Scalar> *joint = this->parent;
518
520 {
521 if (joint_index == joint_num_ - 1)
522 {
523 auto start_point = reinterpret_cast<StartPoint<Scalar> *>(joint->parent);
525 break;
526 }
527
528 joint = joint->parent->parent;
529 }
530 } while (0);
531 }
532
533 return error;
534 }
535};
536
551template <typename Scalar>
552class StartPoint : public Object<Scalar>
553{
554 public:
556
563 StartPoint(Inertia<Scalar> &inertia) : Object<Scalar>(inertia) {}
564
574 {
575 this->runtime_.target = this->runtime_.state;
576 auto fun = [&](Joint<Scalar> *joint) { return ForwardForeachFunLoop(joint, *this); };
577 this->joints.template Foreach<Joint<Scalar> *>(fun);
578 }
579
589 {
590 this->runtime_.target = this->runtime_.state;
591 auto fun = [&](Joint<Scalar> *joint)
592 { return TargetForwardForeachFunLoop(joint, *this); };
593 this->joints.template Foreach<Joint<Scalar> *>(fun);
594 }
595
605 {
606 Joint<Scalar> *res = nullptr;
607 auto fun = [&](Joint<Scalar> *joint)
608 { return InertiaForeachFunLoopStart(joint, res); };
609 this->joints.template Foreach<Joint<Scalar> *>(fun);
610 }
611
621 {
622 this->cog = CenterOfMass<Scalar>(this->param_.inertia, this->runtime_.state);
624 }
625
631 {
632 UNUSED(parent);
633 joint->runtime_.inertia = joint->child->param_.inertia
634 .Translate(joint->runtime_.state.translation -
635 joint->child->runtime_.state.translation)
636 .Rotate(joint->child->runtime_.state.rotation /
637 joint->runtime_.state.rotation);
638
639 joint->runtime_.inertia = Inertia<Scalar>::Rotate(
640 joint->runtime_.inertia, Eigen::Quaternion<Scalar>(joint->runtime_.state_angle));
641
644
647
648 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
649 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_start);
650
651 return ErrorCode::OK;
652 }
653
659 {
660 auto new_inertia =
661 joint->child->param_.inertia
662 .Translate(parent->runtime_.state.translation -
663 joint->child->runtime_.state.translation)
664 .Rotate(parent->runtime_.state.rotation / joint->runtime_.state.rotation);
665
666 parent->runtime_.inertia = new_inertia + parent->runtime_.inertia;
667
670
671 joint->child->joints.template Foreach<Joint<Scalar> *>(fun_loop);
672
673 return ErrorCode::OK;
674 }
675
681 {
682 Transform<Scalar> t_joint(joint->parent->runtime_.state + joint->param_.parent2this);
683
684 joint->runtime_.state = t_joint;
685
687 joint->runtime_.state.rotation * joint->runtime_.state_angle,
688 joint->runtime_.state.translation);
689
690 t_child = t_child + joint->param_.this2child;
691
692 joint->child->runtime_.state = t_child;
693 joint->runtime_.state_axis = joint->runtime_.state.rotation * joint->param_.axis;
694 joint->runtime_.target_axis = joint->runtime_.state_axis;
695
696 joint->runtime_.target = joint->runtime_.state;
697 joint->runtime_.target_angle = joint->runtime_.state_angle;
698 joint->child->runtime_.target = joint->child->runtime_.state;
699
700 auto fun = [&](Joint<Scalar> *child_joint)
702
703 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
704
705 return ErrorCode::OK;
706 }
707
714 {
715 Transform<Scalar> t_joint(joint->parent->runtime_.target + joint->param_.parent2this);
716
717 joint->runtime_.target = t_joint;
718
720 joint->runtime_.target.rotation * joint->runtime_.target_angle,
721 joint->runtime_.target.translation);
722
723 t_child = t_child + joint->param_.this2child;
724 joint->child->runtime_.target = t_child;
725
726 joint->runtime_.target_axis = joint->runtime_.target.rotation * joint->param_.axis;
727
728 auto fun = [&](Joint<Scalar> *child_joint)
730
731 joint->child->joints.template Foreach<Joint<Scalar> *>(fun);
732
733 return ErrorCode::OK;
734 }
735
742 {
743 CenterOfMass<Scalar> child_cog(joint->child->param_.inertia,
744 joint->child->runtime_.state);
745
746 start.cog += child_cog;
747
748 joint->child->joints.Foreach(TargetForwardForeachFunLoop, start);
749
750 return ErrorCode::OK;
751 }
752};
753
754} // namespace Kinematic
755
756} // namespace LibXR
三维坐标轴类,继承自 Eigen::Matrix<Scalar, 3, 1>。 A 3D axis class, inheriting from Eigen::Matrix<Scalar,...
质心信息表示类。Represents the center of mass information.
Definition inertia.hpp:219
表示刚体的惯性张量和质量信息的类。Provides a class to represent the inertia tensor and mass of a rigid body.
Definition inertia.hpp:23
Inertia Rotate(const Eigen::Matrix< Scalar, 3, 3 > &R) const
旋转惯性张量。Rotates the inertia tensor.
Definition inertia.hpp:160
机器人末端点(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:41
Object< Scalar > * parent
指向父物体的指针。 Pointer to the parent object.
Definition kinematic.hpp:83
Object< Scalar > * child
指向子物体的指针。 Pointer to the child object.
Definition kinematic.hpp:84
Joint(Axis< Scalar > axis, Object< Scalar > *parent, Transform< Scalar > &parent2this, Object< Scalar > *child, Transform< Scalar > &this2child)
构造 Joint 关节对象。 Constructs a Joint object.
Definition kinematic.hpp:99
void SetBackwardMult(Scalar mult)
设置逆向运动学计算的步长系数。 Sets the step size coefficient for inverse kinematics calculations.
Param param_
关节的参数配置。 Parameters of the joint.
Definition kinematic.hpp:85
Runtime runtime_
关节的运行时数据。 Runtime data of the joint.
Definition kinematic.hpp:81
void SetState(Scalar state)
设置关节当前状态角度。 Sets the current state angle of the joint.
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.
List::Node< Joint< Scalar > * > Link
关节链接类型。 Type for linking joints.
Param param_
物体参数。 Object parameters.
List joints
物体的关节列表。 List of joints associated with the object.
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:214
三维空间中的位置向量 / 3D position vector
Definition transform.hpp:37
四元数表示与运算,继承自 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 Color Control Library / LibXR终端颜色控制库
Definition esp_gpio.hpp:8
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
关节参数结构体。 Structure containing joint parameters.
Definition kinematic.hpp:48
Axis< Scalar > axis
关节旋转轴。 Rotation axis of the joint.
Definition kinematic.hpp:53
Transform< Scalar > this2child
Definition kinematic.hpp:51
Scalar ik_mult
逆向运动学步长系数。 Step size coefficient for inverse kinematics.
Definition kinematic.hpp:55
Transform< Scalar > parent2this
Definition kinematic.hpp:49
关节运行时状态结构体。 Structure containing runtime state of the joint.
Definition kinematic.hpp:63
Eigen::Matrix< Scalar, 3, 3 > inertia
关节的惯性矩阵。 Inertia matrix of the joint.
Definition kinematic.hpp:70
Transform< Scalar > target
目标状态的变换矩阵。 Transformation matrix of the target state.
Definition kinematic.hpp:78
Axis< Scalar > target_axis
目标关节轴向。 Target axis orientation.
Definition kinematic.hpp:73
Eigen::AngleAxis< Scalar > state_angle
当前关节角度状态。 Current joint angle state.
Definition kinematic.hpp:65
Axis< Scalar > state_axis
当前关节轴向。 Current axis orientation.
Definition kinematic.hpp:72
Eigen::AngleAxis< Scalar > target_angle
目标关节角度状态。 Target joint angle state.
Definition kinematic.hpp:67
Transform< Scalar > state
当前状态的变换矩阵。 Transformation matrix of the current state.
Definition kinematic.hpp:76
物体参数结构体,存储物体的惯性参数。 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.