23
23
#include < OpenSpaceToolkit/Physics/Units/Mass.hpp>
24
24
25
25
#include < OpenSpaceToolkit/Mathematics/Geometry/3D/Transformations/Rotations/RotationMatrix.hpp>
26
+ #include < OpenSpaceToolkit/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.hpp>
26
27
27
28
#include < OpenSpaceToolkit/Core/Error.hpp>
28
29
#include < OpenSpaceToolkit/Core/Utilities.hpp>
@@ -371,8 +372,10 @@ Shared<const Frame> Orbit::getOrbitalFrame (
371
372
372
373
using ostk::math::obj::Vector3d ;
373
374
using ostk::math::geom::d3::trf::rot::Quaternion ;
375
+ using ostk::math::geom::d3::trf::rot::RotationVector ;
374
376
using ostk::math::geom::d3::trf::rot::RotationMatrix ;
375
377
378
+ using ostk::physics::time::Duration ;
376
379
using ostk::physics::coord::spherical::LLA ;
377
380
using FrameManager = ostk::physics::coord::frame::Manager ;
378
381
using DynamicProvider = ostk::physics::coord::frame::provider::Dynamic ;
@@ -390,6 +393,42 @@ Shared<const Frame> Orbit::getOrbitalFrame (
390
393
return FrameManager::Get ().accessFrameWithName (frameName) ;
391
394
}
392
395
396
+ const auto generateDynamicProvider = [this ] (const auto & anAttitudeGenerator) -> auto
397
+ {
398
+
399
+ const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
400
+ (
401
+ [this , anAttitudeGenerator] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
402
+ {
403
+
404
+ const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
405
+
406
+ const Vector3d x_GCRF = state.accessPosition ().accessCoordinates () ;
407
+ const Vector3d v_GCRF_in_GCRF = state.accessVelocity ().accessCoordinates () ;
408
+
409
+ const Vector3d x_VVLH_GCRF_in_GCRF = -x_GCRF ; // [m]
410
+ const Vector3d v_VVLH_GCRF_in_GCRF = -v_GCRF_in_GCRF ; // [m/s]
411
+
412
+ const Quaternion q_VVLH_GCRF = anAttitudeGenerator (state) ;
413
+
414
+ const Duration delta = Duration::Seconds (1.0 ) ; // TBM This should be a parameter
415
+
416
+ const Quaternion q_VVLH_next_GCRF = anAttitudeGenerator (this ->getStateAt (anInstant + delta).inFrame (Frame::GCRF ())) ;
417
+
418
+ const Quaternion q_VVLH_next_VVLH = q_VVLH_next_GCRF * q_VVLH_GCRF.toConjugate () ;
419
+ const RotationVector rv_VVLH_next_VVLH = RotationVector::Quaternion (q_VVLH_next_VVLH) ;
420
+
421
+ const Vector3d w_VVLH_GCRF_in_VVLH = rv_VVLH_next_VVLH.getAxis () * (rv_VVLH_next_VVLH.getAngle ().inRadians () / delta.inSeconds ()) ; // [rad/s]
422
+
423
+ return { anInstant, x_VVLH_GCRF_in_GCRF, v_VVLH_GCRF_in_GCRF, q_VVLH_GCRF, w_VVLH_GCRF_in_VVLH, Transform::Type::Passive } ;
424
+
425
+ }
426
+ ) ;
427
+
428
+ return dynamicProviderSPtr ;
429
+
430
+ } ;
431
+
393
432
Shared<const Frame> orbitalFrameSPtr = nullptr ;
394
433
395
434
switch (aFrameType)
@@ -398,32 +437,28 @@ Shared<const Frame> Orbit::getOrbitalFrame (
398
437
case Orbit::FrameType::NED:
399
438
{
400
439
401
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
402
- (
403
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
404
- {
440
+ const auto calculateAttitude = [this ] (const State& aState) -> Quaternion
441
+ {
405
442
406
- // Get state in central body centered, central body fixed frame
443
+ // Get state in central body centered, central body fixed frame
407
444
408
- const State state = this ->getStateAt (anInstant ).inFrame (celestialObjectSPtr_->accessFrame ()) ;
445
+ const State state = this ->getStateAt (aState. getInstant () ).inFrame (celestialObjectSPtr_->accessFrame ()) ;
409
446
410
- // Express the state position in geodetic coordinates
447
+ // Express the state position in geodetic coordinates
411
448
412
- const LLA lla = LLA::Cartesian (state.accessPosition ().accessCoordinates (), celestialObjectSPtr_->getEquatorialRadius (), celestialObjectSPtr_->getFlattening ()) ;
449
+ const LLA lla = LLA::Cartesian (state.accessPosition ().accessCoordinates (), celestialObjectSPtr_->getEquatorialRadius (), celestialObjectSPtr_->getFlattening ()) ;
413
450
414
- // Compute the NED frame to central body centered, central body fixed frame transform at position
451
+ // Compute the NED frame to central body centered, central body fixed frame transform at position
415
452
416
- const Transform transform = ostk::physics::coord::frame::utilities::NorthEastDownTransformAt (lla, celestialObjectSPtr_->getEquatorialRadius (), celestialObjectSPtr_->getFlattening ()) ; // [TBM] This should be optimized: LLA <> ECEF calculation done twice
453
+ const Transform transform = ostk::physics::coord::frame::utilities::NorthEastDownTransformAt (lla, celestialObjectSPtr_->getEquatorialRadius (), celestialObjectSPtr_->getFlattening ()) ; // [TBM] This should be optimized: LLA <> ECEF calculation done twice
417
454
418
- const Vector3d velocity = - state.accessVelocity ().accessCoordinates () ; // [TBM] Check if derivation frame is correct
419
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
455
+ const Quaternion q_NED_GCRF = transform.getOrientation () ;
420
456
421
- return { anInstant, transform. getTranslation (), velocity, transform. getOrientation (), angularVelocity, Transform::Type::Passive } ;
457
+ return q_NED_GCRF ;
422
458
423
- }
424
- ) ;
459
+ } ;
425
460
426
- orbitalFrameSPtr = Frame::Construct (frameName, false , celestialObjectSPtr_-> accessFrame (), dynamicProviderSPtr ) ;
461
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude) ) ;
427
462
428
463
break ;
429
464
@@ -436,31 +471,23 @@ Shared<const Frame> Orbit::getOrbitalFrame (
436
471
// Z axis along orbital momentum
437
472
// Y axis toward velocity vector
438
473
439
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
440
- (
441
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
442
- {
443
-
444
- const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
445
-
446
- const Vector3d x_GCRF = state.accessPosition ().accessCoordinates () ;
447
- const Vector3d v_GCRF = state.accessVelocity ().accessCoordinates () ;
474
+ const auto calculateAttitude = [] (const State& aState) -> Quaternion
475
+ {
448
476
449
- const Vector3d xAxis = x_GCRF.normalized () ;
450
- const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
451
- const Vector3d yAxis = zAxis.cross (xAxis) ;
477
+ const Vector3d x_GCRF = aState.accessPosition ().accessCoordinates () ;
478
+ const Vector3d v_GCRF = aState.accessVelocity ().accessCoordinates () ;
452
479
453
- const Quaternion q_LVLH_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
480
+ const Vector3d xAxis = x_GCRF.normalized () ;
481
+ const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
482
+ const Vector3d yAxis = zAxis.cross (xAxis) ;
454
483
455
- const Vector3d velocity = -v_GCRF ;
456
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
484
+ const Quaternion q_LVLH_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
457
485
458
- return { anInstant, -x_GCRF, velocity, q_LVLH_GCRF, angularVelocity, Transform::Type::Passive } ;
486
+ return q_LVLH_GCRF ;
459
487
460
- }
461
- ) ;
488
+ } ;
462
489
463
- orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), dynamicProviderSPtr ) ;
490
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude) ) ;
464
491
465
492
break ;
466
493
@@ -473,31 +500,23 @@ Shared<const Frame> Orbit::getOrbitalFrame (
473
500
// Y axis along negative orbital momentum
474
501
// X axis toward velocity vector
475
502
476
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
477
- (
478
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
479
- {
480
-
481
- const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
482
-
483
- const Vector3d x_GCRF = state.accessPosition ().accessCoordinates () ;
484
- const Vector3d v_GCRF = state.accessVelocity ().accessCoordinates () ;
503
+ const auto calculateAttitude = [] (const State& aState) -> Quaternion
504
+ {
485
505
486
- const Vector3d zAxis = -x_GCRF.normalized () ;
487
- const Vector3d yAxis = -x_GCRF.cross (v_GCRF).normalized () ;
488
- const Vector3d xAxis = yAxis.cross (zAxis) ;
506
+ const Vector3d x_GCRF = aState.accessPosition ().accessCoordinates () ;
507
+ const Vector3d v_GCRF = aState.accessVelocity ().accessCoordinates () ;
489
508
490
- const Quaternion q_VVLH_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
509
+ const Vector3d zAxis = -x_GCRF.normalized () ;
510
+ const Vector3d yAxis = -x_GCRF.cross (v_GCRF).normalized () ;
511
+ const Vector3d xAxis = yAxis.cross (zAxis) ;
491
512
492
- const Vector3d velocity = -v_GCRF ;
493
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
513
+ const Quaternion q_VVLH_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
494
514
495
- return { anInstant, -x_GCRF, velocity, q_VVLH_GCRF, angularVelocity, Transform::Type::Passive } ;
515
+ return q_VVLH_GCRF ;
496
516
497
- }
498
- ) ;
517
+ } ;
499
518
500
- orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), dynamicProviderSPtr ) ;
519
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude) ) ;
501
520
502
521
break ;
503
522
@@ -509,31 +528,23 @@ Shared<const Frame> Orbit::getOrbitalFrame (
509
528
// X axis along position vector
510
529
// Z axis along orbital momentum
511
530
512
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
513
- (
514
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
515
- {
516
-
517
- const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
531
+ const auto calculateAttitude = [] (const State& aState) -> Quaternion
532
+ {
518
533
519
- const Vector3d x_GCRF = state .accessPosition ().accessCoordinates () ;
520
- const Vector3d v_GCRF = state .accessVelocity ().accessCoordinates () ;
534
+ const Vector3d x_GCRF = aState .accessPosition ().accessCoordinates () ;
535
+ const Vector3d v_GCRF = aState .accessVelocity ().accessCoordinates () ;
521
536
522
- const Vector3d xAxis = x_GCRF.normalized () ;
523
- const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
524
- const Vector3d yAxis = zAxis.cross (xAxis) ;
537
+ const Vector3d xAxis = x_GCRF.normalized () ;
538
+ const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
539
+ const Vector3d yAxis = zAxis.cross (xAxis) ;
525
540
526
- const Quaternion q_QSW_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
541
+ const Quaternion q_QSW_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
527
542
528
- const Vector3d velocity = -v_GCRF ;
529
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
543
+ return q_QSW_GCRF ;
530
544
531
- return { anInstant, -x_GCRF, velocity, q_QSW_GCRF, angularVelocity, Transform::Type::Passive } ;
545
+ } ;
532
546
533
- }
534
- ) ;
535
-
536
- orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), dynamicProviderSPtr) ;
547
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude)) ;
537
548
538
549
break ;
539
550
@@ -545,31 +556,23 @@ Shared<const Frame> Orbit::getOrbitalFrame (
545
556
// X axis along velocity vector
546
557
// Z axis along orbital momentum
547
558
548
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
549
- (
550
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
551
- {
552
-
553
- const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
554
-
555
- const Vector3d x_GCRF = state.accessPosition ().accessCoordinates () ;
556
- const Vector3d v_GCRF = state.accessVelocity ().accessCoordinates () ;
559
+ const auto calculateAttitude = [] (const State& aState) -> Quaternion
560
+ {
557
561
558
- const Vector3d xAxis = v_GCRF.normalized () ;
559
- const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
560
- const Vector3d yAxis = zAxis.cross (xAxis) ;
562
+ const Vector3d x_GCRF = aState.accessPosition ().accessCoordinates () ;
563
+ const Vector3d v_GCRF = aState.accessVelocity ().accessCoordinates () ;
561
564
562
- const Quaternion q_TNW_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
565
+ const Vector3d xAxis = v_GCRF.normalized () ;
566
+ const Vector3d zAxis = x_GCRF.cross (v_GCRF).normalized () ;
567
+ const Vector3d yAxis = zAxis.cross (xAxis) ;
563
568
564
- const Vector3d velocity = -v_GCRF ;
565
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
569
+ const Quaternion q_TNW_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
566
570
567
- return { anInstant, -x_GCRF, velocity, q_TNW_GCRF, angularVelocity, Transform::Type::Passive } ;
571
+ return q_TNW_GCRF ;
568
572
569
- }
570
- ) ;
573
+ } ;
571
574
572
- orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), dynamicProviderSPtr ) ;
575
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude) ) ;
573
576
574
577
break ;
575
578
@@ -581,31 +584,23 @@ Shared<const Frame> Orbit::getOrbitalFrame (
581
584
// X axis along velocity vector
582
585
// Y axis along orbital momentum
583
586
584
- const Shared<const DynamicProvider> dynamicProviderSPtr = std::make_shared<const DynamicProvider>
585
- (
586
- [this ] (const Instant& anInstant) -> Transform // [TBI] Use shared_from_this instead
587
- {
588
-
589
- const State state = this ->getStateAt (anInstant).inFrame (Frame::GCRF ()) ;
590
-
591
- const Vector3d x_GCRF = state.accessPosition ().accessCoordinates () ;
592
- const Vector3d v_GCRF = state.accessVelocity ().accessCoordinates () ;
587
+ const auto calculateAttitude = [] (const State& aState) -> Quaternion
588
+ {
593
589
594
- const Vector3d xAxis = v_GCRF.normalized () ;
595
- const Vector3d yAxis = x_GCRF.cross (v_GCRF).normalized () ;
596
- const Vector3d zAxis = xAxis.cross (yAxis) ;
590
+ const Vector3d x_GCRF = aState.accessPosition ().accessCoordinates () ;
591
+ const Vector3d v_GCRF = aState.accessVelocity ().accessCoordinates () ;
597
592
598
- const Quaternion q_VNC_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
593
+ const Vector3d xAxis = v_GCRF.normalized () ;
594
+ const Vector3d yAxis = x_GCRF.cross (v_GCRF).normalized () ;
595
+ const Vector3d zAxis = xAxis.cross (yAxis) ;
599
596
600
- const Vector3d velocity = -v_GCRF ;
601
- const Vector3d angularVelocity = { 0.0 , 0.0 , 0.0 } ; // [TBI] Use orbital angular velocity
597
+ const Quaternion q_VNC_GCRF = Quaternion::RotationMatrix (RotationMatrix::Rows (xAxis, yAxis, zAxis)).rectify () ;
602
598
603
- return { anInstant, -x_GCRF, velocity, q_VNC_GCRF, angularVelocity, Transform::Type::Passive } ;
599
+ return q_VNC_GCRF ;
604
600
605
- }
606
- ) ;
601
+ } ;
607
602
608
- orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), dynamicProviderSPtr ) ;
603
+ orbitalFrameSPtr = Frame::Construct (frameName, false , Frame::GCRF (), generateDynamicProvider (calculateAttitude) ) ;
609
604
610
605
break ;
611
606
0 commit comments