00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00039 #include "tutsim.hpp"
00040 #include <opspace/Task.hpp>
00041 #include <jspace/test/sai_util.hpp>
00042 #include <boost/shared_ptr.hpp>
00043 #include <err.h>
00044
00045
00046 namespace tut04 {
00047
00048 class JTask : public opspace::Task {
00049 public:
00050 JTask()
00051 : opspace::Task("tut04::JTask"),
00052 initialized_(false),
00053 inertia_compensation_(true),
00054 coriolis_compensation_(true)
00055 {
00056 }
00057
00058 virtual jspace::Status init(jspace::Model const & model)
00059 {
00061
00062
00063
00064 jacobian_ = jspace::Matrix::Identity(model.getNDOF(), model.getNDOF());
00065
00067
00068
00069 kp_ = 100.0;
00070 kd_ = 20.0;
00071
00073
00074
00075 goalpos_ = model.getState().position_;
00076 goalvel_ = model.getState().velocity_;
00077
00079
00080
00081
00082 initialized_ = true;
00083 jspace::Status ok;
00084 return ok;
00085 }
00086
00087
00088 virtual jspace::Status update(jspace::Model const & model)
00089 {
00091
00092
00093 if ( ! initialized_ ) {
00094 init(model);
00095 }
00096
00098
00099
00100
00101
00102 actual_ = model.getState().position_;
00103
00105
00106
00107
00108
00109
00110 jspace::Vector gamma;
00111 gamma = kp_ * (goalpos_ - actual_) + kd_ * (goalvel_ - model.getState().velocity_);
00112
00113 if (inertia_compensation_) {
00114 jspace::Matrix aa;
00115 if ( ! model.getMassInertia(aa)) {
00116 return jspace::Status(false, "failed to retrieve inertia");
00117 }
00118 command_ = aa * gamma;
00119 }
00120 else {
00121 command_ = gamma;
00122 }
00123
00124 if (coriolis_compensation_) {
00125 jspace::Vector cc;
00126 if ( ! model.getCoriolisCentrifugal(cc)) {
00127 return jspace::Status(false, "failed to retrieve coriolis");
00128 }
00129 command_ += cc;
00130 }
00131
00132 jspace::Vector gg;
00133 if ( ! model.getGravity(gg)) {
00134 return jspace::Status(false, "failed to retrieve gravity torque");
00135 }
00136 command_ += gg;
00137
00138 jspace::Status ok;
00139 return ok;
00140 }
00141
00142 bool initialized_;
00143 bool inertia_compensation_;
00144 bool coriolis_compensation_;
00145 double kp_, kd_;
00146 jspace::Vector goalpos_, goalvel_;
00147 };
00148
00149 }
00150
00151
00152 static std::string model_filename(TUTROB_XML_PATH_STR);
00153 static boost::shared_ptr<jspace::Model> model;
00154 static boost::shared_ptr<tut04::JTask> jtask;
00155
00156
00157 static bool servo_cb(size_t toggle_count,
00158 double wall_time_ms,
00159 double sim_time_ms,
00160 jspace::State & state,
00161 jspace::Vector & command)
00162 {
00164
00165
00166 model->update(state);
00167
00169
00170
00171
00172 jtask->goalpos_.resize(state.position_.rows());
00173 jtask->goalvel_.resize(state.position_.rows());
00174 for (int ii(0); ii < state.position_.rows(); ++ii) {
00175 static double const amplitude(0.9 * M_PI);
00176 double const omega(0.5 + 0.3 * ii);
00177 double const phase(omega * 1e-3 * wall_time_ms);
00178 jtask->goalpos_[ii] = amplitude * sin(phase);
00179 jtask->goalvel_[ii] = omega * amplitude * cos(phase);
00180 }
00181
00183
00184
00185 switch (toggle_count % 3) {
00186 case 0:
00187 jtask->inertia_compensation_ = false;
00188 jtask->coriolis_compensation_ = false;
00189 break;
00190 case 1:
00191 jtask->inertia_compensation_ = true;
00192 jtask->coriolis_compensation_ = false;
00193 break;
00194 case 2:
00195 default:
00196 jtask->inertia_compensation_ = true;
00197 jtask->coriolis_compensation_ = true;
00198 }
00199
00201
00202
00203 jtask->update(*model);
00204 command = jtask->getCommand();
00205
00207
00208
00209 static size_t iteration(0);
00210 if (0 == (iteration % 100)) {
00211 if (jtask->inertia_compensation_) {
00212 std::cerr << "inertia compensation is ON\n";
00213 }
00214 else {
00215 std::cerr << "inertia compensation is off\n";
00216 }
00217 if (jtask->coriolis_compensation_) {
00218 std::cerr << "coriolis compensation is ON\n";
00219 jspace::Vector cc;
00220 model->getCoriolisCentrifugal(cc);
00221 jspace::pretty_print(cc, std::cerr, " Coriolis/centrifugal torques", " ");
00222 }
00223 else {
00224 std::cerr << "coriolis compensation is off\n";
00225 }
00226 jspace::pretty_print(jtask->goalpos_, std::cerr, " goalpos", " ");
00227 jspace::pretty_print(state.position_, std::cerr, " jpos", " ");
00228 jspace::pretty_print(jtask->goalvel_, std::cerr, " goalvel", " ");
00229 jspace::pretty_print(state.velocity_, std::cerr, " jvel", " ");
00230 jspace::pretty_print(command, std::cerr, " command", " ");
00231 }
00232 ++iteration;
00233
00234 return true;
00235 }
00236
00237
00238 static void draw_cb(double x0, double y0, double scale)
00239 {
00240 if (0 != jtask->goalpos_.rows()) {
00241 tutsim::draw_robot(jtask->goalpos_, 1, 100, 255, 100, x0, y0, scale);
00242 }
00243 }
00244
00245
00246 int main(int argc, char ** argv)
00247 {
00248 try {
00249 model.reset(jspace::test::parse_sai_xml_file(model_filename, true));
00250 jtask.reset(new tut04::JTask());
00251 }
00252 catch (std::runtime_error const & ee) {
00253 errx(EXIT_FAILURE, "%s", ee.what());
00254 }
00255 tutsim::set_draw_cb(draw_cb);
00256 return tutsim::run(servo_cb);
00257 }