blob: 3e2701940c3ce48bd62d690b6400c671bf8b46a3 [file] [log] [blame]
Austin Schuh7400da02018-01-28 19:54:58 -08001/**********************************************************************************************************************
2This file is part of the Control Toolbox (https://adrlab.bitbucket.io/ct), copyright by ETH Zurich, Google Inc.
3Authors: Michael Neunert, Markus Giftthaler, Markus Stäuble, Diego Pardo, Farbod Farshidian
4Licensed under Apache2 license (see LICENSE file in main directory)
5**********************************************************************************************************************/
6
7#include <ct/optcon/optcon.h>
8#include <ct/rbd/rbd.h>
9#include <ct/models/HyQ/HyQ.h>
10#include <ct/models/CodegenOutputDirs.h>
11
12#include "helperFunctions.h"
13
14// shortcut for the auto-diff codegen scalar
15typedef CppAD::AD<CppAD::cg::CG<double>> SCALAR;
16typedef typename SCALAR::value_type AD_ValueType;
17
18// a floating base forward-dynamic system templated on scalar type
19typedef ct::rbd::FloatingBaseFDSystem<ct::rbd::HyQ::tpl::Dynamics<SCALAR>, false> HyQSystemAD;
20
21// extract dimensions
22const size_t state_dim = HyQSystemAD::STATE_DIM;
23const size_t control_dim = HyQSystemAD::CONTROL_DIM;
24
25// shortcut for number of joints
26const size_t njoints = HyQSystemAD::Kinematics::NJOINTS;
27
28
29void generateInverseDynamics()
30{
31 typedef ct::core::DerivativesCppadCG<state_dim + 18, control_dim + 6> JacCG;
32 typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqInverseDynamics<SCALAR>;
33 JacCG jacCG(f);
34
35 try
36 {
37 std::cout << "Generating Jacobian of Inverse Dynamics wrt state using forward mode... " << std::endl;
38 jacCG.generateJacobianSource("HyQInverseDynJacForward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
39 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), false);
40
41 std::cout << "Generating Jacobian of Inverse Dynamics wrt state using reverse mode... " << std::endl;
42 jacCG.generateJacobianSource("HyQInverseDynJacReverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
43 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), true);
44 } catch (const std::runtime_error& e)
45 {
46 std::cout << "inverse dynamics code generation failed: " << e.what() << std::endl;
47 }
48}
49
50void generateForwardKinematics()
51{
52 typedef ct::core::DerivativesCppadCG<state_dim, 4 * 6> JacCG;
53 typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqForwardKinematics<SCALAR>;
54 JacCG jacCG(f);
55
56 try
57 {
58 std::cout << "Generating Jacobian of Forward Kinematics wrt state using forward mode... " << std::endl;
59 jacCG.generateJacobianSource("HyQForwardKinJacForward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
60 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), false);
61
62 std::cout << "Generating Jacobian of Forward Kinematics wrt state using reverse mode... " << std::endl;
63 jacCG.generateJacobianSource("HyQForwardKinJacReverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
64 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", JacCG::Sparsity::Ones(), true);
65 } catch (const std::runtime_error& e)
66 {
67 std::cout << "forward kinematics code generation failed: " << e.what() << std::endl;
68 }
69}
70
71void generateForwardZeroForwardDynamics()
72{
73 typedef ct::core::DerivativesCppadCG<state_dim + control_dim + 1, state_dim> JacCG;
74 // Eigen::Matrix<SCALAR, state_dim + control_dim + 1, 1> testInput = Eigen::Matrix<SCALAR, state_dim + control_dim + 1, 1>::Random();
75 // auto asd = ct::models::HyQ::hyqContactModelForwardDynamics<SCALAR>(testInput);
76 typename JacCG::FUN_TYPE_CG f = ct::models::HyQ::hyqContactModelForwardDynamics<SCALAR>;
77 JacCG jacCG(f);
78
79 try
80 {
81 std::cout << "Generating Forward Zero Code... " << std::endl;
82 jacCG.generateForwardZeroSource("HyQForwardZero", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
83 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", false);
84 } catch (const std::runtime_error& e)
85 {
86 std::cout << "forward zero code generation failed: " << e.what() << std::endl;
87 }
88}
89
90
91void generateFDLinearization(int argc, char* argv[])
92{
93 std::cout << "Generating Jacobian of Forward Dynamics... " << std::endl;
94
95 // a contact model (auto-diff'able)
96 typedef ct::rbd::EEContactModel<typename HyQSystemAD::Kinematics> ContactModel;
97
98 std::shared_ptr<HyQSystemAD> adSystem = std::shared_ptr<HyQSystemAD>(new HyQSystemAD);
99
100 // explicitely pass kinematics from the system such that both, contact model and system use
101 // the same instance to give the AD codegen the opportunity to fully optimize the code
102 std::shared_ptr<ContactModel> contactModel =
103 std::shared_ptr<ContactModel>(new ContactModel(SCALAR(5000.0), SCALAR(1000.0), SCALAR(100.0), SCALAR(100.0),
104 SCALAR(-0.02), ContactModel::VELOCITY_SMOOTHING::SIGMOID, adSystem->dynamics().kinematicsPtr()));
105
106 bool useContactModel = (argc <= 2 || !std::string(argv[2]).compare("nocontact") == 0);
107 std::cout << std::boolalpha << "using contact model: " << useContactModel << std::endl;
108
109 // asign the contact model
110 if (useContactModel)
111 adSystem->setContactModel(contactModel);
112
113 // create the codegen linearizer
114 ct::core::ADCodegenLinearizer<state_dim, control_dim> adLinearizer(adSystem);
115
116 std::string baseName;
117 if (useContactModel)
118 baseName = "HyQWithContactModelLinearized";
119 else
120 baseName = "HyQBareModelLinearized";
121
122 try
123 {
124 std::cout << "generating code..." << std::endl;
125 if (argc > 1 && std::string(argv[1]).compare("reverse") == 0)
126 {
127 std::cout << "generating using reverse mode" << std::endl;
128
129 adLinearizer.generateCode(baseName + "Reverse", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
130 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", true);
131 }
132 else
133 {
134 std::cout << "generating using forward mode" << std::endl;
135
136 adLinearizer.generateCode(baseName + "Forward", ct::models::HYQ_CODEGEN_OUTPUT_DIR,
137 ct::core::CODEGEN_TEMPLATE_DIR, "models", "HyQ", false);
138 }
139
140 std::cout << "... done!" << std::endl;
141 } catch (const std::runtime_error& e)
142 {
143 std::cout << "forward dynamics code generation failed: " << e.what() << std::endl;
144 }
145}
146
147
148int main(int argc, char* argv[])
149{
150 generateFDLinearization(argc, argv);
151 generateInverseDynamics();
152 generateForwardKinematics();
153 generateForwardZeroForwardDynamics();
154}