5 #ifndef LODESTAR_SIMPLEPIDBLOCK_HPP
6 #define LODESTAR_SIMPLEPIDBLOCK_HPP
9 #include "Lodestar/blocks/Block.hpp"
10 #include "Lodestar/aux/CompileTimeQualifiers.hpp"
11 #include "Eigen/Dense"
16 enum class SimplePIDBlockOperator {
21 enum class SimplePIDBlockParameter {
26 template<
typename TType,
27 SimplePIDBlockOperator TOps = SimplePIDBlockOperator::Scalar,
28 SimplePIDBlockParameter TPar = SimplePIDBlockParameter::Parametric>
30 static_assert(!::std::is_same<TType, TType>::value,
31 "SimplePIDBlock not defined for this type.");
34 template<
typename TType, SimplePIDBlockOperator TOps>
38 SimplePIDBlockParameter::Parametric
43 ::std::tuple<TType, TType, TType, TType>
50 SimplePIDBlockParameter::Parametric
57 ::std::tuple<TType, TType, TType, TType>
67 return this->
template p<0>();
70 TType &pGain(
const TType Kp)
72 this->
template p<0>() = Kp;
73 return this->
template p<0>();
78 return this->
template p<0>();
83 return this->
template p<1>();
86 TType &iGain(
const TType Ki)
88 this->
template p<1>() = Ki;
89 return this->
template p<1>();
94 return this->
template p<1>();
99 return this->
template p<2>();
102 TType &dGain(
const TType Kd)
104 this->
template p<2>() = Kd;
105 return this->
template p<2>();
110 return this->
template p<2>();
113 TType &samplingPeriod()
115 return this->
template p<3>();
118 TType &samplingPeriod(
const TType t)
120 this->
template p<3>() = t;
121 return this->
template p<3>();
124 TType samplingPeriod()
const
126 return this->
template p<3>();
132 this->equation = ::std::bind(
133 &type::triggerFunction,
135 ::std::placeholders::_1
139 TType pid(
const TType x)
const
141 static TType lastX = 0;
142 static TType intX = 0;
144 TType res = pGain() * x + iGain() * intX + dGain() * (x - lastX)/samplingPeriod();
146 intX += x * samplingPeriod();
152 void triggerFunction(
Base &b)
154 b.template o<0>() = pid(b.template i<0>().object);
158 template<
typename TType, SimplePIDBlockOperator TOps>
162 SimplePIDBlockParameter::AdditionalInput
165 ::std::tuple<TType, TType, TType, TType>,
174 SimplePIDBlockParameter::AdditionalInput
179 ::std::tuple<TType, TType, TType, TType>,
191 return this->
template i<1>();
196 this->
template i<1>() = Kp;
197 return this->
template i<1>();
202 this->
template i<1>() = Kp;
203 return this->
template i<1>();
208 return this->
template i<1>();
213 return this->
template i<2>();
218 this->
template i<2>() = Ki;
219 return this->
template i<2>();
224 this->
template i<2>() = Ki;
225 return this->
template i<2>();
230 return this->
template i<2>();
235 return this->
template i<3>();
240 this->
template i<3>() = Kd;
241 return this->
template i<3>();
246 this->
template i<3>() = Kd;
247 return this->
template i<3>();
252 return this->
template i<3>();
255 TType &samplingPeriod()
257 return this->
template p<0>();
260 TType &samplingPeriod(
const TType t)
262 this->
template p<0>() = t;
263 return this->
template p<0>();
266 TType samplingPeriod()
const
268 return this->
template p<0>();
273 this->equation = ::std::bind(
274 &type::triggerFunction,
276 ::std::placeholders::_1
280 TType pid(
const TType x)
const
282 static TType lastX = 0;
283 static TType intX = 0;
285 TType res = pGain() * x + iGain() * intX + dGain() * (x - lastX)/samplingPeriod();
287 intX += x * samplingPeriod();
293 void triggerFunction(
Base &b)
295 b.template o<0>() = pid(b.template i<0>().object);
299 template<
typename TScalar,
int TRows,
int TCols>
301 Eigen::Matrix<TScalar, TRows, TCols>,
302 SimplePIDBlockOperator::Scalar,
303 SimplePIDBlockParameter::Parametric
306 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
307 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
308 ::std::tuple<TScalar, TScalar, TScalar, TScalar>
313 Eigen::Matrix<TScalar, TRows, TCols>,
314 SimplePIDBlockOperator::Scalar,
315 SimplePIDBlockParameter::Parametric
320 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
321 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
322 ::std::tuple<TScalar, TScalar, TScalar, TScalar>
332 return this->
template p<0>();
335 TScalar &pGain(
const TScalar Kp)
337 this->
template p<0>() = Kp;
338 return this->
template p<0>();
341 TScalar pGain()
const
343 return this->
template p<0>();
348 return this->
template p<1>();
351 TScalar &iGain(
const TScalar Ki)
353 this->
template p<1>() = Ki;
354 return this->
template p<1>();
357 TScalar iGain()
const
359 return this->
template p<1>();
364 return this->
template p<2>();
367 TScalar &dGain(
const TScalar Kd)
369 this->
template p<2>() = Kd;
370 return this->
template p<2>();
373 TScalar dGain()
const
375 return this->
template p<2>();
378 TScalar &samplingPeriod()
380 return this->
template p<3>();
383 TScalar &samplingPeriod(
const TScalar t)
385 this->
template p<3>() = t;
386 return this->
template p<3>();
389 TScalar samplingPeriod()
const
391 return this->
template p<3>();
397 this->equation = ::std::bind(
398 &type::triggerFunction,
400 ::std::placeholders::_1
404 Eigen::Matrix<TScalar, TRows, TCols> pid(Eigen::Matrix<TScalar, TRows, TCols> &x)
const
406 static Eigen::Matrix<TScalar, TRows, TCols> lastX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
407 static Eigen::Matrix<TScalar, TRows, TCols> intX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
409 Eigen::Matrix<TScalar, TRows, TCols> res = pGain() * x + iGain() * intX + dGain() * (x - lastX)/samplingPeriod();
411 intX += samplingPeriod() * x;
417 void triggerFunction(
Base &b)
419 b.template o<0>() = pid(b.template i<0>().object);
423 template<
typename TScalar,
int TRows,
int TCols>
425 Eigen::Matrix<TScalar, TRows, TCols>,
426 SimplePIDBlockOperator::Scalar,
427 SimplePIDBlockParameter::AdditionalInput
430 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, TScalar, TScalar, TScalar>,
431 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
432 ::std::tuple<TScalar>
437 Eigen::Matrix<TScalar, TRows, TCols>,
438 SimplePIDBlockOperator::Scalar,
439 SimplePIDBlockParameter::AdditionalInput
444 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, TScalar, TScalar, TScalar>,
445 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
446 ::std::tuple<TScalar>
456 return this->
template i<1>();
461 this->
template i<1>() = Kp;
462 return this->
template i<1>();
467 this->
template i<1>() = Kp;
468 return this->
template i<1>();
473 return this->
template i<1>();
478 return this->
template i<2>();
483 this->
template i<2>() = Ki;
484 return this->
template i<2>();
489 this->
template i<2>() = Ki;
490 return this->
template i<2>();
495 return this->
template i<2>();
500 return this->
template i<3>();
505 this->
template i<3>() = Kd;
506 return this->
template i<3>();
511 this->
template i<3>() = Kd;
512 return this->
template i<3>();
517 return this->
template i<3>();
520 TScalar &samplingPeriod()
522 return this->
template p<0>();
525 TScalar &samplingPeriod(
const TScalar t)
527 this->
template p<0>() = t;
528 return this->
template p<0>();
531 TScalar samplingPeriod()
const
533 return this->
template p<0>();
539 this->equation = ::std::bind(
540 &type::triggerFunction,
542 ::std::placeholders::_1
546 void triggerFunction(
Base &b)
548 b.template o<0>() = pid(b.template i<0>().object);
551 Eigen::Matrix<TScalar, TRows, TCols> pid(Eigen::Matrix<TScalar, TRows, TCols> &x)
const
553 static Eigen::Matrix<TScalar, TRows, TCols> lastX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
554 static Eigen::Matrix<TScalar, TRows, TCols> intX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
556 Eigen::Matrix<TScalar, TRows, TCols> res = pGain() * x + iGain() * intX + dGain() * (x - lastX)/samplingPeriod();
558 intX += samplingPeriod() * x;
565 template<
typename TScalar,
int TRows,
int TCols>
567 Eigen::Matrix<TScalar, TRows, TCols>,
568 SimplePIDBlockOperator::Elementwise,
569 SimplePIDBlockParameter::Parametric
572 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
573 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
574 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, TScalar>
579 Eigen::Matrix<TScalar, TRows, TCols>,
580 SimplePIDBlockOperator::Elementwise,
581 SimplePIDBlockParameter::Parametric
586 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
587 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
588 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, TScalar>
591 using GainMatrix = Eigen::Matrix<TScalar, TRows, TCols>;
600 return this->
template p<0>();
603 GainMatrix &pGain(
const GainMatrix &Kp)
605 this->
template p<0>() = Kp;
606 return this->
template p<0>();
609 GainMatrix pGain()
const
611 return this->
template p<0>();
616 return this->
template p<1>();
619 GainMatrix &iGain(
const GainMatrix &Ki)
621 this->
template p<1>() = Ki;
622 return this->
template p<1>();
625 GainMatrix iGain()
const
627 return this->
template p<1>();
632 return this->
template p<2>();
635 GainMatrix &dGain(
const GainMatrix &Kd)
637 this->
template p<2>() = Kd;
638 return this->
template p<2>();
641 GainMatrix dGain()
const
643 return this->
template p<2>();
646 TScalar &samplingPeriod()
648 return this->
template p<3>();
651 TScalar &samplingPeriod(
const TScalar t)
653 this->
template p<3>() = t;
654 return this->
template p<3>();
657 TScalar samplingPeriod()
const
659 return this->
template p<3>();
665 this->equation = ::std::bind(
666 &type::triggerFunction,
668 ::std::placeholders::_1
672 Eigen::Matrix<TScalar, TRows, TCols> pid(Eigen::Matrix<TScalar, TRows, TCols> &x)
const
674 static Eigen::Matrix<TScalar, TRows, TCols> lastX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
675 static Eigen::Matrix<TScalar, TRows, TCols> intX = Eigen::Matrix<TScalar, TRows, TCols>::Zero();
677 Eigen::Matrix<TScalar, TRows, TCols> res = pGain().array() * x.array() + iGain().array() * intX.array() + dGain().array() * ((x - lastX)/samplingPeriod()).array();
679 intX += samplingPeriod() * x;
685 void triggerFunction(
Base &b)
687 b.template o<0>() = pid(b.template i<0>().object);
691 template<
typename TScalar,
int TRows,
int TCols>
693 Eigen::Matrix<TScalar, TRows, TCols>,
694 SimplePIDBlockOperator::Elementwise,
695 SimplePIDBlockParameter::AdditionalInput
698 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>>,
699 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
700 ::std::tuple<TScalar>
705 Eigen::Matrix<TScalar, TRows, TCols>,
706 SimplePIDBlockOperator::Elementwise,
707 SimplePIDBlockParameter::AdditionalInput
712 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>, Eigen::Matrix<TScalar, TRows, TCols>>,
713 ::std::tuple<Eigen::Matrix<TScalar, TRows, TCols>>,
714 ::std::tuple<TScalar>
717 using GainMatrix = Eigen::Matrix<TScalar, TRows, TCols>;
726 return this->
template i<1>();
731 this->
template i<1>() = Kp;
732 return this->
template i<1>();
737 this->
template i<1>() = Kp;
738 return this->
template i<1>();
743 return this->
template i<1>();
748 return this->
template i<2>();
753 this->
template i<2>() = Ki;
754 return this->
template i<2>();
759 this->
template i<2>() = Ki;
760 return this->
template i<2>();
765 return this->
template i<2>();
770 return this->
template i<3>();
775 this->
template i<3>() = Kd;
776 return this->
template i<3>();
781 this->
template i<3>() = Kd;
782 return this->
template i<3>();
787 return this->
template i<3>();
790 TScalar &samplingPeriod()
792 return this->
template p<0>();
795 TScalar &samplingPeriod(
const TScalar t)
797 this->
template p<0>() = t;
798 return this->
template p<0>();
801 TScalar samplingPeriod()
const
803 return this->
template p<0>();
809 this->equation = ::std::bind(
810 &type::triggerFunction,
812 ::std::placeholders::_1
816 Eigen::Matrix<TScalar, TRows, TCols> pid(Eigen::Matrix<TScalar, TRows, TCols> &x)
const
818 static Eigen::Matrix<TScalar, TRows, TCols> lastX{};
819 static Eigen::Matrix<TScalar, TRows, TCols> intX{};
821 Eigen::Matrix<TScalar, TRows, TCols> res = pGain().object.array() * x.array() + iGain().object.array() * intX.array() + dGain().object.array() * ((x - lastX)/samplingPeriod()).array();
823 intX += samplingPeriod() * x;
829 void triggerFunction(
Base &b)
831 b.template o<0>() = pid(b.template i<0>().object);
835 template<
typename TType, SimplePIDBlockOperator TOps>
840 template<
typename TType>
845 directFeedthrough =
true
849 using Base =
typename type::Base;
857 static const ::std::array<::std::string, kIns> inTypes;
858 static const ::std::array<::std::string, kOuts> outTypes;
859 static const ::std::array<::std::string, kPars> parTypes;
861 static const ::std::array<::std::string, 3> templateTypes;
864 template<
typename TType>
865 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::kIns>
867 {demangle(
typeid(TType).name())};
869 template<
typename TType>
870 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::kOuts>
871 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::outTypes =
872 {demangle(
typeid(TType).name())};
874 template<
typename TType>
875 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::kPars>
876 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::parTypes =
877 {demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name())};
879 template<
typename TType>
880 const ::std::array<::std::string, 3>
881 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::Parametric>>::templateTypes =
882 {demangle(
typeid(TType).name()), demangle(
typeid(std::SimplePIDBlockOperator).name()), demangle(
typeid(std::SimplePIDBlockParameter).name())};
884 template<
typename TType>
893 using Base =
typename type::Base;
901 static const ::std::array<::std::string, kIns>
inTypes;
902 static const ::std::array<::std::string, kOuts>
outTypes;
903 static const ::std::array<::std::string, kPars>
parTypes;
908 template<
typename TType>
909 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::kIns>
911 {demangle(
typeid(TType).name())};
913 template<
typename TType>
914 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::kOuts>
915 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::outTypes =
916 {demangle(
typeid(TType).name())};
918 template<
typename TType>
919 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::kPars>
920 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::parTypes =
921 {demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name())};
923 template<
typename TType>
924 const ::std::array<::std::string, 3>
925 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::Parametric>>::templateTypes =
926 {demangle(
typeid(TType).name()), demangle(
typeid(std::SimplePIDBlockOperator).name()), demangle(
typeid(std::SimplePIDBlockParameter).name())};
928 template<
typename TType>
937 using Base =
typename type::Base;
945 static const ::std::array<::std::string, kIns>
inTypes;
946 static const ::std::array<::std::string, kOuts>
outTypes;
947 static const ::std::array<::std::string, kPars>
parTypes;
952 template<
typename TType>
953 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::kIns>
955 {demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name())};
957 template<
typename TType>
958 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::kOuts>
959 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::outTypes =
960 {demangle(
typeid(TType).name())};
962 template<
typename TType>
963 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::kPars>
964 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::parTypes =
965 {demangle(
typeid(TType).name())};
967 template<
typename TType>
968 const ::std::array<::std::string, 3>
969 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Scalar, std::SimplePIDBlockParameter::AdditionalInput>>::templateTypes =
970 {demangle(
typeid(TType).name()), demangle(
typeid(std::SimplePIDBlockOperator).name()), demangle(
typeid(std::SimplePIDBlockParameter).name())};
972 template<
typename TType>
973 class BlockTraits<std::
SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>> {
981 using Base =
typename type::Base;
989 static const ::std::array<::std::string, kIns>
inTypes;
990 static const ::std::array<::std::string, kOuts>
outTypes;
991 static const ::std::array<::std::string, kPars>
parTypes;
996 template<
typename TType>
997 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::kIns>
999 {demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name()), demangle(
typeid(TType).name())};
1001 template<
typename TType>
1002 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::kOuts>
1003 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::outTypes =
1004 {demangle(
typeid(TType).name())};
1006 template<
typename TType>
1007 const ::std::array<::std::string, BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::kPars>
1008 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::parTypes =
1009 {demangle(
typeid(TType).name())};
1011 template<
typename TType>
1012 const ::std::array<::std::string, 3>
1013 BlockTraits<std::SimplePIDBlock<TType, std::SimplePIDBlockOperator::Elementwise, std::SimplePIDBlockParameter::AdditionalInput>>::templateTypes =
1014 {demangle(
typeid(TType).name()), demangle(
typeid(std::SimplePIDBlockOperator).name()), demangle(
typeid(std::SimplePIDBlockParameter).name())};
1018 #endif //LODESTAR_SIMPLEPIDBLOCK_HPP