00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "nAxesControllerPosVelAcc.hpp"
00019 #include <ocl/ComponentLoader.hpp>
00020 #include <assert.h>
00021
00022 ORO_LIST_COMPONENT_TYPE( OCL::nAxesControllerPosVelAcc )
00023
00024 namespace OCL{
00025
00026 using namespace RTT;
00027 using namespace std;
00028
00029 nAxesControllerPosVelAcc::nAxesControllerPosVelAcc(string name)
00030 : TaskContext(name,PreOperational),
00031 reset_all_mtd( "resetAll", &nAxesControllerPosVelAcc::resetAll, this),
00032 resetAxis_mtd( "resetAxis", &nAxesControllerPosVelAcc::resetAxis, this),
00033 p_m_port("nAxesSensorPosition"),
00034 v_m_port("nAxesSensorVelocity"),
00035 p_d_port("nAxesDesiredPosition"),
00036 v_d_port("nAxesDesiredVelocity"),
00037 a_d_port("nAxesDesiredAcceleration"),
00038 a_out_port("nAxesOutputAcceleration"),
00039 Kp_prop("Kp", "Position Feedback Gain"),
00040
00041 num_axes_prop("num_axes","Number of Axes"),
00042 use_ad("use_ad","False if no desired acceleration available"),
00043 use_vd("use_vd","False if no desired acceleration available"),
00044 use_pd("use_pd","False if no desired acceleration available"),
00045 avoid_drift("avoid_drift","True if acceleration or velocity should be integrated to avoid drifting"),
00046 differentiate("differentiate","True if acceleration or velocity should be calculated by differentiation")
00047 {
00048
00049
00050
00051 this->ports()->addPort(&p_m_port);
00052 this->ports()->addPort(&v_m_port);
00053 this->ports()->addPort(&p_d_port);
00054 this->ports()->addPort(&v_d_port);
00055 this->ports()->addPort(&a_d_port);
00056 this->ports()->addPort(&a_out_port);
00057
00058
00059 this->properties()->addProperty(&num_axes_prop);
00060 this->properties()->addProperty(&Kp_prop);
00061
00062 this->properties()->addProperty(&use_ad);
00063 this->properties()->addProperty(&use_vd);
00064 this->properties()->addProperty(&use_pd);
00065 this->properties()->addProperty(&avoid_drift);
00066 this->properties()->addProperty(&differentiate);
00067
00068
00069 this->methods()->addMethod( &reset_all_mtd,"reset all axes of the controller");
00070 this->methods()->addMethod( &resetAxis_mtd,"reset a single axis of the controller",
00071 "axis","axis to reset");
00072
00073 }
00074
00075
00076 nAxesControllerPosVelAcc::~nAxesControllerPosVelAcc(){};
00077
00078 bool nAxesControllerPosVelAcc::configureHook(){
00079 num_axes=num_axes_prop.rvalue();
00080
00081
00082
00083 if(Kp_prop.value().size()!=num_axes){
00084 Logger::In in(this->getName().data());
00085 log(Error)<<"Size of "<<Kp_prop.getName()
00086 <<" does not match "<<num_axes_prop.getName()
00087 <<endlog();
00088 return false;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 Kp.resize(num_axes);
00101 Kp=Kp_prop.rvalue();
00102 Kv.resize(num_axes);
00103
00104
00105 p_m.resize(num_axes);
00106 p_d.resize(num_axes);
00107 v_m.resize(num_axes);
00108 v_d.resize(num_axes);
00109 v_d_prev.resize(num_axes);
00110 a_d.resize(num_axes);
00111
00112 is_initialized.resize(num_axes);
00113 time_begin.resize(num_axes);
00114 time_difference.resize(num_axes);
00115
00116
00117 a_out.assign(num_axes,0);
00118 a_out_port.Set(a_out);
00119 return true;
00120
00121 }
00122
00123 bool nAxesControllerPosVelAcc::startHook()
00124 {
00125
00126
00127 if(!p_m_port.ready()){
00128 Logger::In in(this->getName().data());
00129 log(Error)<<p_m_port.getName()<<" not ready"<<endlog();
00130 return false;
00131 }
00132 if(!v_m_port.ready()){
00133 Logger::In in(this->getName().data());
00134 log(Error)<<v_m_port.getName()<<" not ready"<<endlog();
00135 return false;
00136 }
00137
00138
00139 for(unsigned int i=0; i<num_axes; i++)
00140 is_initialized[i] = false;
00141
00142
00143 if(Kp_prop.rvalue().size()!=num_axes)
00144 return false;
00145
00146 Kp=Kp_prop.rvalue();
00147 for(unsigned int i=0;i<num_axes;i++)
00148 Kv[i]=2*0.7*sqrt(Kp[i]);
00149
00150 return true;
00151 }
00152
00153 void nAxesControllerPosVelAcc::updateHook()
00154 {
00155
00156 p_m_port.Get(p_m);
00157 v_m_port.Get(v_m);
00158
00159
00160
00161 for (unsigned int i=0; i<num_axes; i++){
00162 if (!is_initialized[i]){
00163 is_initialized[i] = true;
00164 v_d[i] = v_m[i];
00165 p_d[i] = p_m[i];
00166 time_begin[i] = TimeService::Instance()->getTicks();
00167 }
00168 time_difference[i] = TimeService::Instance()->secondsSince(time_begin[i]);
00169 time_begin[i] = TimeService::Instance()->getTicks();
00170
00171 if(avoid_drift){
00172
00173
00174 if(!use_vd&&use_ad)
00175 v_d[i] += a_d[i] * time_difference[i];
00176 if(!use_pd)
00177 p_d[i] += v_d[i] * time_difference[i];
00178 }
00179 }
00180
00181 if(differentiate){
00182 if(!use_vd&&use_pd)
00183 p_d_prev = p_d;
00184 if(!use_ad)
00185 v_d_prev = v_d;
00186 }
00187
00188 if(use_ad)
00189 a_d_port.Get(a_d);
00190 if(use_vd)
00191 v_d_port.Get(v_d);
00192 if(use_pd)
00193 p_d_port.Get(p_d);
00194
00195 if(differentiate){
00196 for(unsigned int i=0;i<num_axes;i++){
00197 if(!use_vd&&use_pd)
00198 v_d[i] = (p_d[i]-p_d_prev[i])/time_difference[i];
00199 if(!use_ad)
00200 a_d[i] = (v_d[i]-v_d_prev[i])/time_difference[i];
00201 }
00202 }
00203
00204 if(!use_pd)
00205 p_d_port.Set(p_d);
00206 if(!use_vd)
00207 v_d_port.Set(v_d);
00208 if(!use_ad)
00209 a_d_port.Set(a_d);
00210
00211
00212
00213 for(unsigned int i=0; i<num_axes; i++){
00214 a_out[i] = a_d[i] + Kv[i]*(v_d[i]-v_m[i])
00215 + Kp[i]*(p_d[i]-p_m[i]);
00216 }
00217 a_out_port.Set(a_out);
00218 }
00219
00220 void nAxesControllerPosVelAcc::stopHook()
00221 {
00222 for(unsigned int i=0; i<num_axes; i++){
00223 a_out[i] = 0.0;
00224 }
00225 a_out_port.Set(a_out);
00226 }
00227
00228 void nAxesControllerPosVelAcc::resetAll()
00229 {
00230 for(unsigned int i=0; i<num_axes; i++)
00231 is_initialized[i] = false;
00232 }
00233
00234 void nAxesControllerPosVelAcc::resetAxis(int axis)
00235 {
00236 is_initialized[axis] = false;
00237 }
00238 }
00239