blob: 3e2701940c3ce48bd62d690b6400c671bf8b46a3 [file] [log] [blame]
/**********************************************************************************************************************
This file is part of the Control Toolbox (https://adrlab.bitbucket.io/ct), copyright by ETH Zurich, Google Inc.
Authors: Michael Neunert, Markus Giftthaler, Markus Stäuble, Diego Pardo, Farbod Farshidian
Licensed under Apache2 license (see LICENSE file in main directory)
**********************************************************************************************************************/
#include <ct/optcon/optcon.h>
#include <ct/rbd/rbd.h>
#include <ct/models/HyQ/HyQ.h>
#include <ct/models/CodegenOutputDirs.h>
#include "helperFunctions.h"
// shortcut for the auto-diff codegen scalar
typedef CppAD::AD<CppAD::cg::CG<double>> SCALAR;
typedef typename SCALAR::value_type AD_ValueType;
// a floating base forward-dynamic system templated on scalar type
typedef ct::rbd::FloatingBaseFDSystem<ct::rbd::HyQ::tpl::Dynamics<SCALAR>, false> HyQSystemAD;
// extract dimensions
const size_t state_dim = HyQSystemAD::STATE_DIM;
const size_t control_dim = HyQSystemAD::CONTROL_DIM;
// shortcut for number of joints
const size_t njoints = HyQSystemAD::Kinematics::NJOINTS;
void generateInverseDynamics()
{
typedef ct::core::DerivativesCppadCG<state_dim + 18, control_dim + 6> JacCG;
typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqInverseDynamics<SCALAR>;
JacCG jacCG(f);
try
{
std::cout << "Generating Jacobian of Inverse Dynamics wrt state using forward mode... " << std::endl;
jacCG.generateJacobianSource("HyQInverseDynJacForward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), false);
std::cout << "Generating Jacobian of Inverse Dynamics wrt state using reverse mode... " << std::endl;
jacCG.generateJacobianSource("HyQInverseDynJacReverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), true);
} catch (const std::runtime_error& e)
{
std::cout << "inverse dynamics code generation failed: " << e.what() << std::endl;
}
}
void generateForwardKinematics()
{
typedef ct::core::DerivativesCppadCG<state_dim, 4 * 6> JacCG;
typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqForwardKinematics<SCALAR>;
JacCG jacCG(f);
try
{
std::cout << "Generating Jacobian of Forward Kinematics wrt state using forward mode... " << std::endl;
jacCG.generateJacobianSource("HyQForwardKinJacForward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), false);
std::cout << "Generating Jacobian of Forward Kinematics wrt state using reverse mode... " << std::endl;
jacCG.generateJacobianSource("HyQForwardKinJacReverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), true);
} catch (const std::runtime_error& e)
{
std::cout << "forward kinematics code generation failed: " << e.what() << std::endl;
}
}
void generateForwardZeroForwardDynamics()
{
typedef ct::core::DerivativesCppadCG<state_dim + control_dim + 1, state_dim> JacCG;
// Eigen::Matrix<SCALAR, state_dim + control_dim + 1, 1> testInput = Eigen::Matrix<SCALAR, state_dim + control_dim + 1, 1>::Random();
// auto asd = ct::models::HyQ::hyqContactModelForwardDynamics<SCALAR>(testInput);
typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqContactModelForwardDynamics<SCALAR>;
JacCG jacCG(f);
try
{
std::cout << "Generating Forward Zero Code... " << std::endl;
jacCG.generateForwardZeroSource("HyQForwardZero", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", false);
} catch (const std::runtime_error& e)
{
std::cout << "forward zero code generation failed: " << e.what() << std::endl;
}
}
void generateFDLinearization(int argc, char* argv[])
{
std::cout << "Generating Jacobian of Forward Dynamics... " << std::endl;
// a contact model (auto-diff'able)
typedef ct::rbd::EEContactModel<typename HyQSystemAD::Kinematics> ContactModel;
std::shared_ptr<HyQSystemAD> adSystem = std::shared_ptr<HyQSystemAD>(new HyQSystemAD);
// explicitely pass kinematics from the system such that both, contact model and system use
// the same instance to give the AD codegen the opportunity to fully optimize the code
std::shared_ptr<ContactModel> contactModel =
std::shared_ptr<ContactModel>(new ContactModel(SCALAR(5000.0), SCALAR(1000.0), SCALAR(100.0), SCALAR(100.0),
SCALAR(-0.02), ContactModel::VELOCITY_SMOOTHING::SIGMOID, adSystem->dynamics().kinematicsPtr()));
bool useContactModel = (argc <= 2 || !std::string(argv[2]).compare("nocontact") == 0);
std::cout << std::boolalpha << "using contact model: " << useContactModel << std::endl;
// asign the contact model
if (useContactModel)
adSystem->setContactModel(contactModel);
// create the codegen linearizer
ct::core::ADCodegenLinearizer<state_dim, control_dim> adLinearizer(adSystem);
std::string baseName;
if (useContactModel)
baseName = "HyQWithContactModelLinearized";
else
baseName = "HyQBareModelLinearized";
try
{
std::cout << "generating code..." << std::endl;
if (argc > 1 && std::string(argv[1]).compare("reverse") == 0)
{
std::cout << "generating using reverse mode" << std::endl;
adLinearizer.generateCode(baseName + "Reverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", true);
}
else
{
std::cout << "generating using forward mode" << std::endl;
adLinearizer.generateCode(baseName + "Forward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", false);
}
std::cout << "... done!" << std::endl;
} catch (const std::runtime_error& e)
{
std::cout << "forward dynamics code generation failed: " << e.what() << std::endl;
}
}
int main(int argc, char* argv[])
{
generateFDLinearization(argc, argv);
generateInverseDynamics();
generateForwardKinematics();
generateForwardZeroForwardDynamics();
}