Skip to content

Commit 050f0df

Browse files
Update filter parameters for paper
1 parent dde9313 commit 050f0df

File tree

8 files changed

+396
-75
lines changed

8 files changed

+396
-75
lines changed

libraries/robotutils/include/robotutils/GenericStateDerivative.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,27 @@ struct LowPassDerivativeFilter{
1616
Eigen::Matrix<double,state_size,3> deriv_filtered_state;
1717
bool is_first = true;
1818

19-
std::tuple<Eigen::Matrix<double,state_size,1>,Eigen::Matrix<double,state_size,1>> update(Eigen::Matrix<double,state_size,1> in_raw_state, double sample_time){
20-
return update(in_raw_state,Eigen::Matrix<double,state_size,1>::Zero(),sample_time);
21-
}
22-
23-
std::tuple<Eigen::Matrix<double,state_size,1>,Eigen::Matrix<double,state_size,1>> update(Eigen::Matrix<double,state_size,1> in_raw_state, Eigen::Matrix<double,state_size,1> partial_removal, double sample_time){
19+
std::tuple<Eigen::Matrix<double,state_size,1>,Eigen::Matrix<double,state_size,1>> update(Eigen::Matrix<double,state_size,1> in_raw_state, Eigen::Matrix<double,state_size,1> deriv_in_raw_state, double sample_time){
2420
if(is_first){
2521
is_first = false;
2622
raw_state.col(2) = in_raw_state;
2723
raw_state.col(1) = raw_state.col(2);
2824
raw_state.col(0) = raw_state.col(2);
25+
26+
deriv_raw_state.col(2) = deriv_in_raw_state;
27+
deriv_raw_state.col(1) = deriv_raw_state.col(2);
28+
deriv_raw_state.col(0) = deriv_raw_state.col(2);
29+
2930
} else {
3031
raw_state.col(2) = in_raw_state;
32+
deriv_raw_state.col(2) = deriv_in_raw_state;
3133
}
3234
filtered_state.col(2) = 0.222955 * raw_state.col(2)+
3335
0.445910 * raw_state.col(1)+
3436
0.222955 * raw_state.col(0)+
3537
0.295200 * filtered_state.col(1)+
3638
-0.187020 * filtered_state.col(0);
3739

38-
deriv_raw_state.col(2) = (1.0/sample_time)*(raw_state.col(2)-raw_state.col(1))-partial_removal;
3940
deriv_filtered_state.col(2) = 0.222955 * deriv_raw_state.col(2)+
4041
0.445910 * deriv_raw_state.col(1)+
4142
0.222955 * deriv_raw_state.col(0)+

libraries/robotutils/include/robotutils/RippleFilter.h

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,53 @@
33

44
#include <tuple>
55
#include <array>
6+
#include <Eigen/Dense>
67

78
namespace curan {
89
namespace robotic {
910
namespace ripple{
11+
12+
struct Damper{
13+
double damper_derivative = 0.0;
14+
double value = 0.0;
15+
double prev_vel = 0.0;
16+
double delta = 0.0;
17+
18+
template<size_t siz>
19+
void compute(const Eigen::Matrix<double,siz,1>& dq,double sample_time){
20+
const double trigger_point = 0.1;
21+
double max_vel = dq.array().abs().maxCoeff();
22+
double possible_damper_value = std::pow(max_vel/trigger_point,2.0);
23+
if(possible_damper_value < 1.0){
24+
value = possible_damper_value;
25+
damper_derivative = (2.0*max_vel)/(trigger_point*trigger_point)*((max_vel-prev_vel)/sample_time);
26+
} else {
27+
value = 1.0;
28+
damper_derivative = 0.0;
29+
}
30+
prev_vel = max_vel;
31+
delta = std::abs(max_vel*sample_time);
32+
};
33+
34+
};
35+
1036
struct Properties{
11-
double damper_prev;
12-
double damper;
1337
double width;
1438
double frequency;
15-
double delta;
16-
17-
Properties(double in_width = 5.0, double in_frequency = 320.0) : damper_prev{0.0},damper{0.0}, width{in_width}, frequency{in_frequency}, delta{0.0} {};
18-
39+
Properties(double in_width = 5.0, double in_frequency = 320.0) : width{in_width}, frequency{in_frequency}{};
1940
};
2041

2142
struct Data{
2243
std::array<double,3> y_f = {0.0,0.0,0.0};
2344
std::array<double,3> y = {0.0,0.0,0.0};
45+
46+
std::array<double,3> dy_f = {0.0,0.0,0.0};
47+
std::array<double,3> dy = {0.0,0.0,0.0};
2448
};
2549

26-
struct Observation{
27-
double current_vel;
28-
double current_delta;
29-
};
30-
31-
void update_filter_properties(Properties& properties,const Observation& observation);
32-
33-
void shift_filter_data(Data& data, const double& filtered_torque);
50+
void shift_filter_data(Data& data);
3451

35-
void update_filter_data(Data& data, const double& torque);
52+
void update_filter_data(Data& data, const double& torque, const double& dtorque);
3653

3754
/*
3855
this function returns a tuple with the following rules:
@@ -41,7 +58,7 @@ namespace ripple{
4158
basically the derivative of the filtered torque has two components, the derivative due to the changes in the real torque
4259
and the changes due to the scalling function that shuts down the filter
4360
*/
44-
std::tuple<double,double> execute(const Properties& props, Data& data);
61+
std::tuple<double,double> execute(const Properties& props,const Damper& damper, Data& data);
4562

4663
}
4764
}

libraries/robotutils/include/robotutils/ViewFiltering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct ViewFiltering : public UserData{
1717
std::array<ripple::Properties, number_of_joints> second_harmonic;
1818
std::array<ripple::Properties, number_of_joints> third_harmonic;
1919

20+
curan::robotic::ripple::Damper damper;
21+
2022
LowPassDerivativeFilter<number_of_joints> filtering_mechanism;
2123
Eigen::Matrix<double,number_of_joints,1> previous_q;
2224

libraries/robotutils/src/LBRController.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void RobotLBR::command(){
7979
eigen_state = current_state.converteigen();
8080
Eigen::MatrixXd task_jacobian = Eigen::MatrixXd::Identity(number_of_joints,number_of_joints);
8181
eigen_state = std::move(user_data->update(robot_model,std::move(eigen_state),task_jacobian));
82-
eigen_state.cmd_tau = add_constraints<number_of_joints>(robot_model,eigen_state.cmd_tau, 0.005);
82+
//eigen_state.cmd_tau = add_constraints<number_of_joints>(robot_model,eigen_state.cmd_tau, 0.005);
8383
current_state.convertFrom(eigen_state);
8484
atomic_state.store(current_state,std::memory_order_relaxed);
8585
if (robotState().getClientCommandMode() == KUKA::FRI::TORQUE) {

libraries/robotutils/src/RippleFilter.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,35 @@ namespace curan{
66
namespace robotic{
77
namespace ripple{
88

9-
void update_filter_properties(Properties& properties,const Observation& observation){
10-
double damper_trigger = 0.2*properties.frequency;
11-
double filtered_frequency = std::abs(observation.current_vel)*properties.frequency;
12-
properties.damper_prev = properties.damper;
13-
properties.damper = filtered_frequency < damper_trigger ? std::pow(filtered_frequency/damper_trigger,2) : 1.0;
14-
properties.delta = std::abs(observation.current_delta);
15-
}
16-
17-
void shift_filter_data(Data& data, const double& filtered_torque){
9+
void shift_filter_data(Data& data){
1810
data.y[0] = data.y[1];
1911
data.y[1] = data.y[2];
2012

13+
data.dy[0] = data.dy[1];
14+
data.dy[1] = data.dy[2];
15+
2116
data.y_f[0] = data.y_f[1];
2217
data.y_f[1] = data.y_f[2];
23-
data.y_f[2] = filtered_torque;
18+
data.y_f[2] = 0.0;
19+
20+
data.dy_f[0] = data.dy_f[1];
21+
data.dy_f[1] = data.dy_f[2];
22+
data.dy_f[2] = 0.0;
2423
}
2524

26-
void update_filter_data(Data& data, const double& torque){
25+
void update_filter_data(Data& data, const double& torque, const double& dtorque){
2726
data.y[2] = torque;
27+
data.dy[2] = dtorque;
2828
}
2929

30-
std::tuple<double,double> execute(const Properties& props, Data& data, double sample_time){
31-
const double A = 2.0 * props.width * props.frequency * props.delta;
32-
const double B = 4.0 + props.frequency * props.frequency * props.delta * props.delta;
33-
const double damper_derivative = (props.damper-props.damper_prev)/sample_time;
30+
std::tuple<double,double> execute(const Properties& props,const Damper& damper, Data& data){
31+
const double A = 2.0 * props.width * props.frequency * damper.delta;
32+
const double B = 4.0 + props.frequency * props.frequency * damper.delta * damper.delta;
3433
double y_f2 = (1.0/(A+B)) * (A*data.y[2] - A*data.y[0] - 2.0*(B-8.0) * data.y_f[1] - (B-A)*data.y_f[0] );
35-
data.y_f[2] = props.damper*y_f2;
36-
return {data.y_f[2],damper_derivative*y_f2};
34+
double dy_f2 = (1.0/(A+B)) * (A*data.dy[2] - A*data.dy[0] - 2.0*(B-8.0) * data.dy_f[1] - (B-A)*data.dy_f[0] );
35+
data.y_f[2] = damper.value*y_f2;
36+
data.dy_f[2] = damper.value*dy_f2;
37+
return std::make_tuple(data.y_f[2],data.dy_f[2]);
3738
}
3839

3940
}

libraries/robotutils/src/ViewFiltering.cpp

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,56 +15,56 @@ namespace robotic {
1515
EigenState&& ViewFiltering::update(const RobotModel<number_of_joints>& iiwa, EigenState&& state, Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& composed_task_jacobians){
1616
using vector_type = curan::robotic::RobotModel<curan::robotic::number_of_joints>::vector_type;
1717
static double currentTime = 0.0;
18-
/*
19-
We remove some energy from the system whilst moving the robot in free space. Thus we guarantee that the system is passive
20-
*/
21-
22-
state.cmd_tau = -iiwa.mass() * iiwa.velocities();
18+
19+
//We remove some energy from the system whilst moving the robot in free space. Thus we guarantee that the system is passive
20+
21+
//state.cmd_tau = -iiwa.mass() * iiwa.velocities();
22+
state.cmd_tau = vector_type::Zero();
2323
vector_type raw_filtered_torque = vector_type::Zero();
24-
vector_type partial_derivative_torque = vector_type::Zero();
24+
vector_type raw_deriv_filtered_torque = vector_type::Zero();
25+
2526
if(filtering_mechanism.is_first)
2627
previous_q = iiwa.joints();
27-
28-
double fastest_velocity_found = std::numeric_limits<double>::min();
29-
size_t offset_fastest_filter = 0;
3028

31-
for (size_t joint_i = 0; joint_i < curan::robotic::number_of_joints; ++joint_i)
32-
{
33-
const curan::robotic::ripple::Observation obser_i_j{iiwa.velocities()[joint_i], iiwa.joints()[joint_i] - previous_q[joint_i]};
34-
ripple::update_filter_properties(first_harmonic[joint_i], obser_i_j);
35-
ripple::update_filter_properties(second_harmonic[joint_i], obser_i_j);
36-
ripple::update_filter_properties(third_harmonic[joint_i], obser_i_j);
37-
double vel_modulus_i = std::abs(iiwa.velocities()[joint_i]);
38-
if (fastest_velocity_found < vel_modulus_i)
39-
{
40-
fastest_velocity_found = vel_modulus_i;
41-
offset_fastest_filter = joint_i;
42-
}
43-
}
29+
static vector_type init_q = iiwa.joints();
30+
static vector_type prev_tau = iiwa.measured_torque();
31+
32+
damper.compute<curan::robotic::number_of_joints>(iiwa.velocities(),iiwa.sample_time());
4433
previous_q = iiwa.joints();
4534

4635
for (size_t j = 0; j < curan::robotic::number_of_joints; ++j)
4736
{
48-
double filtered_torque_value = iiwa.measured_state()->tau[j];
49-
ripple::shift_filter_data(joint_data_first_harmonic[j], 0.0);
50-
ripple::update_filter_data(joint_data_first_harmonic[j], filtered_torque_value);
51-
auto [filtered_harm_1,partial_derivative_1] = ripple::execute(first_harmonic[offset_fastest_filter], joint_data_first_harmonic[j]);
37+
double filtered_torque_value = iiwa.measured_torque()[j];
38+
double deriv_filtered_torque_value = (iiwa.measured_torque()[j]-prev_tau[j])/(iiwa.sample_time());
39+
curan::robotic::ripple::shift_filter_data(joint_data_first_harmonic[j]);
40+
curan::robotic::ripple::update_filter_data(joint_data_first_harmonic[j], filtered_torque_value,deriv_filtered_torque_value);
41+
auto [filtered_harm_1,partial_derivative_1] = curan::robotic::ripple::execute(first_harmonic[j],damper, joint_data_first_harmonic[j]);
5242
filtered_torque_value -= filtered_harm_1;
53-
ripple::shift_filter_data(joint_data_second_harmonic[j], 0.0);
54-
ripple::update_filter_data(joint_data_second_harmonic[j], filtered_torque_value);
55-
auto [filtered_harm_2,partial_derivative_2]= ripple::execute(second_harmonic[offset_fastest_filter], joint_data_second_harmonic[j]);
43+
deriv_filtered_torque_value -= partial_derivative_1;
44+
curan::robotic::ripple::shift_filter_data(joint_data_second_harmonic[j]);
45+
curan::robotic::ripple::update_filter_data(joint_data_second_harmonic[j], filtered_torque_value,deriv_filtered_torque_value);
46+
auto [filtered_harm_2,partial_derivative_2]= curan::robotic::ripple::execute(second_harmonic[j],damper, joint_data_second_harmonic[j]);
5647
filtered_torque_value -= filtered_harm_2;
57-
ripple::shift_filter_data(joint_data_third_harmonic[j], 0.0);
58-
ripple::update_filter_data(joint_data_third_harmonic[j], filtered_torque_value);
59-
auto [ filtered_harm_3,partial_derivative_3] = ripple::execute(third_harmonic[offset_fastest_filter], joint_data_third_harmonic[j]);
60-
partial_derivative_torque[j] = partial_derivative_1 + partial_derivative_2 +partial_derivative_3;
48+
deriv_filtered_torque_value -= partial_derivative_2;
49+
curan::robotic::ripple::shift_filter_data(joint_data_third_harmonic[j]);
50+
curan::robotic::ripple::update_filter_data(joint_data_third_harmonic[j], filtered_torque_value,deriv_filtered_torque_value);
51+
auto [ filtered_harm_3,partial_derivative_3] = curan::robotic::ripple::execute(third_harmonic[j],damper, joint_data_third_harmonic[j]);
6152
filtered_torque_value -= filtered_harm_3;
53+
deriv_filtered_torque_value -= partial_derivative_3;
6254
raw_filtered_torque[j] = -filtered_torque_value - iiwa.gravity()[j] - iiwa.coriolis()[j];
55+
raw_deriv_filtered_torque[j] = -deriv_filtered_torque_value;
6356
}
6457

65-
const auto& [filtered_torque, filtered_torque_derivative] = filtering_mechanism.update(raw_filtered_torque,partial_derivative_torque,iiwa.sample_time());
66-
state.cmd_q = iiwa.joints() + Eigen::Matrix<double,number_of_joints,1>::Constant(0.5 / 180.0 * M_PI * sin(2 * M_PI * 10 * currentTime));
58+
prev_tau = iiwa.measured_torque();
6759

60+
//const auto& [filtered_torque, filtered_torque_derivative] = filtering_mechanism.update(raw_filtered_torque,partial_derivative_torque,iiwa.sample_time());
61+
const auto& [filtered_torque, filtered_torque_derivative] = filtering_mechanism.update(raw_filtered_torque,raw_deriv_filtered_torque,iiwa.sample_time());
62+
//state.cmd_q = iiwa.joints() + Eigen::Matrix<double,curan::robotic::number_of_joints,1>::Constant(0.5 / 180.0 * M_PI * sin(2 * M_PI * 10 * currentTime));
63+
state.cmd_q = init_q;
64+
state.cmd_q[0] = iiwa.joints()[0]+ (0.5 / 180.0 * M_PI * sin(2 * M_PI * 10 * currentTime));
65+
state.user_defined = raw_filtered_torque;
66+
state.user_defined2 = filtered_torque_derivative;
67+
state.user_defined4 = (iiwa.measured_torque()-prev_tau)/iiwa.sample_time();
6868
currentTime += iiwa.sample_time();
6969
return std::move(state);
7070
}

tests/robotcontrollers/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,16 @@ communication
207207
renderable
208208
)
209209

210+
add_executable(test_robot_controller test_robot_controller.cpp)
211+
212+
target_compile_definitions(test_robot_controller PRIVATE SK_VULKAN)
213+
target_compile_definitions(test_robot_controller PRIVATE CURAN_COPIED_RESOURCE_PATH="${post_build_resource_path}")
214+
215+
target_link_libraries(test_robot_controller PUBLIC
216+
utils
217+
robotutils
218+
communication
219+
renderable
220+
)
221+
210222

0 commit comments

Comments
 (0)