00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "nAxesGeneratorPos.hpp"
00022 #include <ocl/ComponentLoader.hpp>
00023 #include <assert.h>
00024
00025 namespace OCL
00026 {
00027 using namespace RTT;
00028 using namespace KDL;
00029 using namespace std;
00030 typedef nAxesGeneratorPos MyType;
00031
00032 nAxesGeneratorPos::nAxesGeneratorPos(string name)
00033 : TaskContext(name,PreOperational),
00034 moveTo_cmd( "moveTo",&MyType::moveTo,&MyType::moveFinished, this),
00035 reset_position_mtd( "resetPosition", &MyType::resetPosition, this),
00036 p_m_port("nAxesSensorPosition"),
00037 p_d_port("nAxesDesiredPosition"),
00038 v_d_port("nAxesDesiredVelocity"),
00039 v_max_prop("max_vel", "Maximum Velocity in Trajectory"),
00040 a_max_prop("max_acc", "Maximum Acceleration in Trajectory"),
00041 num_axes_prop("num_axes","Number of Axes")
00042 {
00043
00044
00045
00046 this->properties()->addProperty(&num_axes_prop);
00047 this->properties()->addProperty(&v_max_prop);
00048 this->properties()->addProperty(&a_max_prop);
00049
00050
00051 this->ports()->addPort(&p_m_port);
00052 this->ports()->addPort(&p_d_port);
00053 this->ports()->addPort(&v_d_port);
00054
00055
00056 this->commands()->addCommand( &moveTo_cmd,"Set the position setpoint",
00057 "setpoint", "joint setpoint for all axes",
00058 "time", "minimum time to complete trajectory" );
00059
00060
00061 this->methods()->addMethod( &reset_position_mtd, "Reset generator position" );
00062
00063 }
00064
00065 nAxesGeneratorPos::~nAxesGeneratorPos()
00066 {}
00067
00068 bool nAxesGeneratorPos::configureHook()
00069 {
00070 num_axes=num_axes_prop.rvalue();
00071 if(v_max_prop.value().size()!=num_axes){
00072 Logger::In in(this->getName().data());
00073 log(Error)<<"Size of "<<v_max_prop.getName()
00074 <<" does not match "<<num_axes_prop.getName()
00075 <<endlog();
00076 return false;
00077 }
00078
00079 if(a_max_prop.value().size()!=num_axes){
00080 Logger::In in(this->getName().data());
00081 log(Error)<<"Size of "<<a_max_prop.getName()
00082 <<" does not match "<<num_axes_prop.getName()
00083 <<endlog();
00084 return false;
00085 }
00086
00087 v_max=v_max_prop.rvalue();
00088 a_max=a_max_prop.rvalue();
00089
00090
00091 p_m.resize(num_axes);
00092 p_d.resize(num_axes);
00093 v_d.resize(num_axes);
00094 motion_profile.resize(num_axes);
00095
00096
00097 for(unsigned int i=0;i<num_axes;i++)
00098 motion_profile[i].SetMax(v_max[i],a_max[i]);
00099
00100
00101 p_d.assign(num_axes,0);
00102 p_d_port.Set(p_d);
00103 v_d.assign(num_axes,0);
00104 v_d_port.Set(v_d);
00105 return true;
00106 }
00107
00108
00109 bool nAxesGeneratorPos::startHook()
00110 {
00111
00112 if(!p_m_port.ready()){
00113 Logger::In in(this->getName().data());
00114 log(Error)<<p_m_port.getName()<<" not ready"<<endlog();
00115 return false;
00116 }
00117 if(p_m_port.Get().size()!=num_axes){
00118 Logger::In in(this->getName().data());
00119 log(Error)<<"Size of "<<p_m_port.getName()<<": "<<p_m_port.Get().size()<<" != " << num_axes<<endlog();
00120 return false;
00121 }
00122 p_d = p_m_port.Get();
00123 p_d_port.Set(p_d);
00124 is_moving = false;
00125
00126 return true;
00127 }
00128
00129 void nAxesGeneratorPos::updateHook()
00130 {
00131 if (is_moving){
00132 time_passed = TimeService::Instance()->secondsSince(time_begin);
00133 if ( time_passed > max_duration ){
00134
00135 for (unsigned int i=0; i<num_axes; i++){
00136 p_d[i] = motion_profile[i].Pos( max_duration );
00137 v_d[i] = 0;
00138 is_moving = false;
00139 }
00140 }else{
00141 for(unsigned int i=0; i<num_axes; i++){
00142 p_d[i] = motion_profile[i].Pos( time_passed );
00143 v_d[i] = motion_profile[i].Vel( time_passed );
00144 }
00145 }
00146 p_d_port.Set(p_d);
00147 v_d_port.Set(v_d);
00148 }
00149 }
00150
00151
00152 void nAxesGeneratorPos::stopHook()
00153 {
00154 }
00155
00156 bool nAxesGeneratorPos::moveTo(const vector<double>& position, double time)
00157 {
00158 if(position.size()!=num_axes){
00159 Logger::In in((this->getName()+moveTo_cmd.getName()).data());
00160 log(Error)<<"Size of position != "<<num_axes<<endlog();
00161 return false;
00162 }
00163
00164
00165 if (!is_moving){
00166 max_duration = 0;
00167
00168 p_m = p_m_port.Get();
00169 for (unsigned int i=0; i<num_axes; i++){
00170
00171 motion_profile[i].SetProfileDuration( p_m[i], position[i], time );
00172
00173 max_duration = max( max_duration, motion_profile[i].Duration() );
00174 }
00175
00176 for(unsigned int i = 0; i < num_axes; i++)
00177 motion_profile[i].SetProfileDuration( p_m[i], position[i], max_duration );
00178
00179 time_begin = TimeService::Instance()->getTicks();
00180 time_passed = 0;
00181
00182 is_moving = true;
00183 return true;
00184 }
00185
00186 else{
00187 Logger::In in((this->getName()+moveTo_cmd.getName()).data());
00188 log(Error)<<"Still moving, not executing new command."<<endlog();
00189 return false;
00190 }
00191
00192 }
00193
00194 bool nAxesGeneratorPos::moveFinished() const
00195 {
00196 return (!is_moving);
00197 }
00198
00199 void nAxesGeneratorPos::resetPosition()
00200 {
00201 p_d = p_m_port.Get();
00202 for(unsigned int i = 0; i < num_axes; i++)
00203 v_d[i] = 0;
00204 p_d_port.Set(p_d);
00205 v_d_port.Set(v_d);
00206 is_moving = false;
00207 }
00208 }
00209
00210 ORO_LIST_COMPONENT_TYPE( OCL::nAxesGeneratorPos )
00211
00212
00213
00214