@@ -705,7 +705,7 @@ hardware_interface::return_type IgnitionSystem::read(
705
705
this ->dataPtr ->joints_ [i].joint_position = jointPositions->Data ()[0 ];
706
706
this ->dataPtr ->joints_ [i].joint_velocity = jointVelocity->Data ()[0 ];
707
707
// set effort state interface to computed/propagated effort command - passthrough because of ignitionrobotics/ign-physics#124
708
- this ->dataPtr ->joints_ [i].joint_effort = this ->dataPtr ->joints_ [i].joint_effort_cmd ;
708
+ this ->dataPtr ->joints_ [i].joint_effort = this ->dataPtr ->joints_ [i].joint_effort_cmd ;
709
709
}
710
710
711
711
for (unsigned int i = 0 ; i < this ->dataPtr ->imus_ .size (); ++i) {
@@ -845,8 +845,8 @@ hardware_interface::return_type IgnitionSystem::write(
845
845
velocity_error, std::chrono::duration<double >(
846
846
period.to_chrono <std::chrono::nanoseconds>()));
847
847
848
- // remember for potential effort state interface
849
- this ->dataPtr ->joints_ [i].joint_effort_cmd = target_force;
848
+ // remember for potential effort state interface
849
+ this ->dataPtr ->joints_ [i].joint_effort_cmd = target_force;
850
850
851
851
auto forceCmd =
852
852
this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointForceCmd>(
@@ -886,7 +886,7 @@ hardware_interface::return_type IgnitionSystem::write(
886
886
887
887
// calculate target force/torque - output of inner pid
888
888
double target_force = this ->dataPtr ->joints_ [i].pid_vel .Update (
889
- velocity_error , std::chrono::duration<double >(
889
+ position_error , std::chrono::duration<double >(
890
890
period.to_chrono <std::chrono::nanoseconds>()));
891
891
892
892
// remember for potential effort state interface
@@ -921,6 +921,135 @@ hardware_interface::return_type IgnitionSystem::write(
921
921
}
922
922
}
923
923
924
+ // set values of all mimic joints with respect to mimicked joint
925
+ for (const auto & mimic_joint : this ->dataPtr ->mimic_joints_ ) {
926
+ for (const auto & mimic_interface : mimic_joint.interfaces_to_mimic ) {
927
+ // assuming every mimic joint has axis
928
+ const auto * jointAxis =
929
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointAxis>(
930
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint );
931
+
932
+ if (mimic_interface == " position" ) {
933
+ // Get the joint position
934
+ double position_mimicked_joint =
935
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointPosition>(
936
+ this ->dataPtr ->joints_ [mimic_joint.mimicked_joint_index ].sim_joint )->Data ()[0 ];
937
+
938
+ double position_mimic_joint =
939
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointPosition>(
940
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint )->Data ()[0 ];
941
+
942
+ double position_error = position_mimic_joint - std::clamp (
943
+ position_mimicked_joint *
944
+ mimic_joint.multiplier , jointAxis->Data ().Lower (),
945
+ jointAxis->Data ().Upper ());
946
+
947
+ position_error =
948
+ copysign (
949
+ 1.0 ,
950
+ position_error) *
951
+ std::clamp (
952
+ std::abs (position_error), 0.0 ,
953
+ std::abs (jointAxis->Data ().Upper () - jointAxis->Data ().Lower ()));
954
+
955
+ // calculate target velocity - output of outer pid - input to inner pid
956
+ double target_vel = this ->dataPtr ->joints_ [mimic_joint.joint_index ].pid_pos .Update (
957
+ position_error, std::chrono::duration<double >(
958
+ period.to_chrono <std::chrono::nanoseconds>()));
959
+
960
+ // get mimic joint velocity
961
+ double velocity_mimic_joint =
962
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointVelocity>(
963
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint )->Data ()[0 ];
964
+
965
+ double velocity_error = velocity_mimic_joint - std::clamp (
966
+ target_vel, -1.0 * jointAxis->Data ().MaxVelocity (),
967
+ jointAxis->Data ().MaxVelocity ());
968
+
969
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].pid_vel .SetCmdOffset (
970
+ mimic_joint.multiplier *
971
+ this ->dataPtr ->joints_ [mimic_joint.mimicked_joint_index ].joint_effort_cmd );
972
+ // calculate target force/torque - output of inner pid
973
+ double target_force = this ->dataPtr ->joints_ [mimic_joint.joint_index ].pid_vel .Update (
974
+ position_error, std::chrono::duration<double >(
975
+ period.to_chrono <std::chrono::nanoseconds>()));
976
+
977
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].joint_effort_cmd = target_force;
978
+
979
+ auto forceCmd =
980
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointForceCmd>(
981
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint );
982
+
983
+ if (forceCmd == nullptr ) {
984
+ this ->dataPtr ->ecm ->CreateComponent (
985
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint ,
986
+ ignition::gazebo::components::JointForceCmd ({target_force}));
987
+ } else {
988
+ *forceCmd = ignition::gazebo::components::JointForceCmd (
989
+ {target_force});
990
+ }
991
+ }
992
+ if (mimic_interface == " velocity" ) {
993
+ // get the velocity of mimicked joint
994
+ double velocity_mimicked_joint =
995
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointVelocity>(
996
+ this ->dataPtr ->joints_ [mimic_joint.mimicked_joint_index ].sim_joint )->Data ()[0 ];
997
+
998
+ // get mimic joint velocity
999
+ double velocity_mimic_joint =
1000
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointVelocity>(
1001
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint )->Data ()[0 ];
1002
+
1003
+ double velocity_error = velocity_mimic_joint - std::clamp (
1004
+ mimic_joint.multiplier * velocity_mimicked_joint, -1.0 * jointAxis->Data ().MaxVelocity (),
1005
+ jointAxis->Data ().MaxVelocity ());
1006
+
1007
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].pid_vel .SetCmdOffset (
1008
+ mimic_joint.multiplier *
1009
+ this ->dataPtr ->joints_ [mimic_joint.mimicked_joint_index ].joint_effort_cmd );
1010
+
1011
+ // calculate target force/torque - output of inner pid
1012
+ double target_force = this ->dataPtr ->joints_ [mimic_joint.joint_index ].pid_vel .Update (
1013
+ velocity_error, std::chrono::duration<double >(
1014
+ period.to_chrono <std::chrono::nanoseconds>()));
1015
+
1016
+ auto forceCmd =
1017
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointForceCmd>(
1018
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint );
1019
+
1020
+ if (forceCmd == nullptr ) {
1021
+ this ->dataPtr ->ecm ->CreateComponent (
1022
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint ,
1023
+ ignition::gazebo::components::JointForceCmd ({target_force}));
1024
+ } else {
1025
+ *forceCmd = ignition::gazebo::components::JointForceCmd (
1026
+ {target_force});
1027
+ }
1028
+ }
1029
+ if (mimic_interface == " effort" ) {
1030
+ // TODO(ahcorde): Revisit this part ignitionrobotics/ign-physics#124
1031
+ // Get the joint force
1032
+ // const auto * jointForce =
1033
+ // _ecm.Component<ignition::gazebo::components::JointForce>(
1034
+ // this->dataPtr->sim_joints_[j]);
1035
+ if (!this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointForceCmd>(
1036
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint ))
1037
+ {
1038
+ this ->dataPtr ->ecm ->CreateComponent (
1039
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint ,
1040
+ ignition::gazebo::components::JointForceCmd ({0 }));
1041
+ } else {
1042
+ const auto jointEffortCmd =
1043
+ this ->dataPtr ->ecm ->Component <ignition::gazebo::components::JointForceCmd>(
1044
+ this ->dataPtr ->joints_ [mimic_joint.joint_index ].sim_joint );
1045
+ *jointEffortCmd = ignition::gazebo::components::JointForceCmd (
1046
+ {mimic_joint.multiplier *
1047
+ this ->dataPtr ->joints_ [mimic_joint.mimicked_joint_index ].joint_effort_cmd });
1048
+ }
1049
+ }
1050
+ }
1051
+ }
1052
+
924
1053
return hardware_interface::return_type::OK;
925
1054
}
926
1055
} // namespace ign_ros2_control
0 commit comments