00001 #include <reactive_grasping_pr2/pr2_arm_ik.h>
00002
00003 #include <cmath>
00004 #include <algorithm>
00005
00006 namespace pr2_arm_ik {
00007
00008 static VectorT goal;
00009 static Obstacles obstacles;
00010
00011
00012 static float h = 0.5f;
00013 static float c_b = 0.0007f;
00014 static float c_p = 0.0003f;
00015 static float c_u = 0.1f;
00016 static float sigma = 0.01f;
00017 static float sigma_p = 0.005f;
00018 static float c_xT = 0.04f;
00019
00020 void setGoal(const VectorT &g) {
00021 goal = g;
00022 }
00023
00024 void setObstacles(const Obstacles &obs) {
00025 obstacles = obs;
00026 }
00027
00028 Obstacles &getObstacles() {
00029 return obstacles;
00030 }
00031
00032 void dynamics(const VectorT &x, const VectorT &u, VectorT &xNext) {
00033
00034 int m = u.size();
00035 xNext.setZero(x.size());
00036 for (int i = 0; i+m <= x.size(); i+=m) {
00037 for (int j = 0; j < m; ++j)
00038 xNext(i+j) = x(i+j) + u(j);
00039 }
00040 }
00041
00042 void dynamicsD(const VectorT &x, const VectorT &u, Deriv &d) {
00043 int n = x.size();
00044 int m = u.size();
00045
00046 d.fx.resize(n, n);
00047 d.fx.setIdentity();
00048
00049 d.fu.setZero(n, m);
00050 for(int i = 0; i < n; ++i) {
00051 int pos = int(i % m);
00052 d.fu(i, pos) = 1.;
00053 }
00054
00055 d.fxx.resize(n);
00056 d.fxu.resize(n);
00057 d.fuu.resize(n);
00058 for (int i = 0; i < n; ++i) {
00059 d.fxx[i].setZero(n,n);
00060 d.fxu[i].setZero(n,m);
00061 d.fuu[i].setZero(m,m);
00062 }
00063 }
00064
00065 float cost(const VectorT &x, const VectorT &u) {
00066 int m = u.size();
00067 float goalCost = c_xT * (x.head(m) - goal).squaredNorm();
00068 float obstacleSum = 0.;
00069 float partSum = 0.;
00070
00071 for (int i = 0; i < obstacles.size(); ++i) {
00072 obstacleSum += std::exp((-1.f / sigma) * (x.head(m) - obstacles[i]).squaredNorm());
00073 }
00074
00075 for (int i = 0; i+m <= x.size(); i+=m) {
00076 partSum += std::exp((-1.f / sigma_p) * (x.block(i, 0, m , 1) - goal).squaredNorm());
00077 }
00078
00079
00080 float totalCost = goalCost + std::pow(c_u, h) * u.squaredNorm() + c_b * obstacleSum + c_p * partSum;
00081 return totalCost;
00082 }
00083
00084 void costD(const VectorT &x, const VectorT &u, Deriv &d) {
00085 int n = x.size();
00086 int m = u.size();
00087
00088 d.cu = 2.f * std::pow(c_u, h) * u;
00089
00090 d.cuu.setIdentity(m, m);
00091 d.cuu *= 2.f * std::pow(c_u, h);
00092
00093 d.cx.setZero(n);
00094 d.cx.head(m) = 2.f * c_xT * (x.head(m) - goal);
00095 d.cxx.setIdentity(n, n);
00096 d.cxx *= 2.f * c_xT;
00097
00098
00099 VectorT cx_obs;
00100 MatrixT cxx_obs;
00101 cx_obs.setZero(m);
00102 cxx_obs.setZero(m, m);
00103 for (int i = 0; i < obstacles.size(); ++i) {
00104 VectorT tmp_diff = (x.head(m) - obstacles[i]);
00105 MatrixT tmp_diff_outer = tmp_diff * tmp_diff.transpose();
00106 cx_obs += (-2.f/sigma) * tmp_diff * std::exp((-1.f / sigma) * tmp_diff.squaredNorm());
00107
00108 cxx_obs.array() += (4. * tmp_diff_outer.array());
00109 cxx_obs.diagonal().array() -= 2. * sigma;
00110 cxx_obs.array() = (cxx_obs.array() / (sigma * sigma)) * std::exp((-1.f / sigma) * tmp_diff.squaredNorm());
00111 }
00112
00113
00114 VectorT cx_parts;
00115 MatrixT cxx_parts;
00116 cx_parts.setZero(x.size());
00117 cxx_parts.setZero(n, n);
00118 for (int i = m; i+m <= n; i+=m) {
00119 VectorT tmp_diff = (x.block(i, 0, m, 1) - goal);
00120 MatrixT tmp_diff_outer = tmp_diff * tmp_diff.transpose();
00121 cx_parts.block(i, 0, m, 1) += (-2.f/sigma_p) * tmp_diff * std::exp((-1.f / sigma_p) * tmp_diff.squaredNorm());
00122
00123 cxx_parts.block(i, i, m, m).array() += (4. * tmp_diff_outer.array());
00124 cxx_parts.block(i, i, m, m).diagonal().array() -= 2. * sigma_p;
00125 cxx_parts.block(i, i, m, m).array() = (cxx_parts.block(i, i, m, m).array() / (sigma_p * sigma_p)) * std::exp((-1.f / sigma_p) * tmp_diff.squaredNorm());
00126 }
00127
00128 d.cx.head(m) += c_b * cx_obs;
00129 d.cx += c_p * cx_parts;
00130
00131 d.cxx.block(0, 0, m, m) += c_b * cxx_obs.block(0, 0, m, m);
00132 d.cxx += c_p * cxx_parts;
00133
00134 d.cxu.setZero(n, m);
00135 }
00136 }