What it calls when you run the Supervisor: SupervisorFunctionCalls
What it calls when you run the Operator: OperatorFunctionCalls
From measurements on the actual robot doing wing offset changes to get the robot to squeeze in on some boards, we get that to get 1.0 Newtons of force change, you need a wing angle change of about 2-3 degrees. For leg0, it seemed to reliably have changes of 2.8-3.1 degrees/Newton. For leg1, it had values of ~2 degrees/Newton. I'm not sure about the other legs or what caused it to have different values for legs 0 and 1. But this does mean that if we want to have a 3N squeezing force, it will take about 10 degrees of wing offset change to make it ungrip or grip the tree with the feet starting from a position at the surface of the tree.
This was done with the standard
If you make the legs go up very rapidly (zero the wing offset when it is at -200 degrees or so), then it took a change of 23.5 degrees to get it to go from 3.4N to 0. This took 0.09 seconds.
If you just make the wing move through the air, you get the following: the leg hit the surface somewhere around the bottom of the actual wing position.
// update the gait _gait->updateClock(&_clock,&command); // output each leg's command to the robot for (int i=0; i < GAIT_NUMLEGS; i++) { // add in any manual offset angles correctTarget(i, &(command.leg_command[i].target)); // send command to hip _hiphw->setHipGain(i, &(command.leg_command[i].gain)); _hiphw->setHipTarget(i, &(command.leg_command[i].target)); }
Overall flow when you start a gait:
Stuff you have to do when you make a new module or mode:
CVS: ---------------------------------------------------------------------- CVS: Enter Log. Lines beginning with `CVS:' are removed automatically CVS: CVS: Committing in . CVS: CVS: Modified Files: CVS: Demo/Config/robots/arachi/generate_links.sh CVS: Demo/Config/robots/risebus12/stuccogaits.rc CVS: Demo/Config/robots/risebus12/gaits/quad_state.rc CVS: Demo/Operator/Makefile Demo/Operator/RiSEModes.cfg CVS: Demo/Operator/RiSEPanel.cfg Demo/Supervisor/supervisor.cc CVS: RobotCode/Behaviors/include/modules/ForceQuadState.hh CVS: RobotCode/Behaviors/include/modules/GaitClasses.hh CVS: RobotCode/Behaviors/modes/Makefile CVS: RobotCode/Behaviors/modules/ForceQuadState.cc CVS: Added Files: CVS: Demo/Operator/StateMode.acc CVS: RobotCode/Behaviors/include/StateModeStructs.hh CVS: RobotCode/Behaviors/include/modes/StateMode.hh CVS: RobotCode/Behaviors/modes/StateMode.cc CVS: RobotCode/Behaviors/modes/StateMode.mod CVS: ----------------------------------------------------------------------
/////// Functions we might need to call to get the force in the leg's home /////// coord system: // I think we just need to implement localForce() in Object.hh. // // From DeObject.h: // virtual DeFrame* frameHome() { return &homeFrame_; } // DeFrame& homeFrame() { return(homeFrame_); } // // Sample usage in Object.hh: // // This method return the total force (anf torque) acting on the // object relative to the inertial ("global") world frame at the // "current" time. // void globalForce ( DeVector6 *force ) { // _object->forceExternal( force ); // }; // void localForce ( DeVector6 *force ) { // // TODO: Fix this, this is just a placeholder. // _object->force.get(*force); // Added by Alan, this just returns the global Force.. // //_object->forceExternal( force ); // } // // In doing _object->force.get(*force) above we call the following from DeForce.h: // void get(DeVector6& force); // //!< \internal get 6x1 spacial vector that is the accumulation of the force // // properties for an object // // From Contact.hh: // This method calculates a frame transformation between Object A // and Object B (the objects in contact). It is normally assumed // that Object A is the "foot" and Object B is the "wall". The frame // that is returned is Object A's Frame described in Object B's frame. // DeFrame pose( void ); // // From Contact.cc: // DeFrame Contact::pose( void ) { // DeFrame bFa; // // // Get frames relating A and B to global and compute // // Frame relating A to B // DeFrame gFa = _objectA->globalFrame(); // DeFrame gFb = _objectB->globalFrame(); // // bFa.inversedMultiply( gFb, gFa ); // return bFa; // } // // Sample usage in OrientationContact.cc: // DeVector3 axis; DeFloat angle, relangle; // pose().rotation().get( axis, angle ); // // // From Contact.hh: // /** This method returns the relative translational and angular // velocity of object A wrt to object B in a 6-space vector. */ // DeVector6 velocity( void ); // // Implementation in Contact.cc: // Note that a DeVector6 consists of two 3x1 vectors. // spatial vector representing translational part and rotational part // DeVector6 Contact::velocity( void ) { // DeVector6 aVa, bVb, bVa; // DeTransform bTa; // // aVa = _objectA->getDeObject()->velocity(); // bVb = _objectB->getDeObject()->velocity(); // // bTa.set( pose() ); // bVa[0].multiply( bTa.rotation(), aVa[0] ); // bVa[1].multiply( bTa.rotation(), aVa[1] ); // bVa[0].subtract( bVa[0], bVb[0] ); // bVa[1].subtract( bVa[1], bVb[1] ); // // return bVa; // } // // From Object.hh: // This method return the frame of the object relative to the // inertial ("global") world frame at the "current" time. */ // const DeFrame & globalFrame( void ) { return _object->globalFrame( ); }; // // From DeFrame.h: // DE_MATH_API void inverse(const DeFrame& f); // //! this = t // DeFrame Contact::hometocurrentpose( void ) { // DeFrame hFgFa; // // // // Compute Frame relating A currently to its home frame // // Notation: gFa = global Frame for A // // hFa = home Frame for A // DeFrame gFa = _objectA->globalFrame(); // DeFrame hFa = _objectA->homeFrame(); // // hFgFa.inversedMultiply( hFa, gFa ); // return hFgFa; // } // // Now our globalForce function: // void globalForce ( DeVector6 *force ) { // DeVector6 * localforce; // _object->forceExternal( localforce ); // // DeFrame * globalFrame = globalFrame(); // Current frame of the object // // inverse(globalFrame); // Compute the inverse because we want the // // forces in the global frame ? // // Also I think this is the wrong syntax to compute the inverse.. // // Note that (if we are indeed needing to take the inverse) then you just // // need to take the inverse of the rotational part of the frame, which corresponds // // to the transpose. So you can just use <object>.inversedMultiply() which will do that // // at the same time as multiplying it, instead of making this inverse object and stuff // // like I did above. // // DeTransform inverseGlobalFrame; // inverseGlobalFrame.set( globalFrame ); // Note globalFrame has been inverted // // // Now multiply the local force by this transformation so it's in the // // object's global frame: // (*force[0]).multiply( inverseGlobalFrame.rotation(), globalforce[0] ); // forces // (*force[1]).multiply( inverseGlobalFrame.rotation(), globalforce[1] ); // torques // // }
-- AlanAsbeck - 07 Jul 2006