Skip to content

Commit e4bb573

Browse files
committed
fix(franka,controllers): fix osc vibration and trajectory jumping
This commit resolves two issues in the franka controllers: 1. OSC Vibration: The order of torque limiting operations in osc() and joint_controller() was reversed. Torques are now first clamped by TorqueSafetyGuardFn (with new per-joint limits) and then rate-limited. This improves stability. TorqueSafetyGuardFn was also enhanced to support per-joint min/max torque arrays. 2. Trajectory Jumping: The reset() methods in LinearPoseTrajInterpolator and LinearJointPositionTrajInterpolator were refactored. They now correctly use the robot's current position as the start for new trajectories, eliminating abrupt jumps. Redundant internal state variables were removed.
1 parent 5828820 commit e4bb573

2 files changed

Lines changed: 27 additions & 56 deletions

File tree

extensions/rcs_fr3/src/hw/Franka.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,14 @@ void PInverse(const Eigen::MatrixXd &M, Eigen::MatrixXd &M_inv,
147147
M_inv = Eigen::MatrixXd(svd.matrixV() * S_inv * svd.matrixU().transpose());
148148
}
149149

150-
void TorqueSafetyGuardFn(std::array<double, 7> &tau_d_array, double min_torque,
151-
double max_torque) {
150+
void TorqueSafetyGuardFn(std::array<double, 7> &tau_d_array,
151+
const std::array<double, 7> &min_torques,
152+
const std::array<double, 7> &max_torques) {
152153
for (size_t i = 0; i < tau_d_array.size(); i++) {
153-
if (tau_d_array[i] < min_torque) {
154-
tau_d_array[i] = min_torque;
155-
} else if (tau_d_array[i] > max_torque) {
156-
tau_d_array[i] = max_torque;
154+
if (tau_d_array[i] < min_torques[i]) {
155+
tau_d_array[i] = min_torques[i];
156+
} else if (tau_d_array[i] > max_torques[i]) {
157+
tau_d_array[i] = max_torques[i];
157158
}
158159
}
159160
}
@@ -425,12 +426,6 @@ void Franka::osc() {
425426
if (dist2joint_min[i] < 0.25 && dist2joint_min[i] > 0.1)
426427
avoidance_force[i] += avoidance_weights_[i] * dist2joint_min[i];
427428
}
428-
tau_d << tau_d + Nullspace * avoidance_force;
429-
for (int i = 0; i < 7; i++) {
430-
if (dist2joint_max[i] < 0.1 && tau_d[i] > 0.) tau_d[i] = 0.;
431-
if (dist2joint_min[i] < 0.1 && tau_d[i] < 0.) tau_d[i] = 0.;
432-
}
433-
434429
std::array<double, 7> tau_d_array{};
435430
Eigen::VectorXd::Map(&tau_d_array[0], 7) = tau_d;
436431

@@ -439,14 +434,16 @@ void Franka::osc() {
439434
std::chrono::high_resolution_clock::now();
440435
auto time = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
441436

437+
// clamp the torques to a safe range.
438+
std::array<double, 7> min_torques = {-10.0, -10.0, -10.0, -10.0,
439+
-5.0, -5.0, -5.0};
440+
std::array<double, 7> max_torques = {10.0, 10.0, 10.0, 10.0, 5.0, 5.0, 5.0};
441+
TorqueSafetyGuardFn(tau_d_array, min_torques, max_torques);
442+
443+
// limit the rate of change of the clamped torques.
442444
std::array<double, 7> tau_d_rate_limited = franka::limitRate(
443445
franka::kMaxTorqueRate, tau_d_array, robot_state.tau_J_d);
444446

445-
// deoxys/config/control_config.yml
446-
double min_torque = -5;
447-
double max_torque = 5;
448-
TorqueSafetyGuardFn(tau_d_rate_limited, min_torque, max_torque);
449-
450447
return tau_d_rate_limited;
451448
});
452449
}
@@ -533,14 +530,17 @@ void Franka::joint_controller() {
533530
std::chrono::high_resolution_clock::now();
534531
auto time = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
535532

533+
// deoxys/config/control_config.yml
534+
// First clamp the torques to a safe range.
535+
std::array<double, 7> min_torques = {-10.0, -10.0, -10.0, -10.0,
536+
-5.0, -5.0, -5.0};
537+
std::array<double, 7> max_torques = {10.0, 10.0, 10.0, 10.0, 5.0, 5.0, 5.0};
538+
TorqueSafetyGuardFn(tau_d_array, min_torques, max_torques);
539+
540+
// Then limit the rate of change of the clamped torques.
536541
std::array<double, 7> tau_d_rate_limited = franka::limitRate(
537542
franka::kMaxTorqueRate, tau_d_array, robot_state.tau_J_d);
538543

539-
// deoxys/config/control_config.yml
540-
double min_torque = -5;
541-
double max_torque = 5;
542-
TorqueSafetyGuardFn(tau_d_rate_limited, min_torque, max_torque);
543-
544544
return tau_d_rate_limited;
545545
});
546546
}

