// rotate and derivatives inline Point2 rotate_(const Rot2 & R, const Point2& p) {return R.rotate(p);}
int main() { /** * Step 1: Create a factor to express a unary constraint * The "prior" in this case is the measurement from a sensor, * with a model of the noise on the measurement. * * The "Key" created here is a label used to associate parts of the * state (stored in "RotValues") with particular factors. They require * an index to allow for lookup, and should be unique. * * In general, creating a factor requires: * - A key or set of keys labeling the variables that are acted upon * - A measurement value * - A measurement model with the correct dimensionality for the factor */ Rot2 prior = Rot2::fromAngle(30 * degree); prior.print("goal angle"); noiseModel::Isotropic::shared_ptr model = noiseModel::Isotropic::Sigma(1, 1 * degree); Symbol key('x',1); PriorFactor<Rot2> factor(key, prior, model); /** * Step 2: Create a graph container and add the factor to it * Before optimizing, all factors need to be added to a Graph container, * which provides the necessary top-level functionality for defining a * system of constraints. * * In this case, there is only one factor, but in a practical scenario, * many more factors would be added. */ NonlinearFactorGraph graph; graph.add(factor); graph.print("full graph"); /** * Step 3: Create an initial estimate * An initial estimate of the solution for the system is necessary to * start optimization. This system state is the "RotValues" structure, * which is similar in structure to a STL map, in that it maps * keys (the label created in step 1) to specific values. * * The initial estimate provided to optimization will be used as * a linearization point for optimization, so it is important that * all of the variables in the graph have a corresponding value in * this structure. * * The interface to all RotValues types is the same, it only depends * on the type of key used to find the appropriate value map if there * are multiple types of variables. */ Values initial; initial.insert(key, Rot2::fromAngle(20 * degree)); initial.print("initial estimate"); /** * Step 4: Optimize * After formulating the problem with a graph of constraints * and an initial estimate, executing optimization is as simple * as calling a general optimization function with the graph and * initial estimate. This will yield a new RotValues structure * with the final state of the optimization. */ Values result = LevenbergMarquardtOptimizer(graph, initial).optimize(); result.print("final result"); return 0; }
/* ************************************************************************* */ Rot2 Rot2betweenOptimized(const Rot2& r1, const Rot2& r2) { // Same as compose but sign of sin for r1 is reversed return Rot2::fromCosSin(r1.c() * r2.c() + r1.s() * r2.s(), -r1.s() * r2.c() + r1.c() * r2.s()); }
void go() { typedef Vec4<T> Vec; typedef Vec2<T> Vec2D; std::cout << std::endl; std::cout << sizeof(Vec) << std::endl; std::vector<Vec> vec1; vec1.reserve(50); std::vector<T> vect(23); std::vector<Vec> vec2(53); std::vector<Vec> vec3; vec3.reserve(50234); Vec x(2.0,4.0,5.0); Vec y(-3.0,2.0,-5.0); std::cout << x << std::endl; std::cout << Vec4<float>(x) << std::endl; std::cout << Vec4<double>(x) << std::endl; std::cout << -x << std::endl; std::cout << x.template get1<2>() << std::endl; std::cout << y << std::endl; std::cout << T(3.)*x << std::endl; std::cout << y*T(0.1) << std::endl; std::cout << (Vec(1) - y*T(0.1)) << std::endl; std::cout << mathSSE::sqrt(x) << std::endl; std::cout << dot(x,y) << std::endl; std::cout << dotSimple(x,y) << std::endl; std::cout << "equal" << (x==x ? " " : " not ") << "ok" << std::endl; std::cout << "not equal" << (x==y ? " not " : " ") << "ok" << std::endl; Vec z = cross(x,y); std::cout << z << std::endl; std::cout << "rotations" << std::endl; T a = 0.01; T ca = std::cos(a); T sa = std::sin(a); Rot3<T> r1( ca, sa, 0, -sa, ca, 0, 0, 0, 1); Rot2<T> r21( ca, sa, -sa, ca); Rot3<T> r2(Vec( 0, 1 ,0), Vec( 0, 0, 1), Vec( 1, 0, 0)); Rot2<T> r22(Vec2D( 0, 1), Vec2D( 1, 0)); { std::cout << "\n3D rot" << std::endl; Vec xr = r1.rotate(x); std::cout << x << std::endl; std::cout << xr << std::endl; std::cout << r1.rotateBack(xr) << std::endl; Rot3<T> rt = r1.transpose(); Vec xt = rt.rotate(xr); std::cout << x << std::endl; std::cout << xt << std::endl; std::cout << rt.rotateBack(xt) << std::endl; std::cout << r1 << std::endl; std::cout << rt << std::endl; std::cout << r1*rt << std::endl; std::cout << r2 << std::endl; std::cout << r1*r2 << std::endl; std::cout << r2*r1 << std::endl; std::cout << r1*r2.transpose() << std::endl; std::cout << r1.transpose()*r2 << std::endl; } { std::cout << "\n2D rot" << std::endl; Vec2D xr = r21.rotate(x.xy()); std::cout << x.xy() << std::endl; std::cout << xr << std::endl; std::cout << r21.rotateBack(xr) << std::endl; Rot2<T> rt = r21.transpose(); Vec2D xt = rt.rotate(xr); std::cout << x.xy() << std::endl; std::cout << xt << std::endl; std::cout << rt.rotateBack(xt) << std::endl; std::cout << r21 << std::endl; std::cout << rt << std::endl; std::cout << r21*rt << std::endl; std::cout << r22 << std::endl; std::cout << r21*r22 << std::endl; std::cout << r22*r21 << std::endl; std::cout << r21*r22.transpose() << std::endl; std::cout << r21.transpose()*r22 << std::endl; } }
/* ************************************************************************* */ Rot2 Rot2betweenDefault(const Rot2& r1, const Rot2& r2) { return r1.inverse() * r2; }