00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <robot/control/ManipulatorPIDPositionController>
00026
00027 using robot::control::ManipulatorPIDPositionController;
00028 using robot::ControlInterface;
00029
00030 ManipulatorPIDPositionController::ManipulatorPIDPositionController(const robot::KinematicChain& chain)
00031 : chain(chain), Kp(10), Ki(0.1), Kd(0)
00032 {
00033
00034 positionInterface = ref<PositionInterface>(NewObj PositionInterface(ref<ManipulatorPIDPositionController>(this)));
00035 }
00036
00037
00038
00039 void ManipulatorPIDPositionController::setControlInterface(ref<ControlInterface> controlInterface)
00040 {
00041 if (controlInterface->getType()=="JointVelocityControl") {
00042 manipInterface = controlInterface;
00043 Int inputSize = manipInterface->inputSize();
00044 lastInputSize = inputSize;
00045 if (inputSize > 0) {
00046 R.reset(zeroVector(inputSize));
00047 pe.reset(zeroVector(inputSize));
00048 s.reset(zeroVector(inputSize));
00049 }
00050 }
00051 else {
00052 Logln("Ignoring useless ControlInterface name:" << controlInterface->getName() << " type:" << controlInterface->getType());
00053 }
00054 }
00055
00056 bool ManipulatorPIDPositionController::isConnected() const
00057 {
00058 return (manipInterface!=0);
00059 }
00060
00061 bool ManipulatorPIDPositionController::iterate(const base::Time& time)
00062 {
00063 if (!isConnected()) return false;
00064
00065 Int inputSize = manipInterface->inputSize();
00066 if (inputSize != lastInputSize) {
00067 pe.reset(zeroVector(inputSize));
00068 s.reset(zeroVector(inputSize));
00069 lastInputSize = inputSize;
00070 }
00071
00072 Int outputSize = manipInterface->outputSize();
00073 if (outputSize != lastOutputSize) {
00074 R.reset(zeroVector(inputSize));
00075 lastOutputSize = outputSize;
00076 }
00077
00078
00079 for(Int i=0; i<inputSize; i++) {
00080
00081
00082 Real Y = manipInterface->getInput(i);
00083 Real e;
00084
00085
00086 bool angWrap = false;
00087 if (chain.linkOfVariable(i).type() == KinematicChain::Link::Revolute)
00088 if (chain.variableMaxLimit(i) > consts::Pi)
00089 if (chain.variableMinLimit(i) < consts::Pi)
00090 angWrap=true;
00091 if (!angWrap)
00092 e = R[i]-Y;
00093 else
00094 e = Math::angleDifference(R[i],Y);
00095
00096 s[i] += e;
00097 Real u = Kp*e + Ki*s[i] + Kd*(e - pe[i]);
00098 manipInterface->setOutput(i, u);
00099
00100 if (i==inputSize-1) {
00101
00102 }
00103 pe[i] = e;
00104 }
00105
00106 return false;
00107 }
00108
00109
00110 base::ref<ControlInterface> ManipulatorPIDPositionController::getControlInterface(String interfaceName) throw(std::invalid_argument)
00111 {
00112 if (!manipInterface)
00113 throw std::invalid_argument(Exception(String("unknown interface ")+interfaceName+" (not connected)"));
00114
00115 if (interfaceName=="") interfaceName = positionInterface->getName();
00116
00117 if (interfaceName == positionInterface->getName())
00118 return positionInterface;
00119
00120 throw std::invalid_argument(Exception(String("unknown interface name:")+interfaceName));
00121 }
00122
00123
00124
00125
00126 Int ManipulatorPIDPositionController::PositionInterface::inputSize() const
00127 {
00128 return c->manipInterface->inputSize();
00129 }
00130
00131
00132
00133 base::String ManipulatorPIDPositionController::PositionInterface::inputName(Int i) const
00134 {
00135 return c->manipInterface->inputName(i);
00136 }
00137
00138
00139 Real ManipulatorPIDPositionController::PositionInterface::getInput(Int i) const
00140 {
00141 return c->manipInterface->getInput(i);
00142 }
00143
00144
00145 const base::Vector& ManipulatorPIDPositionController::PositionInterface::getInputs() const
00146 {
00147 return c->manipInterface->getInputs();
00148 }
00149
00150
00151 Int ManipulatorPIDPositionController::PositionInterface::outputSize() const
00152 {
00153 return c->manipInterface->outputSize();
00154 }
00155
00156
00157
00158 base::String ManipulatorPIDPositionController::PositionInterface::outputName(Int i) const
00159 {
00160 return c->manipInterface->outputName(i);
00161 }
00162
00163
00164 void ManipulatorPIDPositionController::PositionInterface::setOutput(Int i, Real value)
00165 {
00166 Int outputSize = c->manipInterface->outputSize();
00167 if (i >= outputSize)
00168 throw std::out_of_range(Exception("index out of range"));
00169
00170 if (c->lastOutputSize != outputSize) {
00171 c->R.reset(zeroVector(outputSize));
00172 c->lastOutputSize = outputSize;
00173 }
00174
00175 c->R[i] = value;
00176 }
00177
00178
00179 void ManipulatorPIDPositionController::PositionInterface::setOutputs(const Vector& values)
00180 {
00181 Int outputSize = c->manipInterface->outputSize();
00182 if (values.size() != outputSize)
00183 throw std::invalid_argument(Exception("values Vector has wrong dimension"));
00184
00185 if (c->lastOutputSize != outputSize) {
00186 c->R.reset(zeroVector(outputSize));
00187 c->lastOutputSize = outputSize;
00188 }
00189
00190 c->R = values;
00191 }
00192
00193