include/rcs/LinearPoseTrajInterpolator.h

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,24 @@ class LinearPoseTrajInterpolator {
1010
Eigen::Vector3d p_start_;
1111
Eigen::Vector3d p_goal_;
1212
Eigen::Vector3d last_p_t_;
13-
Eigen::Vector3d prev_p_goal_;
1413

1514
Eigen::Quaterniond q_start_;
1615
Eigen::Quaterniond q_goal_;
1716
Eigen::Quaterniond last_q_t_;
18-
Eigen::Quaterniond prev_q_goal_;
1917

2018
double dt_;
2119
double last_time_;
2220
double max_time_;
2321
double start_time_;
2422
bool start_;
25-
bool first_goal_;
2623

2724
public:
2825
inline LinearPoseTrajInterpolator()
2926
: dt_(0.),
3027
last_time_(0.),
3128
max_time_(1.),
3229
start_time_(0.),
33-
start_(false),
34-
first_goal_(true){};
30+
start_(false){};
3531

3632
inline ~LinearPoseTrajInterpolator(){};
3733

@@ -49,22 +45,8 @@ class LinearPoseTrajInterpolator {
4945

5046
start_ = false;
5147

52-
if (first_goal_) {
53-
p_start_ = p_start;
54-
q_start_ = q_start;
55-
56-
prev_p_goal_ = p_start;
57-
prev_q_goal_ = q_start;
58-
first_goal_ = false;
59-
} else {
60-
// If the goal is already set, use prev goal as the starting point of
61-
// interpolation.
62-
prev_p_goal_ = p_goal_;
63-
prev_q_goal_ = q_goal_;
64-
65-
p_start_ = prev_p_goal_;
66-
q_start_ = prev_q_goal_;
67-
}
48+
p_start_ = p_start;
49+
q_start_ = q_start;
6850

6951
p_goal_ = p_goal;
7052
q_goal_ = q_goal;
@@ -104,14 +86,12 @@ class LinearJointPositionTrajInterpolator {
10486
Vector7d q_goal_;
10587

10688
Vector7d last_q_t_;
107-
Vector7d prev_q_goal_;
10889

10990
double dt_;
11091
double last_time_;
11192
double max_time_;
11293
double start_time_;
11394
bool start_;
114-
bool first_goal_;
11595

11696
double interpolation_fraction_; // fraction of actual interpolation within an
11797
// interval
@@ -122,8 +102,7 @@ class LinearJointPositionTrajInterpolator {
122102
last_time_(0.),
123103
max_time_(1.),
124104
start_time_(0.),
125-
start_(false),
126-
first_goal_(true){};
105+
start_(false){};
127106

128107
inline ~LinearJointPositionTrajInterpolator(){};
129108

@@ -141,15 +120,7 @@ class LinearJointPositionTrajInterpolator {
141120

142121
start_ = false;
143122

144-
if (first_goal_) {
145-
q_start_ = q_start;
146-
prev_q_goal_ = q_start;
147-
first_goal_ = false;
148-
// std::cout << "First goal of the interpolation" << std::endl;
149-
} else {
150-
prev_q_goal_ = q_goal_;
151-
q_start_ = prev_q_goal_;
152-
}
123+
q_start_ = q_start;
153124
q_goal_ = q_goal;
154125
};
155126

0 commit comments

Comments
 (0)