Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5e96627
starting work on gpmp2
kshaji3 Jul 9, 2026
8344e2a
added more gp factors
kshaji3 Jul 9, 2026
06c3547
added interpolators
kshaji3 Jul 9, 2026
1d4dca3
added more code for factor handling
kshaji3 Jul 9, 2026
f393d2b
initial unit tests
kshaji3 Jul 9, 2026
7f8ac12
added unit tests
kshaji3 Jul 9, 2026
d556c36
python tests
kshaji3 Jul 9, 2026
ca2275b
edits for python
kshaji3 Jul 9, 2026
79ca2e0
fixes unit test(?)
kshaji3 Jul 9, 2026
b10c0fe
Potential fix for pull request finding
kshaji3 Jul 10, 2026
9c9bbd4
Potential fix for pull request finding
kshaji3 Jul 10, 2026
f4fdb0e
Potential fix for pull request finding
kshaji3 Jul 10, 2026
de4c718
joint, velocity limits
kshaji3 Jul 10, 2026
db95a61
added unit tests for joint limit loss terms
kshaji3 Jul 10, 2026
2f359f6
added steap impleemntation test
kshaji3 Jul 13, 2026
6923e41
steap edits in python
kshaji3 Jul 13, 2026
4051f6c
edit fix
kshaji3 Jul 14, 2026
dcc9d86
added 18dof factor graph test, but still need to test in RobotStudio …
kshaji3 Jul 14, 2026
e91687c
more tests for handling original platforms thickness
kshaji3 Jul 14, 2026
cc12a53
collision factor addition
kshaji3 Jul 14, 2026
23ef85d
exposed python bindings
kshaji3 Jul 14, 2026
418afc4
fix unit test
kshaji3 Jul 14, 2026
68e1bc1
fixed unit tests I believe
kshaji3 Jul 14, 2026
4750bf3
removed non-sphere-based methods
kshaji3 Jul 20, 2026
0c2dc8e
made it explicitly a sphere factor
kshaji3 Jul 20, 2026
f3beab7
reject same link pairs
kshaji3 Jul 20, 2026
20712cd
added test to reject poiints that have different radii
kshaji3 Jul 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions gtdynamics.i
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,139 @@ class Trajectory {
void writeToFile(const gtdynamics::Robot &robot, const string &name, const gtsam::Values &results) const;
};

/********************** gpmp2 **********************/
#include <gtdynamics/gpmp2/SignedDistanceField.h>
class SignedDistanceField {
SignedDistanceField();
SignedDistanceField(const gtsam::Matrix &positions,
const gtsam::Vector &distances);
SignedDistanceField(const gtsam::Matrix &positions,
const gtsam::Vector &distances, double tol);

double getSignedDistance(const gtsam::Point3 &point) const;

gtsam::Point3 origin() const;
size_t xCount() const;
size_t yCount() const;
size_t zCount() const;
double cellSize() const;

bool equals(const gtdynamics::SignedDistanceField &expected,
double tol) const;
void print(const string &s = "") const;
};

#include <gtdynamics/gpmp2/RobotQueryPoints.h>
class RobotQueryPoints {
RobotQueryPoints(const gtdynamics::Robot &robot, string base_link_name,
const std::vector<gtdynamics::Joint *> &joints,
const gtdynamics::PointOnLinks &points);
RobotQueryPoints(const gtdynamics::Robot &robot, string base_link_name,
const std::vector<gtdynamics::Joint *> &joints,
const gtdynamics::PointOnLinks &points,
const gtsam::Pose3 &wTbase);

size_t dof() const;
size_t nrPoints() const;
gtsam::Matrix worldPoints(const gtsam::Vector &q) const;
};

