2
2
#include " robot_dart/robot.hpp"
3
3
#include " robot_dart/utils.hpp"
4
4
5
+ #include < dart/dynamics/BallJoint.hpp>
6
+ #include < dart/dynamics/EulerJoint.hpp>
7
+ #include < dart/dynamics/FreeJoint.hpp>
8
+ #include < dart/dynamics/RevoluteJoint.hpp>
9
+
5
10
namespace robot_dart {
6
11
namespace control {
7
12
PDControl::PDControl () : RobotControl() {}
8
- PDControl::PDControl (const Eigen::VectorXd& ctrl, bool full_control) : RobotControl(ctrl, full_control) {}
9
- PDControl::PDControl (const Eigen::VectorXd& ctrl, const std::vector<std::string>& controllable_dofs) : RobotControl(ctrl, controllable_dofs) {}
13
+ PDControl::PDControl (const Eigen::VectorXd& ctrl, bool full_control, bool use_angular_errors ) : RobotControl(ctrl, full_control), _use_angular_errors(use_angular_errors ) {}
14
+ PDControl::PDControl (const Eigen::VectorXd& ctrl, const std::vector<std::string>& controllable_dofs, bool use_angular_errors ) : RobotControl(ctrl, controllable_dofs), _use_angular_errors(use_angular_errors ) {}
10
15
11
16
void PDControl::configure ()
12
17
{
@@ -21,14 +26,77 @@ namespace robot_dart {
21
26
{
22
27
ROBOT_DART_ASSERT (_control_dof == _ctrl.size (), " PDControl: Controller parameters size is not the same as DOFs of the robot" , Eigen::VectorXd::Zero (_control_dof));
23
28
auto robot = _robot.lock ();
24
- Eigen::VectorXd& target_positions = _ctrl;
25
29
26
- Eigen::VectorXd q = robot->positions (_controllable_dofs);
27
30
Eigen::VectorXd dq = robot->velocities (_controllable_dofs);
28
31
32
+ Eigen::VectorXd error;
33
+ if (!_use_angular_errors) {
34
+ Eigen::VectorXd q = robot->positions (_controllable_dofs);
35
+ error = _ctrl - q;
36
+ }
37
+ else {
38
+ error = Eigen::VectorXd::Zero (_control_dof);
39
+
40
+ std::unordered_map<size_t , Eigen::VectorXd> joint_vals, joint_desired, errors;
41
+
42
+ for (int i = 0 ; i < _control_dof; ++i) {
43
+ auto dof = robot->dof (_controllable_dofs[i]);
44
+ size_t joint_index = dof->getJoint ()->getJointIndexInSkeleton ();
45
+ if (joint_vals.find (joint_index) == joint_vals.end ()) {
46
+ joint_vals[joint_index] = dof->getJoint ()->getPositions ();
47
+ joint_desired[joint_index] = dof->getJoint ()->getPositions ();
48
+ }
49
+
50
+ joint_desired[joint_index][dof->getIndexInJoint ()] = _ctrl[i];
51
+ }
52
+
53
+ for (int i = 0 ; i < _control_dof; ++i) {
54
+ auto dof = robot->dof (_controllable_dofs[i]);
55
+ size_t joint_index = dof->getJoint ()->getJointIndexInSkeleton ();
56
+ size_t dof_index_in_joint = dof->getIndexInJoint ();
57
+
58
+ Eigen::VectorXd val;
59
+ if (errors.find (joint_index) == errors.end ()) {
60
+ val = Eigen::VectorXd (dof->getJoint ()->getNumDofs ());
61
+
62
+ std::string joint_type = robot->dof (_controllable_dofs[i])->getJoint ()->getType ();
63
+ if (joint_type == dart::dynamics::RevoluteJoint::getStaticType ()) {
64
+ val[dof_index_in_joint] = _angle_dist (_ctrl[i], joint_vals[joint_index][dof_index_in_joint]);
65
+ }
66
+ else if (joint_type == dart::dynamics::BallJoint::getStaticType ()) {
67
+ Eigen::Matrix3d R_desired = dart::math::expMapRot (joint_desired[joint_index]);
68
+ Eigen::Matrix3d R_current = dart::math::expMapRot (joint_vals[joint_index]);
69
+ val = dart::math::logMap (R_desired * R_current.transpose ());
70
+ }
71
+ else if (joint_type == dart::dynamics::EulerJoint::getStaticType ()) {
72
+ // TO-DO: Check if this is 100% correct
73
+ for (size_t d = 0 ; d < dof->getJoint ()->getNumDofs (); d++)
74
+ val[d] = _angle_dist (joint_desired[joint_index][d], joint_vals[joint_index][d]);
75
+ }
76
+ else if (joint_type == dart::dynamics::FreeJoint::getStaticType ()) {
77
+ auto free_joint = static_cast <dart::dynamics::FreeJoint*>(dof->getJoint ());
78
+
79
+ Eigen::Isometry3d tf_desired = free_joint->convertToTransform (joint_desired[joint_index]);
80
+ Eigen::Isometry3d tf_current = free_joint->convertToTransform (joint_vals[joint_index]);
81
+
82
+ val.tail (3 ) = tf_desired.translation () - tf_current.translation ();
83
+ val.head (3 ) = dart::math::logMap (tf_desired.linear ().matrix () * tf_current.linear ().matrix ().transpose ());
84
+ }
85
+ else {
86
+ val[dof_index_in_joint] = _ctrl[i] - joint_vals[joint_index][dof_index_in_joint];
87
+ }
88
+
89
+ errors[joint_index] = val;
90
+ }
91
+ else
92
+ val = errors[joint_index];
93
+ error (i) = val[dof_index_in_joint];
94
+ }
95
+ }
96
+
29
97
// / Compute the simplest PD controller output:
30
98
// / P gain * (target position - current position) + D gain * (0 - current velocity)
31
- Eigen::VectorXd commands = _Kp.array () * (target_positions .array () - q. array () ) - _Kd.array () * dq.array ();
99
+ Eigen::VectorXd commands = _Kp.array () * error .array () - _Kd.array () * dq.array ();
32
100
33
101
return commands;
34
102
}
@@ -52,9 +120,23 @@ namespace robot_dart {
52
120
return std::make_pair (_Kp, _Kd);
53
121
}
54
122
123
+ bool PDControl::using_angular_errors () const { return _use_angular_errors; }
124
+
125
+ void PDControl::set_use_angular_errors (bool enable) { _use_angular_errors = enable; }
126
+
55
127
std::shared_ptr<RobotControl> PDControl::clone () const
56
128
{
57
129
return std::make_shared<PDControl>(*this );
58
130
}
131
+
132
+ double PDControl::_angle_dist (double target, double current)
133
+ {
134
+ double theta = target - current;
135
+ while (theta < -M_PI)
136
+ theta += 2 * M_PI;
137
+ while (theta > M_PI)
138
+ theta -= 2 * M_PI;
139
+ return theta;
140
+ }
59
141
} // namespace control
60
142
} // namespace robot_dart
0 commit comments