-
Notifications
You must be signed in to change notification settings - Fork 8
Feature/se3vel #94
Open
nosmokingsurfer
wants to merge
8
commits into
master
Choose a base branch
from
feature/SE3vel
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Feature/se3vel #94
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
0a88e42
Initial commit for SE3vel class, the extended SE3 group with velocit…
nosmokingsurfer 577713f
SE3velCov class for compounding initial commit #72
nosmokingsurfer 9ac8a21
Initial commit for SE3vel class, the extended SE3 group with velocit…
nosmokingsurfer 7ac2f21
SE3velCov class for compounding initial commit #72
nosmokingsurfer f96c199
new line at the EOF
nosmokingsurfer c221fb6
fixing merge errors
nosmokingsurfer 14e397c
brackets function in namespace mrob, visible for all other files incl…
g-ferrer 9cc6362
brackets function now defined in SE3cov and used in other files, such…
g-ferrer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
#include "mrob/SE3vel.hpp" | ||
|
||
using namespace mrob; | ||
|
||
SE3vel::SE3vel(const Mat5 &T) : T_(T) {} | ||
|
||
SE3vel::SE3vel(const SE3vel &T) : T_(T.T()){} | ||
|
||
SE3vel::SE3vel(const Mat91 &xi) | ||
{ | ||
this->Exp(xi); | ||
} | ||
|
||
Mat31 SE3vel::t() const | ||
{ | ||
return T_.topRightCorner<3,1>(); | ||
} | ||
|
||
Mat31 SE3vel::v() const | ||
{ | ||
return T_.block<3,1>(0,3); | ||
} | ||
|
||
Mat3 SE3vel::R() const | ||
{ | ||
return T_.topLeftCorner<3,3>(); | ||
} | ||
|
||
Mat5 SE3vel::T(void) const | ||
{ | ||
return this->T_; | ||
} | ||
|
||
SE3vel SE3vel::inv(void) const | ||
{ | ||
Mat5 inv(Mat5::Zero()); | ||
Mat3 R = this->R(); | ||
R.transposeInPlace(); | ||
|
||
inv << R, -R*this->v(), -R*this->t(), | ||
0,0,0,1,0, | ||
0,0,0,0,1; | ||
|
||
return SE3vel(inv); | ||
} | ||
|
||
SE3vel operator*(const SE3vel& lhs, const SE3vel& rhs) | ||
{ | ||
return SE3vel(Mat5(lhs.T()*rhs.T())); | ||
} | ||
|
||
Mat9 SE3vel::adj() const | ||
{ | ||
Mat9 res(Mat9::Zero()); | ||
Mat3 R = this->R(); | ||
Mat31 v = this->v(); | ||
Mat31 t = this->t(); | ||
|
||
res.block<3,3>(0,0) = R; | ||
res.block<3,3>(3,3) = R; | ||
res.block<3,3>(6,6) = R; | ||
|
||
res.block<3,3>(3,0) = hat3(v)*R; | ||
res.block<3,3>(6,0) = hat3(t)*R; | ||
|
||
return res; | ||
} | ||
|
||
std::ostream& operator<<(std::ostream &os, const SE3vel& obj) | ||
{ | ||
os << obj.T(); | ||
return os; | ||
} | ||
|
||
|
||
Mat5 hat9(const Mat91 &xi) | ||
{ | ||
Mat5 result(Mat5::Zero()); | ||
|
||
result << 0, -xi(2), xi(1), xi(3), xi(6), | ||
xi(2), 0, -xi(0), xi(4), xi(7), | ||
-xi(1), xi(0), 0, xi(5), xi(8), | ||
0, 0, 0, 0, 0, | ||
0, 0, 0, 0, 0; | ||
|
||
return result; | ||
} | ||
|
||
|
||
/** | ||
* Vee operator (v), the inverse of hat | ||
*/ | ||
Mat91 vee9(const Mat4 &xi_hat) | ||
{ | ||
Mat91 result(Mat91::Zero()); | ||
|
||
result << xi_hat(2,1), xi_hat(0,2), xi_hat(1,0), | ||
xi_hat(0,3), xi_hat(1,3), xi_hat(2,3), | ||
xi_hat(0,4), xi_hat(1,4), xi_hat(2,4); | ||
|
||
return result; | ||
} | ||
|
||
|
||
Mat3 SE3vel::left_jacobian(const Mat31& phi) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this not inside SO3? If that is the case, should it be added directly there? I am ok adding an issue and changing SO3 |
||
{ | ||
Mat3 V = Mat3::Identity(); | ||
Mat3 phi_hat = hat3(phi); | ||
double o = phi.norm(); | ||
double o2 = phi.squaredNorm(); | ||
// If rotation is not zero | ||
matData_t c2, c3; | ||
if ( o > 1e-3){ // c2 and c3 become numerically imprecise for o < 1-5, so we choose a conservative threshold 1e-3 | ||
c2 = (1 - std::cos(o))/o2; | ||
c3 = (o - std::sin(o))/o2/o; | ||
} | ||
else | ||
{ | ||
// second order Taylor (first order is zero since this is an even function) | ||
c2 = 0.5 - o2/24; | ||
// Second order Taylor | ||
c3 = 1.0/6.0 - o2/120; | ||
} | ||
V += c2*phi_hat + c3*phi_hat*phi_hat; | ||
|
||
return V; | ||
} | ||
|
||
|
||
Mat3 SE3vel::inv_left_jacobian(const Mat31 &phi) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same case here, maybe this is better to be moved? |
||
{ | ||
Mat3 Vinv = Mat3::Identity(); | ||
double k1; | ||
double o = phi.norm(); | ||
double o2 = phi.squaredNorm(); | ||
Mat3 phi_hat = hat3(phi); | ||
// 5e-3 bound provided on numerical_test.cpp, smaller than this k1 becomes degradated | ||
if (o > 5e-3) | ||
{ | ||
double c1 = std::sin(o); //sin(o)/o, we remove the o in both coeficients | ||
double c2 = (1 - std::cos(o))/o; // (1 - std::cos(o))/o/o | ||
k1 = 1/o2*(1 - 0.5*c1/c2); | ||
} | ||
//Taylor expansion for small o. | ||
else | ||
{ | ||
// f(o) = 1/12 + 1/2*f''*o^2 | ||
// f'' = 1/360 | ||
k1 = 1.0/12 + o2/720; | ||
} | ||
Vinv += -0.5*phi_hat + k1* phi_hat*phi_hat; | ||
|
||
// v = V^-1 t | ||
return Vinv; | ||
} | ||
|
||
void SE3vel::Exp(const Mat91& xi) | ||
{ | ||
Mat5 result(Mat5::Identity()); | ||
|
||
Mat31 phi = xi.head(3); | ||
Mat31 v = xi.segment<3>(3); | ||
Mat31 t = xi.tail(3); | ||
|
||
SO3 tmp(phi); | ||
|
||
result.topLeftCorner<3,3>() << tmp.R(); | ||
|
||
Mat3 jac = this->left_jacobian(phi); | ||
|
||
result.block<3,1>(0,3) << jac*v; | ||
result.block<3,1>(0,4) << jac*t; | ||
|
||
this->T_ = result; | ||
} | ||
|
||
Mat91 SE3vel::Ln() const | ||
{ | ||
Mat91 result; | ||
|
||
Mat3 R = this->R(); | ||
Mat31 v = this->v(); | ||
Mat31 t = this->t(); | ||
|
||
SO3 tmp(R); | ||
Mat31 log_R_vee = tmp.ln_vee(); | ||
Mat3 jac = SE3vel::inv_left_jacobian(log_R_vee); | ||
|
||
result.head(3) << log_R_vee; | ||
result.segment<3>(3) << jac*v; | ||
result.tail(3) << jac*t; | ||
|
||
return result; | ||
} | ||
|
||
void SE3vel::regenerate() | ||
{ | ||
Mat91 xi = this->Ln(); | ||
this->Exp(xi); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#include "mrob/SE3velCov.hpp" | ||
#include <iostream> | ||
|
||
using namespace mrob; | ||
|
||
SE3velCov::SE3velCov(void) | ||
{ | ||
this->T_ = Mat5::Identity(); | ||
this->covariance = Mat9::Identity(); | ||
} | ||
|
||
SE3velCov::SE3velCov(const SE3vel &pose, const Mat9 &covariance) | ||
{ | ||
this->T_ = pose.T(); | ||
this->covariance = covariance; | ||
} | ||
|
||
Mat9 SE3velCov::getQ(const Mat3 &cov_a, const Mat3 &cov_w, const double dt) const | ||
{ | ||
Mat9 Q(Mat9::Identity()); | ||
|
||
Q.topLeftCorner<3, 3>() = cov_w; | ||
Q.block<3, 3>(3, 3) = cov_a; | ||
Q.block<3, 3>(6, 3) = 1. / 2. * cov_a * dt; | ||
Q.block<3, 3>(3, 6) = 1. / 2. * cov_a * dt; | ||
Q.bottomRightCorner<3, 3>() = 1. / 4. * cov_a * dt * dt; | ||
Q *= dt * dt; | ||
|
||
return Q; | ||
} | ||
|
||
void SE3velCov::compound_2nd_order(const SE3vel &pose_increment, const Mat9 &Q, const double dt) | ||
{ | ||
Mat9 F(Mat9::Identity()); | ||
F.block<3, 3>(6, 3) = dt * Mat3::Identity(); | ||
|
||
Mat9 Gamma_inv_adj = pose_increment.inv().adj(); | ||
|
||
Mat9 tmp = Gamma_inv_adj * F; | ||
|
||
this->covariance = tmp * this->covariance * tmp.transpose() + Q; | ||
|
||
this->T_ = this->T() * pose_increment.T(); | ||
} | ||
|
||
void SE3velCov::compound_4th_order(const SE3vel &pose_increment, const Mat9 &Q, const double dt) | ||
{ | ||
Mat9 S_4th = this->get_S_4th(Q); // get_s_4th mus be called exactly before calling compound_2nd | ||
compound_2nd_order(pose_increment, Q, dt); | ||
|
||
this->covariance += S_4th; | ||
} | ||
|
||
Mat9 SE3velCov::get_S_4th(const Mat9 &Q) const | ||
{ | ||
Mat9 S_4th(Mat9::Zero()); | ||
|
||
Mat9 A_sigma(Mat9::Zero()); | ||
|
||
Mat9 sigma = this->covariance; | ||
Mat3 sigma_phi_phi = sigma.topLeftCorner<3, 3>(); | ||
Mat3 sigma_phi_nu = sigma.block<3, 3>(0, 3); | ||
Mat3 sigma_nu_phi = sigma_phi_nu.transpose(); | ||
Mat3 sigma_phi_rho = sigma.topRightCorner<3, 3>(); | ||
Mat3 sigma_rho_phi = sigma_phi_rho.transpose(); | ||
Mat3 sigma_nu_nu = sigma.block<3, 3>(3, 3); | ||
Mat3 sigma_nu_rho = sigma.block<3, 3>(3, 6); | ||
Mat3 sigma_rho_rho = sigma.bottomRightCorner<3, 3>(); | ||
|
||
A_sigma.topLeftCorner<3, 3>() = brackets(sigma_phi_phi); | ||
A_sigma.block<3, 3>(3, 0) = brackets(sigma_phi_nu.transpose() + sigma_phi_nu); | ||
A_sigma.block<3, 3>(3, 3) = brackets(sigma_phi_phi); | ||
A_sigma.bottomLeftCorner<3, 3>() = brackets(sigma_phi_rho.transpose() + sigma_phi_rho); | ||
A_sigma.bottomRightCorner<3, 3>() = brackets(sigma_phi_phi); | ||
|
||
Mat9 A_q(Mat9::Zero()); | ||
|
||
Mat3 q_phi_phi = Q.topLeftCorner<3, 3>(); | ||
Mat3 q_phi_nu = Q.block<3, 3>(0, 3); | ||
Mat3 q_nu_phi = q_phi_nu.transpose(); | ||
Mat3 q_phi_rho = Q.topRightCorner<3, 3>(); | ||
Mat3 q_rho_phi = q_phi_rho.transpose(); | ||
Mat3 q_nu_nu = Q.block<3, 3>(3, 3); | ||
Mat3 q_nu_rho = Q.block<3, 3>(3, 6); | ||
Mat3 q_rho_rho = Q.bottomRightCorner<3, 3>(); | ||
|
||
A_q.topLeftCorner<3, 3>() = brackets(q_phi_phi); | ||
A_q.block<3, 3>(3, 0) = brackets(q_phi_nu + q_phi_nu.transpose()); | ||
A_q.block<3, 3>(3, 3) = brackets(q_phi_phi); | ||
A_q.bottomLeftCorner<3, 3>() = brackets(q_phi_rho + q_phi_rho.transpose()); | ||
A_q.bottomRightCorner<3, 3>() = brackets(q_phi_phi); | ||
|
||
Mat9 B(Mat9::Zero()); | ||
|
||
B.topLeftCorner<3, 3>() = brackets(sigma_phi_phi, q_phi_phi); | ||
B.block<3, 3>(3, 0) = brackets(sigma_phi_phi, q_phi_nu) + brackets(sigma_nu_phi, q_phi_phi); | ||
B.block<3, 3>(0, 3) = B.block<3, 3>(3, 0).transpose(); | ||
B.block<3, 3>(6, 0) = brackets(sigma_phi_phi, q_phi_rho) + brackets(sigma_rho_phi, q_phi_phi); | ||
B.block<3, 3>(0, 6) = B.block<3, 3>(6, 0).transpose(); | ||
B.block<3,3>(3,3) = brackets(sigma_phi_phi,q_nu_nu) + brackets(sigma_phi_nu,q_nu_phi) + | ||
brackets(sigma_nu_phi, q_nu_phi) + brackets(sigma_nu_nu,q_phi_phi); | ||
|
||
B.block<3,3>(3,6) = brackets(sigma_nu_rho,q_phi_phi) + brackets(sigma_phi_rho,q_nu_phi) + | ||
brackets(sigma_nu_phi,q_rho_phi) + brackets(sigma_phi_phi, q_nu_rho); | ||
B.block<3,3>(6,3) = B.block<3,3>(3,6).transpose(); | ||
B.bottomRightCorner<3, 3>() = brackets(sigma_phi_phi,q_rho_rho) + brackets(sigma_phi_rho,q_rho_phi) + | ||
brackets(sigma_rho_phi,q_phi_rho) + brackets(sigma_rho_rho,q_phi_phi); | ||
|
||
S_4th = 1./12.*(A_sigma*Q + Q*A_sigma.transpose() + A_q*sigma + sigma*A_q.transpose()) + 1./4.*B; | ||
|
||
return S_4th; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, you can also use the form Mat<1,9> or Vec<9> but i guess this was more convenient... I