00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <opspace/ClassicTaskPostureController.hpp>
00023 #include <opspace/pseudo_inverse.hpp>
00024
00025
00026 #include <Eigen/LU>
00027 #include <Eigen/SVD>
00028 #include <opspace/task_library.hpp>
00029
00030 using jspace::pretty_print;
00031 using boost::shared_ptr;
00032
00033 namespace opspace {
00034
00035
00036 ClassicTaskPostureController::
00037 ClassicTaskPostureController(std::string const & name)
00038 : Controller(name)
00039 {
00040 declareParameter("jpos", &jpos_);
00041 declareParameter("jvel", &jvel_);
00042 declareParameter("gamma", &gamma_);
00043 declareParameter("fstar", &fstar_);
00044 declareParameter("lambda", &lambda_);
00045 declareParameter("jbar", &jbar_);
00046 declareParameter("nullspace", &nullspace_);
00047 }
00048
00049
00050 Status ClassicTaskPostureController::
00051 init(Model const & model)
00052 {
00053 return Status();
00054 }
00055
00056
00057 Status ClassicTaskPostureController::
00058 computeCommand(Model const & model,
00059 Skill & skill,
00060 Vector & gamma)
00061 {
00062 Status st(skill.update(model));
00063 if ( ! st) {
00064 return st;
00065 }
00066
00067 Skill::task_table_t const * tasks(skill.getTaskTable());
00068 if ( ! tasks) {
00069 st.ok = false;
00070 st.errstr = "null task table";
00071 return st;
00072 }
00073 if (2 != tasks->size()) {
00074 st.ok = false;
00075 st.errstr = "task table must have exactly 2 entries";
00076 return st;
00077 }
00078
00079 Task const * task((*tasks)[0]);
00080 Task const * posture((*tasks)[1]);
00081
00082 Matrix ainv;
00083 if ( ! model.getInverseMassInertia(ainv)) {
00084 st.ok = false;
00085 st.errstr = "failed to retrieve inverse mass inertia";
00086 return st;
00087 }
00088 Vector grav;
00089 if ( ! model.getGravity(grav)) {
00090 st.ok = false;
00091 st.errstr = "failed to retrieve gravity torques";
00092 return st;
00093 }
00094
00095 size_t const ndof(model.getNDOF());
00096 Matrix const & jac(task->getJacobian());
00097
00098 pseudoInverse(jac * ainv * jac.transpose(),
00099 task->getSigmaThreshold(),
00100 lambda_,
00101 0);
00102 fstar_ = lambda_ * task->getCommand();
00103 jbar_ = ainv * jac.transpose() * lambda_;
00104 nullspace_ = Matrix::Identity(ndof, ndof) - jac.transpose() * jbar_.transpose();
00105
00106 gamma_ = jac.transpose() * fstar_ + nullspace_ * posture->getCommand() + grav;
00107 gamma = gamma_;
00108
00109 jpos_ = model.getState().position_;
00110 jvel_ = model.getState().velocity_;
00111
00112 return st;
00113 }
00114
00115
00116 void ClassicTaskPostureController::
00117 dbg(std::ostream & os,
00118 std::string const & title,
00119 std::string const & prefix) const
00120 {
00121 if ( ! title.empty()) {
00122 os << title << "\n";
00123 }
00124 pretty_print(jpos_, os, prefix + "jpos", prefix + " ");
00125 pretty_print(jvel_, os, prefix + "jvel", prefix + " ");
00126 pretty_print(fstar_, os, prefix + "fstar", prefix + " ");
00127 pretty_print(lambda_, os, prefix + "lambda", prefix + " ");
00128 pretty_print(jbar_, os, prefix + "jbar", prefix + " ");
00129 pretty_print(gamma_, os, prefix + "gamma", prefix + " ");
00130 }
00131
00132 }