/*************************************************************************** * Copyright (c) 2023 Ondsel, Inc. * * * * This file is part of OndselSolver. * * * * See LICENSE file for details about copyright. * ***************************************************************************/ #pragma once #include #include "EulerArray.h" #include "FullMatrix.h" namespace MbD { template class EulerAngles; template class EulerAnglesDDot; template class EulerAnglesDot : public EulerArray { //aEulerAngles cAdot aAdot omeF omef public: EulerAnglesDot() : EulerArray(3) {} std::shared_ptr> differentiateWRT(T var); void calc() override; EulerAngles* aEulerAngles; //Use raw pointer to point backwards FColFMatDsptr cAdot; FMatDsptr aAdot; FColDsptr omeF, omef; }; template inline std::shared_ptr> EulerAnglesDot::differentiateWRT(T var) { auto derivatives = std::make_shared>(); std::transform(this->begin(), this->end(), derivatives->begin(), [var](T term) { return term->differentiateWRT(var); } ); derivatives->aEulerAnglesDot = this; return derivatives; } template inline void EulerAnglesDot::calc() { aEulerAngles->calc(); auto rotOrder = aEulerAngles->rotOrder; auto cA = aEulerAngles->cA; cAdot = std::make_shared>(3); for (int i = 0; i < 3; i++) { auto axis = rotOrder->at(i); auto angle = aEulerAngles->at(i)->getValue(); auto angleDot = this->at(i)->getValue(); if (axis == 1) { cAdot->atiput(i, FullMatrix::rotatexrotDot(angle, angleDot)); } else if (axis == 2) { cAdot->atiput(i, FullMatrix::rotateyrotDot(angle, angleDot)); } else if (axis == 3) { cAdot->atiput(i, FullMatrix::rotatezrotDot(angle, angleDot)); } else { throw std::runtime_error("Euler angle rotation order must be any permutation of 1,2,3 without consecutive repeats."); } } auto phidot = this->at(0)->getValue(); auto thedot = this->at(1)->getValue(); auto psidot = this->at(2)->getValue(); auto phiA = cA->at(0); auto theA = cA->at(1); auto psiA = cA->at(2); auto phiAdot = cAdot->at(0); auto theAdot = cAdot->at(1); auto psiAdot = cAdot->at(2); aAdot = phiAdot->timesFullMatrix(theA->timesFullMatrix(psiA)) ->plusFullMatrix(phiA->timesFullMatrix(theAdot->timesFullMatrix(psiA))) ->plusFullMatrix(phiA->timesFullMatrix(theA->timesFullMatrix(psiAdot))); omeF = (phiA->column(0)->times(phidot) ->plusFullColumn(phiA->timesFullMatrix(theA)->column(1)->times(thedot)) ->plusFullColumn(aEulerAngles->aA->column(2)->times(psidot))); omef = aEulerAngles->aA->transposeTimesFullColumn(omeF); } }