#include <gtdynamics/factors/GPLinearPriorFactor.h>
class GPLinearPrior : gtsam::NoiseModelFactor {
GPLinearPrior(gtsam::Key pose_key1, gtsam::Key vel_key1, gtsam::Key pose_key2,
gtsam::Key vel_key2, double delta_t,
const gtsam::noiseModel::Base *Qc_model);

size_t dof() const;
double deltaT() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

#include <gtdynamics/factors/ObstacleSDFFactor.h>
class ObstacleSDFFactor : gtsam::NoiseModelFactor {
ObstacleSDFFactor(gtsam::Key q_key, const gtdynamics::RobotQueryPoints &robot,
const gtdynamics::SignedDistanceField *sdf,
double cost_sigma, double epsilon);
ObstacleSDFFactor(gtsam::Key q_key, const gtdynamics::RobotQueryPoints &robot,
const gtdynamics::SignedDistanceField *sdf,
double cost_sigma, double epsilon,
const gtsam::Vector &radii);

double epsilon() const;
gtsam::Vector radii() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

#include <gtdynamics/factors/JointLimitFactorVector.h>
class JointLimitFactorVector : gtsam::NoiseModelFactor {
JointLimitFactorVector(gtsam::Key q_key,
const gtsam::noiseModel::Base *cost_model,
const gtsam::Vector &down_limit,
const gtsam::Vector &up_limit,
const gtsam::Vector &limit_thresh);

size_t dof() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

#include <gtdynamics/factors/VelocityLimitFactorVector.h>
class VelocityLimitFactorVector : gtsam::NoiseModelFactor {
VelocityLimitFactorVector(gtsam::Key v_key,
const gtsam::noiseModel::Base *cost_model,
const gtsam::Vector &vel_limit,
const gtsam::Vector &limit_thresh);

size_t dof() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

#include <gtdynamics/factors/ObstacleSDFFactorGP.h>
class ObstacleSDFFactorGP : gtsam::NoiseModelFactor {
ObstacleSDFFactorGP(gtsam::Key q_key1, gtsam::Key v_key1, gtsam::Key q_key2,
gtsam::Key v_key2,
const gtdynamics::RobotQueryPoints &robot,
const gtdynamics::SignedDistanceField *sdf,
double cost_sigma, double epsilon,
const gtsam::noiseModel::Base *Qc_model, double delta_t,
double tau);

double epsilon() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

#include <gtdynamics/factors/SelfCollisionSphereFactor.h>
class SelfCollisionPair {
SelfCollisionPair();
SelfCollisionPair(size_t a, size_t b, double epsilon);

size_t a;
size_t b;
double epsilon;
};
// SelfCollisionPairs defined in specializations.h

class SelfCollisionSphereFactor : gtsam::NoiseModelFactor {
SelfCollisionSphereFactor(gtsam::Key q_key,
const gtdynamics::RobotQueryPoints &robot,
const gtdynamics::SelfCollisionPairs &pairs,
const gtsam::Vector &radii, double cost_sigma);
SelfCollisionSphereFactor(gtsam::Key q_key,
const gtdynamics::RobotQueryPoints &robot,
const gtdynamics::SelfCollisionPairs &pairs,
const gtsam::Vector &radii,
const gtsam::Vector &sigmas);

size_t nrPairs() const;
gtsam::Vector radii() const;
void print(const string &s = "", const gtsam::KeyFormatter &keyFormatter =
gtdynamics::GTDKeyFormatter);
};

/********************** Utilities **********************/
#include <gtdynamics/utils/format.h>
string GtdFormat(const gtsam::Values &t, const string &s = "");
Expand Down
2 changes: 1 addition & 1 deletion gtdynamics/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# All subdirectories that contain source code relevant to this library.
set(SOURCE_SUBDIRS universal_robot utils factors constraints optimizer constrained_optimizer kinematics mechanics statics dynamics cmopt cmcopt scenarios)
set(SOURCE_SUBDIRS universal_robot utils factors constraints optimizer constrained_optimizer kinematics mechanics statics dynamics cmopt cmcopt scenarios gpmp2)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand Down
3 changes: 3 additions & 0 deletions gtdynamics/factors/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if(GTSAM_BUILD_TESTS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt)
add_subdirectory(tests)
endif()
172 changes: 172 additions & 0 deletions gtdynamics/factors/GPLiePriorFactor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/* ----------------------------------------------------------------------------
* GTDynamics Copyright 2020, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* See LICENSE for the license information
* -------------------------------------------------------------------------- */

/**
* @file GPLiePriorFactor.h
* @brief Gaussian process prior factor on any Lie group, see Barfoot14rss.
* @author Karthik Shaji - Adapted from gpmp2 by Jing Dong.
*/

#pragma once

#include <gtdynamics/gpmp2/GPutils.h>
#include <gtsam/base/Lie.h>
#include <gtsam/base/Matrix.h>
#include <gtsam/base/Vector.h>
#include <gtsam/base/concepts.h>
#include <gtsam/nonlinear/NoiseModelFactorN.h>
#include <gtsam/nonlinear/NonlinearFactor.h>

#include <cmath>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>

#ifdef GTDYNAMICS_ENABLE_BOOST_SERIALIZATION
#include <boost/serialization/access.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/nvp.hpp>
#endif

namespace gtdynamics {

/**
* A 4-way GaussianProcess prior factor on any Lie group T.
* Implemented similarly to that used in the GPMP2 paper. Each state consists of
* a pose in T and a velocity in the tangent space, separated by delta_t. With
* r = Logmap(Inverse(pose1) * pose2), the error is
* [r - delta_t * vel1; vel2 - vel1].
*/
template <typename T>
class GPLiePrior
: public gtsam::NoiseModelFactorN<T, gtsam::Vector, T, gtsam::Vector> {
private:
GTSAM_CONCEPT_ASSERT(gtsam::IsLieGroup<T>);

using This = GPLiePrior<T>;
using Base = gtsam::NoiseModelFactorN<T, gtsam::Vector, T, gtsam::Vector>;

size_t dof_;
double delta_t_;

public:
/// Default constructor, only for serialization.
GPLiePrior() {}

/**
* Constructor from the keys of the two states.
* @param pose_key1 key for the pose of the first state
* @param vel_key1 key for the velocity of the first state
* @param pose_key2 key for the pose of the second state
* @param vel_key2 key for the velocity of the second state
* @param delta_t time between the two states
* @param Qc_model Gaussian noise model whose covariance is Qc
*/
GPLiePrior(gtsam::Key pose_key1, gtsam::Key vel_key1, gtsam::Key pose_key2,
gtsam::Key vel_key2, double delta_t,
const gtsam::SharedNoiseModel &Qc_model)
: Base(gtsam::noiseModel::Gaussian::Covariance(
calcQAccel(getQc(Qc_model), delta_t)),
pose_key1, vel_key1, pose_key2, vel_key2),
dof_(Qc_model->dim()),
delta_t_(delta_t) {
checkGPDeltaT(delta_t_);
// A mismatched Qc dimension silently mis-sizes the error and Jacobians, so
// reject it up front. Only checkable when T has a fixed dimension.
if (gtsam::traits<T>::dimension != Eigen::Dynamic &&
dof_ != static_cast<size_t>(gtsam::traits<T>::dimension)) {
throw std::invalid_argument(
"GPLiePrior: Qc_model dimension must equal the tangent dimension of "
"the Lie group.");
}
}

~GPLiePrior() override {}

/// Return a deep copy of this factor.
gtsam::NonlinearFactor::shared_ptr clone() const override {
return std::static_pointer_cast<gtsam::NonlinearFactor>(
gtsam::NonlinearFactor::shared_ptr(new This(*this)));
}

/// Evaluate the Gaussian process prior error and its Jacobians.
gtsam::Vector evaluateError(
const T &pose1, const gtsam::Vector &vel1, const T &pose2,
const gtsam::Vector &vel2, gtsam::OptionalMatrixType H1 = nullptr,
gtsam::OptionalMatrixType H2 = nullptr,
gtsam::OptionalMatrixType H3 = nullptr,
gtsam::OptionalMatrixType H4 = nullptr) const override {
// Relative increment between the two poses, in the tangent space.
gtsam::Matrix Hinv, Hcomp1, Hcomp2, Hlogmap;
gtsam::Vector r;
if (H1 || H2 || H3 || H4) {
r = gtsam::traits<T>::Logmap(
gtsam::traits<T>::Compose(gtsam::traits<T>::Inverse(pose1, Hinv),
pose2, Hcomp1, Hcomp2),
Hlogmap);
} else {
r = gtsam::traits<T>::Logmap(
gtsam::traits<T>::Compose(gtsam::traits<T>::Inverse(pose1), pose2));
}

const gtsam::Matrix identity = gtsam::Matrix::Identity(dof_, dof_);
const gtsam::Matrix zero = gtsam::Matrix::Zero(dof_, dof_);

if (H1)
*H1 = (gtsam::Matrix(2 * dof_, dof_) << Hlogmap * Hcomp1 * Hinv, zero)
.finished();
if (H2)
*H2 = (gtsam::Matrix(2 * dof_, dof_) << -delta_t_ * identity, -identity)
.finished();
if (H3)
*H3 =
(gtsam::Matrix(2 * dof_, dof_) << Hlogmap * Hcomp2, zero).finished();
if (H4) *H4 = (gtsam::Matrix(2 * dof_, dof_) << zero, identity).finished();

return (gtsam::Vector(2 * dof_) << (r - vel1 * delta_t_), (vel2 - vel1))
.finished();
}

/// Return the degrees of freedom of a single state.
size_t dof() const { return dof_; }

/// Return the time between the two states.
double deltaT() const { return delta_t_; }

/// Equality up to a tolerance.
bool equals(const gtsam::NonlinearFactor &expected,
double tol = 1e-9) const override {
const This *e = dynamic_cast<const This *>(&expected);
return e != nullptr && Base::equals(*e, tol) &&
std::fabs(this->delta_t_ - e->delta_t_) < tol;
}

/// Print contents.
void print(const std::string &s = "",
const gtsam::KeyFormatter &keyFormatter =
gtsam::DefaultKeyFormatter) const override {
std::cout << s << "4-way Gaussian process prior factor on Lie<" << dof_
<< ">" << std::endl;
Base::print("", keyFormatter);
}

private:
#ifdef GTDYNAMICS_ENABLE_BOOST_SERIALIZATION
/// Serialization function
friend class boost::serialization::access;
template <class ARCHIVE>
void serialize(ARCHIVE &ar, const unsigned int /*version*/) { // NOLINT
ar &boost::serialization::make_nvp(
"NoiseModelFactorN", boost::serialization::base_object<Base>(*this));
ar &BOOST_SERIALIZATION_NVP(dof_);
ar &BOOST_SERIALIZATION_NVP(delta_t_);
}
#endif
}; // \class GPLiePrior

} // namespace gtdynamics
Loading
Loading