// // Created by xtkuang on 2025/7/8. // #ifndef STATE_H #define STATE_H #pragma once #include #include "utils/math/se3.h" namespace cmvr::dyn { template class Robot; template class State { public: template friend class Robot; template using ContainerType = typename std::conditional_t<(N > 0), std::array, std::vector >; unsigned int GetBaseLinkIdx() const { // NOLINT return base_link_user_idx; } template void SetQ(const Eigen::MatrixBase &new_q) { Set(q, new_q.eval()); } Eigen::Vector GetQ() { return q(utr_joint_map); } template void SetQdot(const Eigen::MatrixBase &new_qdot) { Set(qdot, new_qdot.eval()); } Eigen::Vector GetQdot() { return qdot(utr_joint_map); } template void SetQddot(const Eigen::MatrixBase &new_qddot) { Set(qddot, new_qddot.eval()); } Eigen::Vector GetQddot() { return qddot(utr_joint_map); } template void SetTau(const Eigen::MatrixBase &new_tau) { Set(tau, new_tau.eval()); } Eigen::Vector GetTau() { return tau(utr_joint_map); } void SetV0(const math::se3v::MatrixType &new_V0) { V0 = new_V0; } // Vdot of root link in root frame void SetVdot0(const math::se3v::MatrixType &new_Vdot0) { Vdot0 = new_Vdot0; } void SetGravity(const math::se3v::MatrixType &gravity) { Vdot0 = -gravity; } ContainerType GetJointNames() const { return joint_names; } [[nodiscard]] std::vector GetLinkNames() const { return link_names; } private: explicit State(int dof) { if (!(DOF < 0 || dof == DOF)) { throw std::runtime_error("State initialization failed"); } if constexpr (DOF < 0) { q.resize(dof); qdot.resize(dof); qddot.resize(dof); tau.resize(dof); E.resize(dof + 1, math::SE3::Identity()); S.resize(6, dof); T.resize(dof + 1, math::SE3::Identity()); V.resize(6, dof); Vdot.resize(6, dof); F.resize(6, dof); joint_names.resize(dof); utr_joint_map.resize(dof); rtu_joint_map.resize(dof); } else { E.fill(math::SE3::Identity()); T.fill(math::SE3::Identity()); } q.setZero(); qdot.setZero(); qddot.setZero(); S.setZero(); V.setZero(); Vdot0.setZero(); F.setZero(); } template void Set(Eigen::Vector &s, const Eigen::Vector &i) { if (s.size() == i.size()) { s = i(rtu_joint_map); } else if (s.size() > i.size()) { s.template head<>(i.size()) = i(rtu_joint_map.template head<>(i.size())); } else { throw std::runtime_error("i.size cannot be greater than s.size"); } } ContainerType joint_names; Eigen::Vector utr_joint_map; // user joint idx -> robot joint idx Eigen::Vector rtu_joint_map; // robot joint idx -> user joint idx unsigned int base_link_user_idx; std::vector link_names; std::vector::LinkIdx_> utr_link_map; // user link idx -> robot dummy/sub link idx public: Eigen::Vector q; Eigen::Vector qdot; Eigen::Vector qddot; Eigen::Vector tau; math::se3v::MatrixType V0{math::se3v::MatrixType::Zero()}; math::se3v::MatrixType Vdot0{math::se3v::MatrixType::Zero()}; ContainerType E{}; // exponential mapping Eigen::Matrix S; // S(q_0,...q_i) in root frame ContainerType T{}; // product of exponential Eigen::Matrix V; Eigen::Matrix Vdot; Eigen::Matrix F; }; } #endif //STATE_H