@@ -85,11 +85,30 @@ Scene::Scene(const std::string& name, const std::string& urdf, const std::string
8585 joint.shortname () + " ' but this is not in the RoboPlan joint map." );
8686 }
8787 auto info = JointInfo (kPinocchioJointTypeMap .at (joint.shortname ()));
88- for (int idx = 0 ; idx < joint.nq (); ++idx) {
89- info.limits .min_position [idx] = mimic_model.lowerPositionLimit (q_idx);
90- info.limits .max_position [idx] = mimic_model.upperPositionLimit (q_idx);
91- ++q_idx;
88+ switch (info.type ) {
89+ case (JointType::PRISMATIC):
90+ case (JointType::REVOLUTE):
91+ info.limits .min_position [0 ] = mimic_model.lowerPositionLimit (q_idx);
92+ info.limits .max_position [0 ] = mimic_model.upperPositionLimit (q_idx);
93+ break ;
94+ case (JointType::PLANAR):
95+ // Only the position limits need to be incorporated, as orientation is unlimited.
96+ for (size_t dof = 0 ; dof < 2 ; ++dof) {
97+ info.limits .min_position [dof] = mimic_model.lowerPositionLimit (q_idx + dof);
98+ info.limits .max_position [dof] = mimic_model.upperPositionLimit (q_idx + dof);
99+ }
100+ break ;
101+ case (JointType::FLOATING):
102+ // Only the position limits need to be incorporated, as orientation is unlimited.
103+ for (size_t dof = 0 ; dof < 3 ; ++dof) {
104+ info.limits .min_position [dof] = mimic_model.lowerPositionLimit (q_idx + dof);
105+ info.limits .max_position [dof] = mimic_model.upperPositionLimit (q_idx + dof);
106+ }
107+ break ;
108+ default : // Includes continuous joints, where no operation is needed.
109+ break ;
92110 }
111+ q_idx += info.num_position_dofs ;
93112
94113 std::optional<YAML::Node> maybe_acc_limits;
95114 std::optional<YAML::Node> maybe_jerk_limits;
@@ -400,6 +419,173 @@ Eigen::VectorXi Scene::getJointPositionIndices(const std::vector<std::string>& j
400419 return Eigen::VectorXi::Map (q_indices.data (), q_indices.size ());
401420}
402421
422+ tl::expected<EigenVectorPair, std::string>
423+ Scene::getPositionLimitVectors (const std::string& group_name) const {
424+ const auto maybe_joint_group_info = getJointGroupInfo (group_name);
425+ if (!maybe_joint_group_info) {
426+ return tl::make_unexpected (" Failed to get position limit vectors: " +
427+ maybe_joint_group_info.error ());
428+ }
429+ const auto & joint_group_info = maybe_joint_group_info.value ();
430+
431+ // Initialize all limits as infinity and only set the joint DOFs that are finite.
432+ Eigen::VectorXd lower_limits = Eigen::VectorXd::Constant (
433+ joint_group_info.nq_collapsed , -std::numeric_limits<double >::infinity ());
434+ Eigen::VectorXd upper_limits = Eigen::VectorXd::Constant (joint_group_info.nq_collapsed ,
435+ std::numeric_limits<double >::infinity ());
436+ size_t q_idx = 0 ;
437+ for (size_t j_idx = 0 ; j_idx < joint_group_info.joint_names .size (); ++j_idx) {
438+ const auto & joint_name = joint_group_info.joint_names .at (j_idx);
439+ const auto maybe_joint_info = getJointInfo (joint_name);
440+ if (!maybe_joint_info) {
441+ return tl::make_unexpected (" Failed to get position limit vectors: " +
442+ maybe_joint_info.error ());
443+ }
444+ const auto & joint_info = maybe_joint_info.value ();
445+
446+ switch (joint_info.type ) {
447+ case JointType::FLOATING:
448+ // Position limits can be finite, orientation stays unlimited.
449+ for (int dof = 0 ; dof < 3 ; ++dof) {
450+ if (joint_info.limits .min_position .size () > dof) {
451+ lower_limits (q_idx + dof) = joint_info.limits .min_position (dof);
452+ }
453+ if (joint_info.limits .max_position .size () > dof) {
454+ upper_limits (q_idx + dof) = joint_info.limits .max_position (dof);
455+ }
456+ }
457+ q_idx += 6 ;
458+ break ;
459+ case JointType::PLANAR:
460+ // Position limits can be finite, orientation stays unlimited.
461+ for (int dof = 0 ; dof < 2 ; ++dof) {
462+ if (joint_info.limits .min_position .size () > dof) {
463+ lower_limits (q_idx + dof) = joint_info.limits .min_position (dof);
464+ }
465+ if (joint_info.limits .max_position .size () > dof) {
466+ upper_limits (q_idx + dof) = joint_info.limits .max_position (dof);
467+ }
468+ }
469+ q_idx += 3 ;
470+ break ;
471+ case JointType::CONTINUOUS:
472+ // Already has infinite limits, no action needed.
473+ ++q_idx;
474+ break ;
475+ default : // Prismatic or revolute.
476+ if (joint_info.limits .min_position .size () > 0 ) {
477+ lower_limits (q_idx) = joint_info.limits .min_position (0 );
478+ }
479+ if (joint_info.limits .max_position .size () > 0 ) {
480+ upper_limits (q_idx) = joint_info.limits .max_position (0 );
481+ }
482+ ++q_idx;
483+ }
484+ }
485+ return std::make_pair (lower_limits, upper_limits);
486+ }
487+
488+ tl::expected<EigenVectorPair, std::string>
489+ Scene::getVelocityLimitVectors (const std::string& group_name) const {
490+ const auto maybe_joint_group_info = getJointGroupInfo (group_name);
491+ if (!maybe_joint_group_info) {
492+ return tl::make_unexpected (" Failed to get velocity limit vectors: " +
493+ maybe_joint_group_info.error ());
494+ }
495+ const auto & joint_group_info = maybe_joint_group_info.value ();
496+
497+ // Initialize all limits as infinity and only set the joint DOFs that are finite.
498+ Eigen::VectorXd lower_limits = Eigen::VectorXd::Constant (
499+ joint_group_info.v_indices .size (), -std::numeric_limits<double >::infinity ());
500+ Eigen::VectorXd upper_limits = Eigen::VectorXd::Constant (joint_group_info.v_indices .size (),
501+ std::numeric_limits<double >::infinity ());
502+ size_t v_idx = 0 ;
503+ for (size_t j_idx = 0 ; j_idx < joint_group_info.joint_names .size (); ++j_idx) {
504+ const auto & joint_name = joint_group_info.joint_names .at (j_idx);
505+ const auto maybe_joint_info = getJointInfo (joint_name);
506+ if (!maybe_joint_info) {
507+ return tl::make_unexpected (" Failed to get velocity limit vectors: " +
508+ maybe_joint_info.error ());
509+ }
510+ const auto & joint_info = maybe_joint_info.value ();
511+
512+ for (size_t dof = 0 ; dof < joint_info.num_velocity_dofs ; ++dof) {
513+ const auto & max_vel = joint_info.limits .max_velocity (dof);
514+ lower_limits (v_idx + dof) = -max_vel;
515+ upper_limits (v_idx + dof) = max_vel;
516+ }
517+ v_idx += joint_info.num_velocity_dofs ;
518+ }
519+ return std::make_pair (lower_limits, upper_limits);
520+ }
521+
522+ tl::expected<EigenVectorPair, std::string>
523+ Scene::getAccelerationLimitVectors (const std::string& group_name) const {
524+ const auto maybe_joint_group_info = getJointGroupInfo (group_name);
525+ if (!maybe_joint_group_info) {
526+ return tl::make_unexpected (" Failed to get acceleration limit vectors: " +
527+ maybe_joint_group_info.error ());
528+ }
529+ const auto & joint_group_info = maybe_joint_group_info.value ();
530+
531+ // Initialize all limits as infinity and only set the joint DOFs that are finite.
532+ Eigen::VectorXd lower_limits = Eigen::VectorXd::Constant (
533+ joint_group_info.v_indices .size (), -std::numeric_limits<double >::infinity ());
534+ Eigen::VectorXd upper_limits = Eigen::VectorXd::Constant (joint_group_info.v_indices .size (),
535+ std::numeric_limits<double >::infinity ());
536+ size_t v_idx = 0 ;
537+ for (size_t j_idx = 0 ; j_idx < joint_group_info.joint_names .size (); ++j_idx) {
538+ const auto & joint_name = joint_group_info.joint_names .at (j_idx);
539+ const auto maybe_joint_info = getJointInfo (joint_name);
540+ if (!maybe_joint_info) {
541+ return tl::make_unexpected (" Failed to get acceleration limit vectors: " +
542+ maybe_joint_info.error ());
543+ }
544+ const auto & joint_info = maybe_joint_info.value ();
545+
546+ for (size_t dof = 0 ; dof < joint_info.num_velocity_dofs ; ++dof) {
547+ const auto & max_accel = joint_info.limits .max_acceleration (dof);
548+ lower_limits (v_idx + dof) = -max_accel;
549+ upper_limits (v_idx + dof) = max_accel;
550+ }
551+ v_idx += joint_info.num_velocity_dofs ;
552+ }
553+ return std::make_pair (lower_limits, upper_limits);
554+ }
555+
556+ tl::expected<EigenVectorPair, std::string>
557+ Scene::getJerkLimitVectors (const std::string& group_name) const {
558+ const auto maybe_joint_group_info = getJointGroupInfo (group_name);
559+ if (!maybe_joint_group_info) {
560+ return tl::make_unexpected (" Failed to get jerk limit vectors: " +
561+ maybe_joint_group_info.error ());
562+ }
563+ const auto & joint_group_info = maybe_joint_group_info.value ();
564+
565+ // Initialize all limits as infinity and only set the joint DOFs that are finite.
566+ Eigen::VectorXd lower_limits = Eigen::VectorXd::Constant (
567+ joint_group_info.v_indices .size (), -std::numeric_limits<double >::infinity ());
568+ Eigen::VectorXd upper_limits = Eigen::VectorXd::Constant (joint_group_info.v_indices .size (),
569+ std::numeric_limits<double >::infinity ());
570+ size_t v_idx = 0 ;
571+ for (size_t j_idx = 0 ; j_idx < joint_group_info.joint_names .size (); ++j_idx) {
572+ const auto & joint_name = joint_group_info.joint_names .at (j_idx);
573+ const auto maybe_joint_info = getJointInfo (joint_name);
574+ if (!maybe_joint_info) {
575+ return tl::make_unexpected (" Failed to get jerk limit vectors: " + maybe_joint_info.error ());
576+ }
577+ const auto & joint_info = maybe_joint_info.value ();
578+
579+ for (size_t dof = 0 ; dof < joint_info.num_velocity_dofs ; ++dof) {
580+ const auto & max_jerk = joint_info.limits .max_jerk (dof);
581+ lower_limits (v_idx + dof) = -max_jerk;
582+ upper_limits (v_idx + dof) = max_jerk;
583+ }
584+ v_idx += joint_info.num_velocity_dofs ;
585+ }
586+ return std::make_pair (lower_limits, upper_limits);
587+ }
588+
403589tl::expected<void , std::string> Scene::addBoxGeometry (const std::string& name,
404590 const std::string& parent_frame,
405591 const Box& box, const Eigen::Matrix4d& tform,
0 commit comments