00001 #include "ArmMC.h"
00002 #include "Kinematics.h"
00003 #include "IKSolver.h"
00004 #include "Shared/debuget.h"
00005 #include "Shared/WorldState.h"
00006 #include "MotionManager.h"
00007 #include "Shared/Config.h"
00008 #include "Wireless/Socket.h"
00009 #include "Shared/get_time.h"
00010 #include "Events/EventBase.h"
00011
00012 #include <memory>
00013 #include <cmath>
00014 using namespace std;
00015
00016 ArmMC::ArmMC()
00017 : MotionCommand(), dirty(true), hold(true), tolerance(.05f),
00018 completionReported(true), targetTimestamp(0), timeout(2000)
00019 {
00020
00021
00022
00023
00024 takeSnapshot();
00025 setWeight(0);
00026 defaultMaxSpeed();
00027 }
00028
00029 void ArmMC::freezeMotion() {
00030 #ifdef TGT_HAS_ARMS
00031 for(unsigned int i=0; i<NumArmJoints; i++)
00032 armTargets[i]=armCmds[i].value;
00033 dirty=false;
00034 #endif
00035 }
00036
00037 void ArmMC::takeSnapshot() {
00038 #ifdef TGT_HAS_ARMS
00039 for(unsigned int i=0; i<NumArmJoints; i++)
00040 armTargets[i]=armCmds[i].value=state->outputs[ArmOffset+i];
00041 dirty=true;
00042 #endif
00043 }
00044
00045 float ArmMC::armJointValue(unsigned int i) {
00046 #ifdef TGT_HAS_ARMS
00047 return armTargets[i];
00048 #else
00049 serr->printf("WARNING: No Arm");
00050 return -1000.0f;
00051 #endif
00052 }
00053
00054 void ArmMC::defaultMaxSpeed(float x) {
00055 #ifdef TGT_HAS_ARMS
00056 for(unsigned int i = 0; i<NumArmJoints; i++)
00057 maxSpeed[i] = 0.3f;
00058 #endif
00059 }
00060
00061 void ArmMC::setWeight(float w) {
00062 #ifdef TGT_HAS_ARMS
00063 for(unsigned int i=0; i<NumArmJoints; i++)
00064 armCmds[i].weight=w;
00065 markDirty();
00066 #endif
00067 }
00068
00069 void ArmMC::setWeight(int i, float w) {
00070 #ifdef TGT_HAS_ARMS
00071 armCmds[i].weight=w;
00072 markDirty();
00073 #endif
00074 }
00075
00076 void ArmMC::setJoints(float shoulder, float elbow, float wrist){
00077 #ifdef TGT_HAS_ARMS
00078 setMaxSpeed(0, 0.4f);
00079 setMaxSpeed(1, 0.4f);
00080 setMaxSpeed(2, 0.4f);
00081 setJointValue(0, shoulder);
00082 setJointValue(1, elbow);
00083 setJointValue(2, wrist);
00084 #endif
00085 }
00086
00087
00088 void ArmMC::setJoints(float shoulder, float elbow, float yaw, float pitch, float roll, float gripper) {
00089 #ifdef TGT_HAS_ARMS
00090 setMaxSpeed(0, 0.4f);
00091 setMaxSpeed(1, 0.4f);
00092 setMaxSpeed(2, 0.4f);
00093 setMaxSpeed(3, 0.4f);
00094 setMaxSpeed(4, 0.4f);
00095 setMaxSpeed(5, 0.4f);
00096 setJointValue(0, shoulder);
00097 setJointValue(1, elbow);
00098 setJointValue(2, yaw);
00099 setJointValue(3, pitch);
00100 setJointValue(4, roll);
00101 setJointValue(5, gripper);
00102 #endif
00103 }
00104
00105 void ArmMC::setWrist(float pitch, float roll, float gripper) {
00106 #ifdef TGT_HAS_ARMS
00107 setMaxSpeed(3, 0.4f);
00108 setMaxSpeed(4, 0.4f);
00109 setMaxSpeed(5, 0.4f);
00110 setJointValue(3, pitch);
00111 setJointValue(4, roll);
00112 setJointValue(5, gripper);
00113 #endif
00114 }
00115
00116 bool ArmMC::moveOffsetToPoint(const fmat::Column<3>& offset, const fmat::Column<3>& tgt) {
00117 #ifndef TGT_HAS_ARMS
00118 return false;
00119 #else
00120 const KinematicJoint * kinEff=NULL;
00121 unsigned int effIdx = capabilities.findFrameOffset("GripperFrame");
00122 if(effIdx!=-1U)
00123 kinEff = kine->getKinematicJoint(effIdx);
00124 if(kinEff==NULL)
00125 kinEff = kine->getKinematicJoint(ArmOffset+NumArmJoints-1);
00126 if(kinEff==NULL)
00127 return false;
00128 KinematicJoint * effector = kinEff->cloneBranch();
00129 std::auto_ptr<KinematicJoint> root(effector->getRoot());
00130
00131
00132 bool conv = effector->getIK().solve(offset,*effector,IKSolver::Point(tgt));
00133
00134
00135 while(effector!=NULL) {
00136 if(effector->outputOffset<NumOutputs)
00137 setOutputCmd(effector->outputOffset, effector->getQ());
00138 effector = effector->getParent();
00139 }
00140 return conv;
00141 #endif
00142 }
00143
00144 bool ArmMC::moveOffsetToPointWithOrientation(const fmat::Column<3>& offset, const fmat::Column<3>& tgt, const fmat::Quaternion& ori) {
00145 #ifndef TGT_HAS_ARMS
00146 return false;
00147 #else
00148 const KinematicJoint * kinEff=NULL;
00149 unsigned int effIdx = capabilities.findFrameOffset("GripperFrame");
00150 if(effIdx!=-1U)
00151 kinEff = kine->getKinematicJoint(effIdx);
00152 if(kinEff==NULL)
00153 kinEff = kine->getKinematicJoint(ArmOffset+NumArmJoints-1);
00154 if(kinEff==NULL)
00155 return false;
00156 KinematicJoint * effector = kinEff->cloneBranch();
00157 std::auto_ptr<KinematicJoint> root(effector->getRoot());
00158
00159
00160 bool conv = effector->getIK().solve(offset, IKSolver::Rotation(fmat::Quaternion()), *effector, IKSolver::Point(tgt), 1, IKSolver::Rotation(ori), 0);
00161
00162
00163 while(effector!=NULL) {
00164 if(effector->outputOffset<NumOutputs)
00165 setOutputCmd(effector->outputOffset, effector->getQ());
00166 effector = effector->getParent();
00167 }
00168 return conv;
00169 #endif
00170 }
00171
00172 int ArmMC::updateOutputs() {
00173 int prevDirty=isDirty();
00174 if(prevDirty || hold) {
00175 dirty=false;
00176 #ifdef TGT_HAS_ARMS
00177 for(unsigned int i=0; i < NumArmJoints; i++) {
00178 if(maxSpeed[i]<=0) {
00179 armCmds[i].value=armTargets[i];
00180 motman->setOutput(this,i+ArmOffset,armCmds[i]);
00181 } else {
00182 unsigned int f=0;
00183 while(armTargets[i]>armCmds[i].value+maxSpeed[i] && f<NumFrames) {
00184 armCmds[i].value+=maxSpeed[i];
00185 motman->setOutput(this,i+ArmOffset,armCmds[i],f);
00186 f++;
00187 }
00188 while(armTargets[i]<armCmds[i].value-maxSpeed[i] && f<NumFrames) {
00189 armCmds[i].value-=maxSpeed[i];
00190 motman->setOutput(this,i+ArmOffset,armCmds[i],f);
00191 f++;
00192 }
00193 if(f<NumFrames) {
00194 armCmds[i].value=armTargets[i];
00195 for(;f<NumFrames;f++)
00196 motman->setOutput(this,i+ArmOffset,armCmds[i],f);
00197 } else
00198 dirty=true;
00199 }
00200 }
00201 #endif
00202 if(!dirty && !completionReported) {
00203 postEvent(EventBase(EventBase::motmanEGID,getID(),EventBase::statusETID));
00204 completionReported=true;
00205 targetTimestamp=get_time();
00206 }
00207 }
00208 return prevDirty;
00209 }
00210
00211 int ArmMC::isAlive() {
00212 #ifdef TGT_HAS_ARMS
00213 if(dirty || !completionReported)
00214 return true;
00215
00216 if(completionReported && (!hold || get_time()-targetTimestamp>timeout)) {
00217 if(get_time()-targetTimestamp>timeout && getAutoPrune())
00218 serr->printf("WARNING: ArmPointerMC (mcid %d) timed out - possible joint conflict or out-of-range target\n",getID());
00219 return false;
00220 }
00221 float maxdiff=0;
00222 for(unsigned int i=0; i<NumArmJoints; i++) {
00223 float diff=fabsf(state->outputs[ArmOffset+i]-armTargets[i]);
00224 if(diff>maxdiff)
00225 maxdiff=diff;
00226 }
00227 return (maxdiff>tolerance);
00228 #else
00229 return false;
00230 #endif
00231 }
00232
00233 void ArmMC::markDirty() {
00234 dirty=true;
00235 completionReported=false;
00236 #ifdef TGT_HAS_ARMS
00237 for(unsigned int i=0; i<NumArmJoints; i++)
00238 armCmds[i].value=motman->getOutputCmd(ArmOffset+i).value;
00239 #endif
00240 }
00241
00242 bool ArmMC::ensureValidJoint(unsigned int& i) {
00243 #ifdef TGT_HAS_ARMS
00244 if(i<NumArmJoints)
00245 return true;
00246 if(i>=ArmOffset && i<ArmOffset+NumArmJoints) {
00247 i-=ArmOffset;
00248 serr->printf("WARNING: ArmMC received a joint index of %d (ArmOffset+%d).\n",i+ArmOffset,i);
00249 serr->printf(" Since all parameters are assumed to be relative to ArmOffset,\n");
00250 serr->printf(" you should just pass %d directly.\n",i);
00251 serr->printf("WARNING: Assuming you meant %d...\n",i);
00252 return true;
00253 }
00254 serr->printf("ERROR: ArmMC received a joint index of %d (ArmOffset%+d).\n",i,i-ArmOffset);
00255 serr->printf("ERROR: This does not appear to be a arm joint. ArmPointerMC only controls\n");
00256 serr->printf(" arm joints, and assumes its arguments are relative to ArmOffset\n");
00257 #endif
00258 return false;
00259 }