00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00059 #include "tutsim.hpp"
00060 #include <opspace/task_library.hpp>
00061 #include <jspace/test/sai_util.hpp>
00062 #include <boost/shared_ptr.hpp>
00063 #include <FL/fl_draw.H>
00064 #include <err.h>
00065
00066
00067 namespace tut05 {
00068
00069 using namespace jspace;
00070
00071 class PTask : public opspace::Task {
00072 public:
00073 PTask()
00074 : opspace::Task("tut05::PTask"),
00075 initialized_(false)
00076 {
00077 declareParameter("goalpos", &goalpos_);
00078 declareParameter("goalvel", &goalvel_);
00079 }
00080
00081 void updateStateAndJacobian(Model const & model)
00082 {
00083 jspace::Transform ee_transform;
00084 model.computeGlobalFrame(model.getNode(3),
00085 0, 0, -1,
00086 ee_transform);
00087 actual_ = ee_transform.translation().block(1, 0, 2, 1);
00088 Matrix Jfull;
00089 model.computeJacobian(model.getNode(3),
00090 ee_transform.translation(),
00091 Jfull);
00092 jacobian_ = Jfull.block(1, 0, 2, Jfull.cols());
00093 curvel_ = jacobian_ * model.getState().velocity_;
00094 }
00095
00096 virtual jspace::Status init(jspace::Model const & model)
00097 {
00099
00100
00101 kp_ = 32.0;
00102 kd_ = 8.0;
00103
00105
00106
00107
00108
00109
00110
00111
00112 updateStateAndJacobian(model);
00113
00115
00116
00117 goalpos_ = actual_;
00118 goalvel_ = jspace::Vector::Zero(2);
00119
00121
00122
00123
00124 initialized_ = true;
00125 jspace::Status ok;
00126 return ok;
00127 }
00128
00129
00130 virtual jspace::Status update(jspace::Model const & model)
00131 {
00133
00134
00135 if ( ! initialized_ ) {
00136 init(model);
00137 }
00138
00140
00141
00142 updateStateAndJacobian(model);
00143
00145
00146
00147
00148
00149
00150
00151 command_ = kp_ * (goalpos_ - actual_) + kd_ * (goalvel_ - curvel_);
00152
00153 jspace::Status ok;
00154 return ok;
00155 }
00156
00157 bool initialized_;
00158 double kp_, kd_;
00159 jspace::Vector curvel_;
00160 jspace::Vector goalpos_, goalvel_;
00161
00162
00163
00164 opspace::Task::actual_;
00165 opspace::Task::jacobian_;
00166 };
00167
00168 }
00169
00170
00171 static std::string model_filename(TUTROB_XML_PATH_STR);
00172 static boost::shared_ptr<jspace::Model> model;
00173 static tut05::PTask ptask;
00174 static opspace::Parameter * goalpos;
00175 static opspace::Parameter * goalvel;
00176 static size_t mode;
00177
00178
00179 static bool servo_cb(size_t toggle_count,
00180 double wall_time_ms,
00181 double sim_time_ms,
00182 jspace::State & state,
00183 jspace::Vector & command)
00184 {
00185 mode = toggle_count % 4;
00186 static size_t prevmode(42);
00187
00188 if (0 == mode) {
00189
00191
00192
00193 for (int ii(0); ii < state.position_.rows(); ++ii) {
00194 static double const amplitude(0.5 * M_PI);
00195 double const omega(1.0 + 0.1 * ii);
00196 double const phase(omega * 1e-3 * wall_time_ms);
00197 state.position_[ii] = amplitude * sin(phase);
00198 state.velocity_[ii] = omega * amplitude * cos(phase);
00199 }
00200 prevmode = mode;
00201 return false;
00202
00203 }
00204
00206
00207
00208 model->update(state);
00209
00210 if (0 == prevmode) {
00211 jspace::Status const st(ptask.init(*model));
00212 if ( ! st) {
00213 errx(EXIT_FAILURE, "ptask.init() failed: %s", st.errstr.c_str());
00214 }
00215 }
00216
00217 static jspace::Vector pos(2), vel(2);
00218 static double const ox(0.2);
00219 static double const oy(0.37);
00220 static double const amp(2.5);
00221 double const px(ox * 1e-3 * wall_time_ms);
00222 double const py(oy * 1e-3 * wall_time_ms);
00223 pos << amp * sin(px), amp * sin(py);
00224 vel << ox * amp * cos(px), oy * amp * cos(py);
00225 if ( ! goalpos->set(pos)) {
00226 errx(EXIT_FAILURE, "failed to set end-effector goal position");
00227 }
00228 if ( ! goalvel->set(vel)) {
00229 errx(EXIT_FAILURE, "failed to set end-effector goal velocity");
00230 }
00231
00232 ptask.update(*model);
00233
00235
00236
00237
00238
00239
00240
00241
00242
00243 jspace::Matrix aa;
00244 model->getMassInertia(aa);
00245 jspace::Vector gg;
00246 model->getGravity(gg);
00247 jspace::Vector cc;
00248 model->getCoriolisCentrifugal(cc);
00249
00250 char const * mode_desc;
00251 switch (mode) {
00252 case 1:
00253 mode_desc = "no compensation\n";
00254 command = ptask.getJacobian().transpose() * ptask.getCommand();
00255 break;
00256 case 2:
00257 mode_desc = "only gravity compensation\n";
00258 command = ptask.getJacobian().transpose() * ptask.getCommand() + gg;
00259 break;
00260 default:
00261 mode_desc = "full compensation\n";
00262 command = aa * ptask.getJacobian().transpose() * ptask.getCommand() + gg + cc;
00263 }
00264
00265 static size_t iteration(0);
00266 if (0 == (iteration % 100)) {
00267 std::cerr << "**************************************************\n"
00268 << mode_desc;
00269 jspace::pretty_print(state.position_, std::cerr, " jpos", " ");
00270 jspace::pretty_print(state.velocity_, std::cerr, " jvel", " ");
00271 jspace::pretty_print(ptask.actual_, std::cerr, " ppos", " ");
00272 jspace::pretty_print(ptask.curvel_, std::cerr, " pvel", " ");
00273 jspace::pretty_print(ptask.goalpos_, std::cerr, " goalpos", " ");
00274 jspace::pretty_print(ptask.goalvel_, std::cerr, " goalvel", " ");
00275 jspace::pretty_print(ptask.jacobian_, std::cerr, " Jacobian", " ");
00276 jspace::pretty_print(command, std::cerr, " command", " ");
00277 }
00278 ++iteration;
00279
00280 prevmode = mode;
00281 return true;
00282 }
00283
00284
00285 static void draw_cb(double x0, double y0, double scale)
00286 {
00287 if (0 != mode) {
00288
00290
00291
00292
00293
00294
00295 fl_color(255, 100, 100);
00296 fl_line_style(FL_SOLID, 1, 0);
00297
00298 double const gx(goalpos->getVector()->x());
00299 double const gy(goalpos->getVector()->y());
00300 int const rr(ceil(0.15 * scale));
00301 int const dd(2 * rr);
00302 fl_arc(int(x0 + gx * scale) - rr, int(y0 - gy * scale) - rr, dd, dd, 0.0, 360.0);
00303
00304 double const vx(goalvel->getVector()->x());
00305 double const vy(goalvel->getVector()->y());
00306 double const px(gx + vx * 0.1);
00307 double const py(gy + vy * 0.1);
00308 fl_line(x0 + (gx + 0.2) * scale, y0 - gy * scale,
00309 x0 + (gx - 0.2) * scale, y0 - gy * scale);
00310 fl_line(x0 + gx * scale, y0 - (gy + 0.2) * scale,
00311 x0 + gx * scale, y0 - (gy - 0.2) * scale);
00312 fl_color(255, 255, 100);
00313 fl_line(x0 + gx * scale, y0 - gy * scale,
00314 x0 + px * scale, y0 - py * scale);
00315 }
00316 }
00317
00318
00319 int main(int argc, char ** argv)
00320 {
00321 try {
00322 model.reset(jspace::test::parse_sai_xml_file(model_filename, true));
00323 goalpos = ptask.lookupParameter("goalpos", opspace::PARAMETER_TYPE_VECTOR);
00324 if ( ! goalpos) {
00325 errx(EXIT_FAILURE, "failed to find appropriate goalpos parameter");
00326 }
00327 goalvel = ptask.lookupParameter("goalvel", opspace::PARAMETER_TYPE_VECTOR);
00328 if ( ! goalvel) {
00329 errx(EXIT_FAILURE, "failed to find appropriate goalvel parameter");
00330 }
00331 }
00332 catch (std::runtime_error const & ee) {
00333 errx(EXIT_FAILURE, "%s", ee.what());
00334 }
00335 tutsim::set_draw_cb(draw_cb);
00336 return tutsim::run(servo_cb);
00337 }