source: trunk/extremum_seeking/esc_perturb/src/perturb_esc_nd.cpp @ 27

Last change on this file since 27 was 22, checked in by wcaarls, 12 years ago

Updated extremum_seeking to revision 1178

File size: 4.8 KB
Line 
1/*
2 * perturb_esc_nd.cpp
3 *
4 *  Created on: Aug 1, 2012
5 *      Author: Berk Calli
6 *      Organization: Delft Biorobotics Lab., Delft University of Technology
7 *      Contact info: b.calli@tudelft.nl, web: www.dbl.tudelft.nl
8 *
9 * Class for perturbation based extremum seeking control
10 *
11 * * References:
12 * - K. B. Ariyur and M. Krstic, "Real-Time Optimization by Extremum-Seeking Control", Wiley, 2003.
13 * - B. Calli, W. Caarls, P. Jonker, M. Wisse, "Comparison of Extremum Seeking Control Algorithms for Robotic Applications", IROS 2012.
14 *
15 */
16
17#include "esc_perturb/perturb_esc_nd.h"
18
19PerturbESCND::PerturbESCND(){
20        sin_amp_ = 0;
21        sin_freq_ = 0;
22        corr_gain_ = 0;
23        high_pass_pole_ = 0;
24        low_pass_pole_ = 0;
25        comp_pole_ = 0;
26        comp_zero_ = 0;
27        period_ = 0;
28        state_initialized_ = false;
29        initialized_ = false;
30        old_vals_initialized_ = false;
31}
32PerturbESCND::PerturbESCND(double sin_amp, double sin_freq, double corr_gain, double high_pass_pole, double low_pass_pole, double comp_zero, double comp_pole, double period){
33        init(sin_amp, sin_freq, corr_gain, high_pass_pole, low_pass_pole, comp_zero, comp_pole, period);
34}
35void PerturbESCND::init(double sin_amp, double sin_freq, double corr_gain, double high_pass_pole, double low_pass_pole, double comp_zero, double comp_pole, double period){
36        sin_amp_ = sin_amp;
37        sin_freq_ = sin_freq;
38        corr_gain_ = corr_gain;
39        high_pass_pole_ = high_pass_pole;
40        low_pass_pole_ = low_pass_pole;
41        comp_pole_ = comp_pole;
42        comp_zero_ = comp_zero;
43        period_ = period;
44        obj_val_old_ = 0;
45        cycle_count_ = 0;
46        hpf_out_old_ = 0;
47        opt_dim_ = 0;
48        state_initialized_ = false;
49        old_vals_initialized_ = false;
50        initialized_ = true;
51}
52
53std::vector<double>  PerturbESCND::step(std::vector<double> state, double obj_val){
54
55        if(!initialized_){
56                fprintf(stderr,"The perturbation based ESC (1D) is not initialized... It will not be executed. \n");
57                return std::vector<double>();
58        }
59
60        if(!state_initialized_ && state.empty()){
61                fprintf(stderr,"The state value of the perturbation based ESC (1D) cannot be initialized: State vector is empty. The algorithm will not be executed. \n");
62                return std::vector<double>();
63        }
64
65        else if(!state_initialized_){
66
67                opt_dim_ = (unsigned int)state.size();
68                lpf_out_old_.resize(opt_dim_);
69                signal_demodulated_old_.resize(opt_dim_);
70                comp_old_.resize(opt_dim_);
71                corr_signal_.resize(opt_dim_);
72                pos_ref_.resize(opt_dim_);
73                for (size_t i = 0; i<opt_dim_; i++){
74                        pos_ref_[i] = state[i];
75                        lpf_out_old_[i] = 0;
76                        signal_demodulated_old_[i] = 0;
77                        comp_old_[i] = 0;
78                        corr_signal_[i] = 0;
79                }
80
81                phase_shift_.resize(opt_dim_);
82                phase_shift_[0] = 0;
83                for (size_t i = 1; i<opt_dim_; i++){
84                        phase_shift_[i] = i*PI/((double)opt_dim_);
85                }
86                state_initialized_ = true;
87        }
88
89        double hpf_out = (-(period_*high_pass_pole_-2)*hpf_out_old_+2*obj_val-2*obj_val_old_)/(2+high_pass_pole_*period_);
90        hpf_out_old_ = hpf_out;
91        obj_val_old_ = obj_val;
92        std::vector<double> signal_demodulated(opt_dim_);
93        std::vector<double> lpf_out(opt_dim_);
94        std::vector<double> comp_out(opt_dim_);
95        std::vector<double> output;
96
97        for (size_t i = 0; i<opt_dim_; i++){
98                signal_demodulated[i]= hpf_out*sin_amp_*std::sin(cycle_count_*period_*sin_freq_ + phase_shift_[i]);
99                lpf_out[i] = ((2.0-low_pass_pole_*period_)*lpf_out_old_[i]+low_pass_pole_*period_*signal_demodulated[i]+low_pass_pole_*period_*signal_demodulated_old_[i])/(2.0+low_pass_pole_*period_);
100                comp_out[i]= ((2.0+period_*comp_zero_)*lpf_out[i]+(period_*comp_zero_-2.0)*lpf_out_old_[i]-(period_*comp_pole_-2.0)*comp_old_[i])/(2.0+period_*comp_pole_);
101                corr_signal_[i] = corr_signal_[i]+corr_gain_*comp_out[i]*period_;
102                if(!old_vals_initialized_)
103                        pos_ref_[i] = sin_amp_*std::sin(cycle_count_*period_*sin_freq_ + phase_shift_[i]);      //modulation
104                else
105                        pos_ref_[i] = corr_signal_[i]+sin_amp_*std::sin(cycle_count_*period_*sin_freq_ + phase_shift_[i]);      //modulation
106                output.push_back(pos_ref_[i]);
107                signal_demodulated_old_[i] = signal_demodulated[i];
108                lpf_out_old_[i] = lpf_out[i];
109                comp_old_[i] = comp_out[i];
110        }
111        old_vals_initialized_ = true;
112        cycle_count_++;
113
114        return output;
115}
116
117ESC::inputType PerturbESCND::getInputType(){
118        return ESC::inputStateValue;
119}
120
121ESC::outputType PerturbESCND::getOutputType(){
122        return ESC::outputPosition;
123}
124
125std::vector<double> PerturbESCND::monitor(){
126        std::vector<double> monitor_values;
127
128        for(size_t i = 0; i<opt_dim_; i++)
129                monitor_values.push_back(corr_signal_[i]);
130
131        return monitor_values;
132}
133std::vector<std::string> PerturbESCND::monitorNames(){
134        std::vector<std::string> monitor_names;
135        std::string base = "correction signal ";
136        char numstr[21];
137        for(size_t i = 0; i<opt_dim_; i++){
138                sprintf(numstr, "%zd", i+1);
139                monitor_names.push_back(base + numstr);
140        }
141
142        return monitor_names;
143}
144
145void PerturbESCND::reset(){
146        obj_val_old_ = 0;
147        cycle_count_ = 0;
148        hpf_out_old_ = 0;
149        opt_dim_ = 0;
150        state_initialized_ = false;
151        old_vals_initialized_ = false;
152}
Note: See TracBrowser for help on using the repository browser.