kiam-astro 2.0.4__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kiam_astro/trajectory.py CHANGED
@@ -19,6 +19,8 @@ import numpy
19
19
  import networkx as nx
20
20
  import math
21
21
  import copy
22
+ from numpy.linalg import norm
23
+ import warnings
22
24
 
23
25
  variables_all = {'rv', 'rvm', 'rv_stm',
24
26
  'ee', 'eem', 'ee_stm',
@@ -26,7 +28,18 @@ variables_all = {'rv', 'rvm', 'rv_stm',
26
28
 
27
29
  systems_ephemeris = {'itrs', 'gcrs', 'gsrf_em', 'gsrf_se', # Earth-cent. systems
28
30
  'scrs', 'ssrf_em', 'mer', 'sors', # Moon-cent. systems
29
- 'hcrs', 'hsrf_se'} # Sun-cent. systems
31
+ 'hcrs', 'hsrf_se', # Sun-cent. systems
32
+ 'hsrf_smer', 'hsrf_sv', # Sun-cent. systems
33
+ 'hsrf_sm', 'hsrf_sj', # Sun-cent. systems
34
+ 'hsrf_ssat', 'hsrf_su', # Sun-cent. systems
35
+ 'hsrf_sn', # Sun-cent. systems
36
+ 'mercrs', 'mersrf_smer', # Mercury-cent. systems
37
+ 'vcrs', 'vsrf_sv', # Venus-cent. systems
38
+ 'mcrs', 'msrf_sm', # Mars-cent. systems
39
+ 'jcrs', 'jsrf_sj', # Jupiter-cent. systems
40
+ 'satcrs', 'satsrf_ssat', # Saturn-cent. systems
41
+ 'ucrs', 'usrf_su', # Uranus-cent. systems
42
+ 'ncrs', 'nsrf_sn'} # Neptune-cent. systems
30
43
 
31
44
  systems_cr3bp = {'ine_fb', 'ine_sb', 'ine_cm', 'rot_fb', 'rot_sb', 'rot_cm'}
32
45
 
@@ -36,7 +49,8 @@ systems_hill = {'rot_sb', 'ine_sb'}
36
49
 
37
50
  systems_all = {*systems_cr3bp, *systems_br4bp, *systems_hill, *systems_ephemeris}
38
51
 
39
- units_all = {'earth', 'moon', 'dim', 'earth_moon', 'sun_earth'}
52
+ units_all = {'dim', 'sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune',
53
+ 'sun_mercury', 'sun_venus', 'sun_earth', 'earth_moon', 'sun_mars', 'sun_jupiter', 'sun_saturn', 'sun_uranus', 'sun_neptune'}
40
54
 
41
55
  models_nbp = {'nbp'}
42
56
 
@@ -48,6 +62,27 @@ models_hill = {'hill'}
48
62
 
49
63
  models_all = {*models_cr3bp, *models_br4bp, *models_hill, *models_nbp}
50
64
 
65
+ crssystem2centralbody = {
66
+ 'hcrs': 'sun',
67
+ 'mercrs': 'mercury',
68
+ 'vcrs': 'venus',
69
+ 'mcrs': 'mars',
70
+ 'jcrs': 'jupiter',
71
+ 'satcrs': 'saturn',
72
+ 'ucrs': 'uranus',
73
+ 'ncrs': 'neptune'
74
+ }
75
+
76
+ centralbody2crssystem = {
77
+ 'sun': 'hcrs',
78
+ 'mercury': 'mercrs',
79
+ 'venus': 'vcrs',
80
+ 'mars': 'mcrs',
81
+ 'jupiter': 'jcrs',
82
+ 'saturn': 'satcrs',
83
+ 'uranus': 'ucrs',
84
+ 'neptune': 'ncrs'
85
+ }
51
86
 
52
87
  class Trajectory:
53
88
 
@@ -178,7 +213,15 @@ class Trajectory:
178
213
 
179
214
  `parts` : list[int]
180
215
 
181
- The numbers of nodes between which the trajectory was sequentially propagated.
216
+ The nodes between which the trajectory was sequentially propagated:
217
+
218
+ `tr.states[:, tr.parts[0]:tr.parts[1]+1]` -- first part
219
+
220
+ `tr.states[:, tr.parts[1]:tr.parts[2]+1]` -- second part
221
+
222
+ `tr.states[:, tr.parts[2]:tr.parts[3]+1]` -- third part
223
+
224
+ etc.
182
225
 
183
226
  `states` : numpy.array, shape(m,n)
184
227
 
@@ -250,6 +293,8 @@ class Trajectory:
250
293
  self.vars = variables
251
294
  self.states = numpy.reshape(initial_state, (-1, 1))
252
295
  self.times = numpy.reshape(initial_time, (1,))
296
+ self.control_history = numpy.zeros((3, 0))
297
+ self.specific_impulse_history = numpy.zeros(0)
253
298
  self.system = system
254
299
  self.units_name = units_name
255
300
  self.jds = numpy.reshape(initial_jd, (1,))
@@ -266,16 +311,7 @@ class Trajectory:
266
311
  self._allocate_systems_graph()
267
312
  self._allocate_units_graph()
268
313
 
269
- if units_name == 'earth':
270
- self._set_earth_units()
271
- elif units_name == 'dim':
272
- self._set_dim_units()
273
- elif units_name == 'earth_moon':
274
- self._set_earth_moon_units()
275
- elif units_name == 'sun_earth':
276
- self._set_sun_earth_units()
277
- elif units_name == 'moon':
278
- self._set_moon_units()
314
+ self._set_units(units_name)
279
315
 
280
316
  def set_model(self, variables: str, model_type, primary: str, sources_list: list[str]) -> None:
281
317
  """
@@ -365,59 +401,72 @@ class Trajectory:
365
401
  self.model['type'] = model_type
366
402
  self.model['primary'] = primary
367
403
  self.model['sources_list'] = sources_list
368
- self.model['data'] = {}
404
+ self.model['data'] = {
405
+ 'jd_zero': 0.0,
406
+ 'area': 0.0,
407
+ 'mass': 0.0,
408
+ 'order': 0.0
409
+ }
369
410
  self.model['units'] = {}
411
+ self.model['control'] = None
370
412
 
371
413
  if model_type == 'r2bp':
372
414
 
373
- if (primary != 'earth') and (primary != 'moon'):
374
- raise Exception('Earth or Moon as primary are required for r2bp type of model.')
415
+ if primary not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
416
+ raise Exception('A primary for the r2bp model should be one of: sun, mercury, venus, earth, moon, mars, jupiter, saturn, uranus, neptune.')
375
417
 
376
418
  self.model['data']['grav_parameter'] = 1.0
377
419
  self._set_model_units(primary)
378
- if primary == 'earth':
379
- self.model['system'] = 'gcrs'
380
- elif primary == 'moon':
381
- self.model['system'] = 'scrs'
382
- else:
383
- raise Exception('Unknown primary')
420
+ self.model['system'] = centralbody2crssystem[primary]
384
421
 
385
422
  elif model_type == 'cr3bp_fb':
386
423
 
387
424
  if variables not in ['rv', 'rv_stm']:
388
425
  raise Exception('CR3BP model assumes rv or rv_stm variables.')
389
426
 
390
- if primary == 'earth_moon':
391
- ku = kiam.units('Earth', 'Moon')
392
- self.model['data']['mass_parameter'] = ku['mu']
393
- self._set_model_units('earth_moon')
394
- self.model['system'] = 'rot_fb'
395
- elif primary == 'sun_earth':
396
- ku = kiam.units('Sun', 'Earth')
397
- self.model['data']['mass_parameter'] = ku['mu']
398
- self._set_model_units('sun_earth')
399
- self.model['system'] = 'rot_fb'
400
- else:
427
+ if '_' not in primary:
401
428
  raise Exception('Unknown primary.')
402
429
 
430
+ primaries = primary.split('_')
431
+
432
+ if len(primaries) != 2:
433
+ raise Exception('Unknown primary.')
434
+
435
+ if primaries[0] == 'sun' and primaries[1] not in ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
436
+ raise Exception('Unknown primary.')
437
+
438
+ if primaries[0] == 'earth' and primaries[1] != 'moon':
439
+ raise Exception('Unknown primary.')
440
+
441
+ ku = kiam.units(primaries[0], primaries[1])
442
+ self.model['data']['mass_parameter'] = ku['mu']
443
+ self._set_model_units(primary)
444
+ self.model['system'] = 'rot_fb'
445
+
403
446
  elif model_type == 'cr3bp_sb':
404
447
 
405
448
  if variables not in ['rv', 'rv_stm']:
406
449
  raise Exception('CR3BP model assumes rv or rv_stm variables.')
407
450
 
408
- if primary == 'earth_moon':
409
- ku = kiam.units('Earth', 'Moon')
410
- self.model['data']['mass_parameter'] = ku['mu']
411
- self._set_model_units('earth_moon')
412
- self.model['system'] = 'rot_sb'
413
- elif primary == 'sun_earth':
414
- ku = kiam.units('Sun', 'Earth')
415
- self.model['data']['mass_parameter'] = ku['mu'] # Sun - (Earth + Moon)
416
- self._set_model_units('sun_earth')
417
- self.model['system'] = 'rot_sb'
418
- else:
451
+ if '_' not in primary:
419
452
  raise Exception('Unknown primary.')
420
453
 
454
+ primaries = primary.split('_')
455
+
456
+ if len(primaries) != 2:
457
+ raise Exception('Unknown primary.')
458
+
459
+ if primaries[0] == 'sun' and primaries[1] not in ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
460
+ raise Exception('Unknown primary.')
461
+
462
+ if primaries[0] == 'earth' and primaries[1] != 'moon':
463
+ raise Exception('Unknown primary.')
464
+
465
+ ku = kiam.units(primaries[0], primaries[1])
466
+ self.model['data']['mass_parameter'] = ku['mu']
467
+ self._set_model_units(primary)
468
+ self.model['system'] = 'rot_sb'
469
+
421
470
  elif model_type == 'br4bp_fb':
422
471
 
423
472
  if variables not in ['rv', 'rv_stm']:
@@ -453,34 +502,42 @@ class Trajectory:
453
502
  if variables not in ['rv']:
454
503
  raise Exception('Hill model assumes rv variables.')
455
504
 
456
- if primary == 'earth_moon':
457
- self._set_model_units('earth_moon')
458
- self.model['system'] = 'rot_sb'
459
- elif primary == 'sun_earth':
460
- self._set_model_units('sun_earth')
461
- self.model['system'] = 'rot_sb'
505
+ if '_' not in primary:
506
+ raise Exception('Unknown primary.')
507
+
508
+ primaries = primary.split('_')
509
+
510
+ if len(primaries) != 2:
511
+ raise Exception('Unknown primary.')
512
+
513
+ if primaries[0] == 'sun' and primaries[1] not in ['mercury', 'venus', 'earth', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
514
+ raise Exception('Unknown primary.')
515
+
516
+ if primaries[0] == 'earth' and primaries[1] != 'moon':
517
+ raise Exception('Unknown primary.')
518
+
519
+ self._set_model_units(primary)
520
+ self.model['system'] = 'rot_sb'
462
521
 
463
522
  elif model_type == 'nbp':
464
523
 
524
+ primary2system = {
525
+ 'sun': 'hcrs',
526
+ 'mercury': 'mercrs',
527
+ 'venus': 'vcrs',
528
+ 'earth': 'gcrs',
529
+ 'moon': 'scrs',
530
+ 'mars': 'mcrs',
531
+ 'jupiter': 'jcrs',
532
+ 'saturn': 'satcrs',
533
+ 'uranus': 'ucrs',
534
+ 'neptune': 'ncrs'
535
+ }
536
+
465
537
  self._set_model_sources()
466
- if variables == 'rv' and primary == 'earth':
467
- self._set_model_units('earth')
468
- self.model['system'] = 'gcrs'
469
- elif variables == 'rv_stm' and primary == 'earth':
470
- self._set_model_units('earth')
471
- self.model['system'] = 'gcrs'
472
- elif variables == 'rv' and primary == 'moon':
473
- self._set_model_units('moon')
474
- self.model['system'] = 'scrs'
475
- elif variables == 'rv_stm' and primary == 'moon':
476
- self._set_model_units('moon')
477
- self.model['system'] = 'scrs'
478
- elif variables == 'rvm' and primary == 'earth':
479
- self._set_model_units('earth')
480
- self.model['system'] = 'gcrs'
481
- elif variables == 'rvm' and primary == 'moon':
482
- self._set_model_units('moon')
483
- self.model['system'] = 'scrs'
538
+ if variables in ['rv', 'rvm', 'rv_stm']:
539
+ self._set_model_units(primary)
540
+ self.model['system'] = primary2system[primary]
484
541
  elif variables == 'ee' and primary == 'earth':
485
542
  self._set_model_units('earth')
486
543
  self.model['system'] = 'gcrs'
@@ -523,7 +580,8 @@ class Trajectory:
523
580
 
524
581
  if self.model['type'] == 'nbp':
525
582
  T, X = kiam.propagate_nbp(self.model['primary'], tspan, self.states[0:, -1],
526
- self.model['sources'], self.model['data'], stm, self.vars)
583
+ self.model['sources'], self.model['data'],
584
+ self.model['units'], stm, self.vars, self.model['control'])
527
585
  elif self.model['type'] == 'r2bp':
528
586
  T, X = kiam.propagate_r2bp(tspan, self.states[0:, -1])
529
587
  elif self.model['type'] == 'cr3bp_fb':
@@ -550,15 +608,21 @@ class Trajectory:
550
608
  raise Exception('Unknown model_type.')
551
609
 
552
610
  if len(self.parts) == 0:
553
- self.parts = [0, len(T)]
611
+ self.parts = [0, len(T) - 1]
554
612
  else:
555
- self.parts.append(self.parts[-1] + len(T))
613
+ self.parts.append(self.parts[-1] + len(T) - 1)
556
614
 
557
615
  self.jds = numpy.append(self.jds[0:-1], self.jds[-1] + (T - self.times[-1]) * self.units['TimeUnit'])
558
616
  self.times = numpy.append(self.times[0:-1], T)
559
617
  self.states = numpy.append(self.states[:, 0:-1], X, axis=1)
560
618
  self.finalDate = kiam.jd2time(self.jds[-1])
561
619
 
620
+ if self.model['control'] is not None:
621
+ control_history = numpy.array([self.model['control'](t, x)[0] for (t, x) in zip(T, X.T)]).T
622
+ specific_impulse_history = numpy.array([self.model['control'](t, x)[1] for (t, x) in zip(T, X.T)]).T
623
+ self.control_history = numpy.append(self.control_history[:, 0:-1], control_history, axis=1)
624
+ self.specific_impulse_history = numpy.append(self.specific_impulse_history[0:-1], specific_impulse_history)
625
+
562
626
  def repropagate(self, tof: float, npoints: int = 2, start_index: int = 0) -> None:
563
627
  """
564
628
  Clears the calculated data in trajectory and propagate the trajectory from the beginning.
@@ -598,12 +662,14 @@ class Trajectory:
598
662
 
599
663
  Options:
600
664
 
601
- 1. 'xy', '3d' if self.vars in ['rv', 'rvm', 'rv_stm']
665
+ 1. 'xy', '3d', 'r' if self.vars in ['rv', 'rvm', 'rv_stm']
602
666
 
603
667
  'xy' plots the trajectory in x-y axes.
604
668
 
605
669
  '3d' plots the trajectory in 3d.
606
670
 
671
+ 'r' plots the distance to the origin of the coordinate system.
672
+
607
673
  2. 'a', 'e', 'inc', 'Om', 'w', 'th' if self.vars in ['oe', 'oem', 'oe_stm']
608
674
 
609
675
  'a' plots the semi-major axis wrt time
@@ -650,49 +716,57 @@ class Trajectory:
650
716
  tlabel = 'Time of flight, nondimensional'
651
717
  if self.vars in ['rv', 'rvm', 'rv_stm']:
652
718
  if variables == 'xy':
653
- if self.units_name == 'earth':
654
- xlabel = 'x, Earth radii'
655
- ylabel = 'y, Earth radii'
656
- elif self.units_name == 'moon':
657
- xlabel = 'x, Moon radii'
658
- ylabel = 'y, Moon radii'
659
- elif self.units_name == 'dim':
719
+ if self.units_name == 'dim':
660
720
  xlabel = 'x, km'
661
721
  ylabel = 'y, km'
662
- elif self.units_name in ['earth_moon', 'sun_earth']:
722
+ elif self.units_name == 'sun':
723
+ xlabel = 'x, a.u.'
724
+ ylabel = 'y, a.u.'
725
+ elif '_' not in self.units_name:
726
+ xlabel = f'x, {self.units_name.capitalize()}\'s radii'
727
+ ylabel = f'y, {self.units_name.capitalize()}\'s radii'
728
+ else:
663
729
  xlabel = 'x, nondimensional'
664
730
  ylabel = 'y, nondimensional'
665
- else:
666
- raise Exception('Unknown units.')
667
731
  fig = kiam.plot(self.states[0, :], self.states[1, :], xlabel=xlabel, ylabel=ylabel)
668
732
  elif variables == '3d':
669
- if self.units_name == 'earth':
670
- xlabel = r'x, Earth radii'
671
- ylabel = r'y, Earth radii'
672
- zlabel = r'z, Earth radii'
673
- elif self.units_name == 'moon':
674
- xlabel = r'x, Moon radii'
675
- ylabel = r'y, Moon radii'
676
- zlabel = r'z, Moon radii'
677
- elif self.units_name == 'dim':
678
- xlabel = r'x, km'
679
- ylabel = r'y, km'
680
- zlabel = r'y, km'
681
- elif self.units_name in ['earth_moon', 'sun_earth']:
682
- xlabel = r'x, nondimensional'
683
- ylabel = r'y, nondimensional'
684
- zlabel = r'z, nondimensional'
733
+ if self.units_name == 'dim':
734
+ xlabel = 'x, km'
735
+ ylabel = 'y, km'
736
+ zlabel = 'z, km'
737
+ elif self.units_name == 'sun':
738
+ xlabel = 'x, a.u.'
739
+ ylabel = 'y, a.u.'
740
+ zlabel = 'z, a.u.'
741
+ elif '_' not in self.units_name:
742
+ xlabel = f'x, {self.units_name.capitalize()}\'s radii'
743
+ ylabel = f'y, {self.units_name.capitalize()}\'s radii'
744
+ zlabel = f'z, {self.units_name.capitalize()}\'s radii'
685
745
  else:
686
- raise Exception('Unknown units.')
746
+ xlabel = 'x, nondimensional'
747
+ ylabel = 'y, nondimensional'
748
+ zlabel = 'z, nondimensional'
687
749
  fig = kiam.plot3(self.states[0, :], self.states[1, :], self.states[2, :], xlabel=xlabel, ylabel=ylabel, zlabel=zlabel)
750
+ elif variables == 'r':
751
+ if self.units_name == 'dim':
752
+ rlabel = 'r, km'
753
+ elif self.units_name == 'sun':
754
+ rlabel = 'r, a.u.'
755
+ elif '_' not in self.units_name:
756
+ rlabel = f'r, {self.units_name.capitalize()}\'s radii'
757
+ else:
758
+ rlabel = 'r, nondimensional'
759
+ fig = kiam.plot(self.times, norm(self.states[0:3, :], axis=0), xlabel=tlabel, ylabel=rlabel)
688
760
  else:
689
761
  raise 'Unknown variables to show.'
690
762
  elif self.vars in ['oe', 'oem', 'oe_stm']:
691
763
  if variables == 'a':
692
764
  if self.units_name == 'dim':
693
765
  ylabel = 'Semi-major axis, km'
694
- elif self.units_name == 'earth':
695
- ylabel = 'Semi-major axis, Earth''s radii'
766
+ elif self.units_name in ['mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
767
+ ylabel = f'Semi-major axis, {self.units_name.capitalize()}\'s radii'
768
+ elif self.units_name == 'sun':
769
+ ylabel = f'Semi-major axis, a.u.'
696
770
  else:
697
771
  ylabel = ''
698
772
  fig = kiam.plot(self.times, self.states[0, :], xlabel=tlabel, ylabel=ylabel)
@@ -717,7 +791,7 @@ class Trajectory:
717
791
  if variables == 'h':
718
792
  if self.units_name == 'dim':
719
793
  ylabel = r'$h\text{, (km/s)}^{-1}$'
720
- elif self.units_name == 'earth':
794
+ elif self.units_name in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
721
795
  ylabel = r'$h\text{, nondimensional}$'
722
796
  else:
723
797
  ylabel = ''
@@ -745,21 +819,43 @@ class Trajectory:
745
819
  fig.show()
746
820
  return fig
747
821
 
748
- def copy(self):
822
+ def copy(self, forced: bool = False):
749
823
  """
750
824
  Returns independent copy of the trajectory object.
825
+
826
+ Parameters:
827
+ -----------
828
+
829
+ forced : bool
830
+
831
+ If False (default), raise exception if model['control'] is not None. Do not make copy.
832
+
833
+ If True (default), erase funtion handle in model['control'] and make copy.
834
+
835
+ Returns:
836
+ --------
837
+
838
+ If successfull, the deep copy of the Trajectory object is returned.
839
+
751
840
  """
841
+ if self.model['control'] is not None and forced:
842
+ warnings.warn('Control function handle in model is removed.')
843
+ self.model['control'] = None
844
+ elif self.model['control'] is not None and not forced:
845
+ raise Exception('Control function handle in model prevents copying. Use forced=True flag to ignore the warning and erase the control function handle.')
752
846
  return copy.deepcopy(self)
753
847
 
754
848
  def clear(self) -> None:
755
849
  """
756
850
  Clears states, times, julian dates, parts, and resets the final date.
757
851
  """
758
- self.states = numpy.reshape(self.states[:, 0], (6, 1))
852
+ self.states = numpy.reshape(self.states[:, 0], (-1, 1))
759
853
  self.times = numpy.reshape(self.times[0], (1,))
760
854
  self.jds = numpy.reshape(self.jds[0], (1,))
761
855
  self.parts = []
762
856
  self.finalDate = self.initialDate
857
+ self.control_history = numpy.zeros((3, 0))
858
+ self.specific_impulse_history = numpy.zeros(0)
763
859
 
764
860
  def change_vars(self, new_vars: str) -> None:
765
861
  """
@@ -810,6 +906,20 @@ class Trajectory:
810
906
 
811
907
  'hcrs', 'hsrf_se' (the Sun-centered systems)
812
908
 
909
+ 'mercrs', 'mersrf_smer' (the Mercury-centered systems)
910
+
911
+ 'vcrs', 'vsrf_sv' (the Venus-centered systems)
912
+
913
+ 'mcrs', 'msrf_sm' (the Mars-centered systems)
914
+
915
+ 'jcrs', 'jsrf_sj' (the Jupiter-centered systems)
916
+
917
+ 'satcrs', 'satsrf_ssat' (the Saturn-centered systems)
918
+
919
+ 'ucrs', 'usrf_su' (the Uranus-centered systems)
920
+
921
+ 'ncrs', 'nsrf_sn' (the Neptune-centered systems)
922
+
813
923
  'ine_fb' (non-rotating frame in CR3BP, BR4BP at first primary)
814
924
 
815
925
  'ine_cm' (non-rotating frame in CR3BP, BR4BP at barycenter)
@@ -926,8 +1036,8 @@ class Trajectory:
926
1036
  Variables after transformation.
927
1037
  """
928
1038
  if vars1 == 'rv' and vars2 == 'ee': # mu = 1.0
929
- if self.units_name != 'earth' and self.units_name != 'moon':
930
- raise Exception('Wrong units: rv2ee suggests earth or moon, mu = 1.0.')
1039
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1040
+ raise Exception('Wrong units: rv2ee assumes mu = 1.0.')
931
1041
  elif self.vars != 'rv' and self.vars != 'rvm':
932
1042
  raise Exception('Vars should be rv or rvm.')
933
1043
  self.states = kiam.rv2ee(self.states, 1.0)
@@ -935,8 +1045,8 @@ class Trajectory:
935
1045
  # self.states[0:6, i] = kiam.rv2ee(self.states[0:6, i], 1.0)
936
1046
  self.vars = 'ee'
937
1047
  elif vars1 == 'ee' and vars2 == 'rv': # mu = 1.0
938
- if self.units_name != 'earth' and self.units_name != 'moon':
939
- raise Exception('Wrong units: ee2rv suggests earth or moon, mu = 1.0.')
1048
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1049
+ raise Exception('Wrong units: ee2rv assumes mu = 1.0.')
940
1050
  elif self.vars != 'ee' and self.vars != 'eem':
941
1051
  raise Exception('Vars should be ee or eem.')
942
1052
  self.states = kiam.ee2rv(self.states, 1.0)
@@ -944,8 +1054,8 @@ class Trajectory:
944
1054
  # self.states[0:6, i] = kiam.ee2rv(self.states[0:6, i], 1.0)
945
1055
  self.vars = 'rv'
946
1056
  elif vars1 == 'rv' and vars2 == 'oe': # mu = 1.0
947
- if self.units_name != 'earth' and self.units_name != 'moon':
948
- raise Exception('Wrong units: rv2oe suggests earth or moon, mu = 1.0.')
1057
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1058
+ raise Exception('Wrong units: rv2oe assumes mu = 1.0.')
949
1059
  elif self.vars != 'rv' and self.vars != 'rvm':
950
1060
  raise Exception('Vars should be rv or rvm.')
951
1061
  self.states = kiam.rv2oe(self.states, 1.0)
@@ -953,8 +1063,8 @@ class Trajectory:
953
1063
  # self.states[0:6, i] = kiam.rv2oe(self.states[0:6, i], 1.0)
954
1064
  self.vars = 'oe'
955
1065
  elif vars1 == 'oe' and vars2 == 'rv': # mu = 1.0
956
- if self.units_name != 'earth' and self.units_name != 'moon':
957
- raise Exception('Wrong units: oe2rv suggests earth or moon, mu = 1.0.')
1066
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1067
+ raise Exception('Wrong units: oe2rv assumes earth or moon, mu = 1.0.')
958
1068
  elif self.vars != 'oe' and self.vars != 'oem':
959
1069
  raise Exception('Vars should be oe or oem.')
960
1070
  self.states = kiam.oe2rv(self.states, 1.0)
@@ -992,8 +1102,8 @@ class Trajectory:
992
1102
  numpy.delete(self.states, 6, 0)
993
1103
  self.vars = 'ee'
994
1104
  elif vars1 == 'rv_stm' and vars2 == 'oe_stm':
995
- if self.units_name != 'earth' and self.units_name != 'moon':
996
- raise Exception('Wrong units: rv_stm2oe_stm suggests earth or moon, mu = 1.0.')
1105
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1106
+ raise Exception('Wrong units: rv_stm2oe_stm assumes mu = 1.0.')
997
1107
  elif self.vars != 'rv_stm':
998
1108
  raise Exception('Vars should be rv_stm.')
999
1109
  _, doe0 = kiam.rv2oe(self.states[0:6, 0], 1.0, True)
@@ -1005,8 +1115,8 @@ class Trajectory:
1005
1115
  self.states[6:42, i] = numpy.reshape(phi_oe.T, (36,))
1006
1116
  self.vars = 'oe_stm'
1007
1117
  elif vars1 == 'oe_stm' and vars2 == 'rv_stm':
1008
- if self.units_name != 'earth' and self.units_name != 'moon':
1009
- raise Exception('Wrong units: oe_stm2rv_stm suggests earth or moon, mu = 1.0.')
1118
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1119
+ raise Exception('Wrong units: oe_stm2rv_stm assumes mu = 1.0.')
1010
1120
  elif self.vars != 'oe_stm':
1011
1121
  raise Exception('Vars should be oe_stm.')
1012
1122
  _, drv0 = kiam.oe2rv(self.states[0:6, 0], 1.0, True)
@@ -1018,8 +1128,8 @@ class Trajectory:
1018
1128
  self.states[6:42, i] = numpy.reshape(phi_rv.T, (36,))
1019
1129
  self.vars = 'rv_stm'
1020
1130
  elif vars1 == 'rv_stm' and vars2 == 'ee_stm':
1021
- if self.units_name != 'earth' and self.units_name != 'moon':
1022
- raise Exception('Wrong units: rv_stm2ee_stm suggests earth or moon, mu = 1.0.')
1131
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1132
+ raise Exception('Wrong units: rv_stm2ee_stm assumes mu = 1.0.')
1023
1133
  elif self.vars != 'rv_stm':
1024
1134
  raise Exception('Vars should be rv_stm.')
1025
1135
  _, dee0 = kiam.rv2ee(self.states[0:6, 0], 1.0, True)
@@ -1031,8 +1141,8 @@ class Trajectory:
1031
1141
  self.states[6:42, i] = numpy.reshape(phi_ee.T, (36,))
1032
1142
  self.vars = 'ee_stm'
1033
1143
  elif vars1 == 'ee_stm' and vars2 == 'rv_stm':
1034
- if self.units_name != 'earth' and self.units_name != 'moon':
1035
- raise Exception('Wrong units: ee_stm2rv_stm suggests earth or moon, mu = 1.0.')
1144
+ if self.units_name not in ['sun', 'mercury', 'venus', 'earth', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune']:
1145
+ raise Exception('Wrong units: ee_stm2rv_stm assumes mu = 1.0.')
1036
1146
  elif self.vars != 'ee_stm':
1037
1147
  raise Exception('Vars should be ee_stm.')
1038
1148
  _, drv0 = kiam.ee2rv(self.states[0:6, 0], 1.0, True)
@@ -1064,19 +1174,38 @@ class Trajectory:
1064
1174
  self.systems_graph.add_edge('hcrs', 'hsrf_se')
1065
1175
  self.systems_graph.add_edge('scrs', 'sors')
1066
1176
 
1177
+ # New transformations
1178
+ self.systems_graph.add_edge('hcrs', 'mercrs') # done
1179
+ self.systems_graph.add_edge('hcrs', 'vcrs') # done
1180
+ self.systems_graph.add_edge('hcrs', 'mcrs') # done
1181
+ self.systems_graph.add_edge('hcrs', 'jcrs') # done
1182
+ self.systems_graph.add_edge('hcrs', 'satcrs') # done
1183
+ self.systems_graph.add_edge('hcrs', 'ucrs') # done
1184
+ self.systems_graph.add_edge('hcrs', 'ncrs') # done
1185
+
1186
+ self.systems_graph.add_edge('hcrs', 'hsrf_smer') # done
1187
+ self.systems_graph.add_edge('hcrs', 'hsrf_sv') # done
1188
+ self.systems_graph.add_edge('hcrs', 'hsrf_sm') # done
1189
+ self.systems_graph.add_edge('hcrs', 'hsrf_sj') # done
1190
+ self.systems_graph.add_edge('hcrs', 'hsrf_ssat') # done
1191
+ self.systems_graph.add_edge('hcrs', 'hsrf_su') # done
1192
+ self.systems_graph.add_edge('hcrs', 'hsrf_sn') # done
1193
+
1194
+ self.systems_graph.add_edge('mercrs', 'mersrf_smer') # done
1195
+ self.systems_graph.add_edge('vcrs', 'vsrf_sv') # done
1196
+ self.systems_graph.add_edge('mcrs', 'msrf_sm') # done
1197
+ self.systems_graph.add_edge('jcrs', 'jsrf_sj') # done
1198
+ self.systems_graph.add_edge('satcrs', 'satsrf_ssat') # done
1199
+ self.systems_graph.add_edge('ucrs', 'usrf_su') # done
1200
+ self.systems_graph.add_edge('ncrs', 'nsrf_sn') # done
1201
+
1067
1202
  # CR3BP and BR4BP coordinate systems
1068
1203
  self.systems_graph.add_edge('ine_fb', 'rot_fb')
1069
1204
  self.systems_graph.add_edge('ine_sb', 'rot_sb')
1070
1205
  self.systems_graph.add_edge('ine_cm', 'rot_cm')
1071
- self.systems_graph.add_edge('rot_fb', 'ine_fb')
1072
- self.systems_graph.add_edge('rot_sb', 'ine_sb')
1073
- self.systems_graph.add_edge('rot_cm', 'ine_cm')
1074
1206
  self.systems_graph.add_edge('rot_fb', 'rot_cm')
1075
- self.systems_graph.add_edge('rot_cm', 'rot_fb')
1076
1207
  self.systems_graph.add_edge('rot_fb', 'rot_sb')
1077
- self.systems_graph.add_edge('rot_sb', 'rot_fb')
1078
1208
  self.systems_graph.add_edge('rot_sb', 'rot_cm')
1079
- self.systems_graph.add_edge('rot_cm', 'rot_sb')
1080
1209
 
1081
1210
  def _system_transform(self, system1: str, system2: str) -> None:
1082
1211
  """
@@ -1095,6 +1224,16 @@ class Trajectory:
1095
1224
  Coordinate system after transformation.
1096
1225
  """
1097
1226
 
1227
+ system2secondbody = {
1228
+ 'hsrf_smer': 'Mercury',
1229
+ 'hsrf_sv': 'Venus',
1230
+ 'hsrf_sm': 'Mars',
1231
+ 'hsrf_sj': 'Jupiter',
1232
+ 'hsrf_ssat': 'Saturn',
1233
+ 'hsrf_su': 'Uranus',
1234
+ 'hsrf_sn': 'Neptune'
1235
+ }
1236
+
1098
1237
  case_nbp = self.model['type'] == 'nbp' and system1 in systems_ephemeris and system2 in systems_ephemeris
1099
1238
  if case_nbp:
1100
1239
  if system1 == 'itrs' and system2 == 'gcrs':
@@ -1103,6 +1242,8 @@ class Trajectory:
1103
1242
  elif self.system != 'itrs':
1104
1243
  raise Exception('System should be itrs.')
1105
1244
  self.states[0:6] = kiam.itrs2gcrs(self.states[0:6], self.jds)
1245
+ if self.control_history.shape[1] > 0:
1246
+ self.control_history = kiam.itrs2gcrs(self.control_history, self.jds)
1106
1247
  # self.states[0:3, :] = kiam.itrs2gcrs(self.states[0:3, :], self.jds)
1107
1248
  # self.states[3:6, :] = kiam.itrs2gcrs(self.states[3:6, :], self.jds)
1108
1249
  # for i in range(self.states.shape[1]):
@@ -1115,6 +1256,8 @@ class Trajectory:
1115
1256
  elif self.system != 'gcrs':
1116
1257
  raise Exception('System should be gcrs.')
1117
1258
  self.states[0:6] = kiam.gcrs2itrs(self.states[0:6], self.jds)
1259
+ if self.control_history.shape[1] > 0:
1260
+ self.control_history = kiam.gcrs2itrs(self.control_history, self.jds)
1118
1261
  # self.states[0:3, :] = kiam.gcrs2itrs(self.states[0:3, :], self.jds)
1119
1262
  # self.states[3:6, :] = kiam.gcrs2itrs(self.states[3:6, :], self.jds)
1120
1263
  # for i in range(self.states.shape[1]):
@@ -1128,6 +1271,10 @@ class Trajectory:
1128
1271
  raise Exception('System should be gcrs.')
1129
1272
  self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Earth', 'Moon',
1130
1273
  self.units['DistUnit'], self.units['VelUnit'])
1274
+ if self.control_history.shape[1] > 0:
1275
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1276
+ self.jds, 'Earth', 'Moon',
1277
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1131
1278
  self.system = 'gsrf_em'
1132
1279
  elif system1 == 'gsrf_em' and system2 == 'gcrs':
1133
1280
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1136,6 +1283,10 @@ class Trajectory:
1136
1283
  raise Exception('System should be gsrf_em.')
1137
1284
  self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Earth', 'Moon',
1138
1285
  self.units['DistUnit'], self.units['VelUnit'])
1286
+ if self.control_history.shape[1] > 0:
1287
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1288
+ self.jds, 'Earth', 'Moon',
1289
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1139
1290
  self.system = 'gcrs'
1140
1291
  elif system1 == 'gcrs' and system2 == 'gsrf_se':
1141
1292
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1144,6 +1295,10 @@ class Trajectory:
1144
1295
  raise Exception('System should be gcrs.')
1145
1296
  self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Earth',
1146
1297
  self.units['DistUnit'], self.units['VelUnit'])
1298
+ if self.control_history.shape[1] > 0:
1299
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1300
+ self.jds, 'Sun', 'Earth',
1301
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1147
1302
  self.system = 'gsrf_se'
1148
1303
  elif system1 == 'gsrf_se' and system2 == 'gcrs':
1149
1304
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1152,6 +1307,10 @@ class Trajectory:
1152
1307
  raise Exception('System should be gsrf_se.')
1153
1308
  self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Earth',
1154
1309
  self.units['DistUnit'], self.units['VelUnit'])
1310
+ if self.control_history.shape[1] > 0:
1311
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1312
+ self.jds, 'Sun', 'Earth',
1313
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1155
1314
  self.system = 'gcrs'
1156
1315
  elif system1 == 'scrs' and system2 == 'ssrf_em':
1157
1316
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1160,6 +1319,10 @@ class Trajectory:
1160
1319
  raise Exception('System should be scrs.')
1161
1320
  self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Earth', 'Moon',
1162
1321
  self.units['DistUnit'], self.units['VelUnit'])
1322
+ if self.control_history.shape[1] > 0:
1323
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1324
+ self.jds, 'Earth', 'Moon',
1325
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1163
1326
  self.system = 'ssrf_em'
1164
1327
  elif system1 == 'ssrf_em' and system2 == 'scrs':
1165
1328
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1168,6 +1331,10 @@ class Trajectory:
1168
1331
  raise Exception('System should be ssrf_em.')
1169
1332
  self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Earth', 'Moon',
1170
1333
  self.units['DistUnit'], self.units['VelUnit'])
1334
+ if self.control_history.shape[1] > 0:
1335
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1336
+ self.jds, 'Earth', 'Moon',
1337
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1171
1338
  self.system = 'scrs'
1172
1339
  elif system1 == 'gcrs' and system2 == 'scrs':
1173
1340
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1191,6 +1358,8 @@ class Trajectory:
1191
1358
  elif self.system != 'scrs':
1192
1359
  raise Exception('System should be scrs.')
1193
1360
  self.states[0:6, :] = kiam.scrs2mer(self.states[0:6, :], self.jds)
1361
+ if self.control_history.shape[1] > 0:
1362
+ self.control_history = kiam.scrs2mer(self.control_history, self.jds)
1194
1363
  self.system = 'mer'
1195
1364
  elif system1 == 'mer' and system2 == 'scrs':
1196
1365
  if self.vars not in ['rv', 'rvm', 'rv_stm']:
@@ -1198,6 +1367,8 @@ class Trajectory:
1198
1367
  elif self.system != 'mer':
1199
1368
  raise Exception('System should be mer.')
1200
1369
  self.states[0:6, :] = kiam.mer2scrs(self.states[0:6, :], self.jds)
1370
+ if self.control_history.shape[1] > 0:
1371
+ self.control_history = kiam.mer2scrs(self.control_history, self.jds)
1201
1372
  self.system = 'scrs'
1202
1373
  elif system1 == 'gcrs' and system2 == 'hcrs':
1203
1374
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1222,6 +1393,10 @@ class Trajectory:
1222
1393
  raise Exception('System should be hcrs.')
1223
1394
  self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Earth',
1224
1395
  self.units['DistUnit'], self.units['VelUnit'])
1396
+ if self.control_history.shape[1] > 0:
1397
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1398
+ self.jds, 'Sun', 'Earth',
1399
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1225
1400
  self.system = 'hsrf_se'
1226
1401
  elif system1 == 'hsrf_se' and system2 == 'hcrs':
1227
1402
  if self.vars != 'rv' and self.vars != 'rvm':
@@ -1230,6 +1405,10 @@ class Trajectory:
1230
1405
  raise Exception('System should be hsrf_se.')
1231
1406
  self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Earth',
1232
1407
  self.units['DistUnit'], self.units['VelUnit'])
1408
+ if self.control_history.shape[1] > 0:
1409
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1410
+ self.jds, 'Sun', 'Earth',
1411
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1233
1412
  self.system = 'hcrs'
1234
1413
  elif system1 == 'scrs' and system2 == 'sors':
1235
1414
  if self.vars not in ['rv', 'rvm', 'rv_stm']:
@@ -1245,6 +1424,8 @@ class Trajectory:
1245
1424
  phi_scrs = numpy.reshape(self.states[6:42, i], (6, 6)).T
1246
1425
  phi_sors = kiam.dotainvb(numpy.matmul(dxsors[:, :, i], phi_scrs), dxsors[:, :, 0])
1247
1426
  self.states[6:42, i] = numpy.reshape(phi_sors.T, (36,))
1427
+ if self.control_history.shape[1] > 0:
1428
+ self.control_history = kiam.scrs2sors(self.control_history, self.jds, False)
1248
1429
  self.system = 'sors'
1249
1430
  elif system1 == 'sors' and system2 == 'scrs':
1250
1431
  if self.vars not in ['rv', 'rvm', 'rv_stm']:
@@ -1260,17 +1441,229 @@ class Trajectory:
1260
1441
  phi_sors = numpy.reshape(self.states[6:42, i], (6, 6)).T
1261
1442
  phi_scrs = kiam.dotainvb(numpy.matmul(dxscrs[:, :, i], phi_sors), dxscrs[:, :, 0])
1262
1443
  self.states[6:42, i] = numpy.reshape(phi_scrs.T, (36,))
1444
+ if self.control_history.shape[1] > 0:
1445
+ self.control_history = kiam.sors2scrs(self.control_history, self.jds, False)
1263
1446
  self.system = 'scrs'
1447
+ elif system1 == 'hcrs' and system2 in ['hsrf_smer', 'hsrf_sv', 'hsrf_sm', 'hsrf_sj', 'hsrf_ssat', 'hsrf_su', 'hsrf_sn']:
1448
+ if self.vars != 'rv' and self.vars != 'rvm':
1449
+ raise Exception('Vars should be rv or rvm')
1450
+ elif self.system != system1:
1451
+ raise Exception(f'System should be {system1}.')
1452
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', system2secondbody[system2],
1453
+ self.units['DistUnit'], self.units['VelUnit'])
1454
+ if self.control_history.shape[1] > 0:
1455
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1456
+ self.jds, 'Sun', system2secondbody[system2],
1457
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1458
+ self.system = system2
1459
+ elif system2 == 'hcrs' and system1 in ['hsrf_smer', 'hsrf_sv', 'hsrf_sm', 'hsrf_sj', 'hsrf_ssat', 'hsrf_su', 'hsrf_sn']:
1460
+ if self.vars != 'rv' and self.vars != 'rvm':
1461
+ raise Exception('Vars should be rv or rvm')
1462
+ elif self.system != system1:
1463
+ raise Exception(f'System should be {system1}.')
1464
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', system2secondbody[system1],
1465
+ self.units['DistUnit'], self.units['VelUnit'])
1466
+ if self.control_history.shape[1] > 0:
1467
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1468
+ self.jds, 'Sun', system2secondbody[system2],
1469
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1470
+ self.system = system2
1471
+ elif system1 in ['hcrs', 'mercrs', 'vcrs', 'mcrs', 'jcrs', 'satcrs', 'ucrs', 'ncrs'] and \
1472
+ system2 in ['hcrs', 'mercrs', 'vcrs', 'mcrs', 'jcrs', 'satcrs', 'ucrs', 'ncrs']:
1473
+ if self.vars != 'rv' and self.vars != 'rvm':
1474
+ raise Exception('Vars should be rv or rvm')
1475
+ elif self.system != system1:
1476
+ raise Exception(f'System should be {system1}.')
1477
+ self.states[0:6, :] = kiam.b1crs2b2crs(crssystem2centralbody[system1], crssystem2centralbody[system2], self.states[0:6, :], self.jds,
1478
+ self.units['DistUnit'], self.units['VelUnit'])
1479
+ self.system = system2
1480
+ elif system1 == 'mercrs' and system2 == 'mersrf_smer':
1481
+ if self.vars != 'rv' and self.vars != 'rvm':
1482
+ raise Exception('Vars should be rv or rvm')
1483
+ elif self.system != system1:
1484
+ raise Exception(f'System should be {system1}.')
1485
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Mercury',
1486
+ self.units['DistUnit'], self.units['VelUnit'])
1487
+ if self.control_history.shape[1] > 0:
1488
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1489
+ self.jds, 'Sun', 'Mercury',
1490
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1491
+ self.system = system2
1492
+ elif system1 == 'mersrf_smer' and system2 == 'mercrs':
1493
+ if self.vars != 'rv' and self.vars != 'rvm':
1494
+ raise Exception('Vars should be rv or rvm')
1495
+ elif self.system != system1:
1496
+ raise Exception(f'System should be {system1}.')
1497
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Mercury',
1498
+ self.units['DistUnit'], self.units['VelUnit'])
1499
+ if self.control_history.shape[1] > 0:
1500
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1501
+ self.jds, 'Sun', 'Mercury',
1502
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1503
+
1504
+ self.system = system2
1505
+ elif system1 == 'vcrs' and system2 == 'vsrf_sv':
1506
+ if self.vars != 'rv' and self.vars != 'rvm':
1507
+ raise Exception('Vars should be rv or rvm')
1508
+ elif self.system != system1:
1509
+ raise Exception(f'System should be {system1}.')
1510
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Venus',
1511
+ self.units['DistUnit'], self.units['VelUnit'])
1512
+ if self.control_history.shape[1] > 0:
1513
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1514
+ self.jds, 'Sun', 'Venus',
1515
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1516
+
1517
+ self.system = system2
1518
+ elif system1 == 'vsrf_sv' and system2 == 'vcrs':
1519
+ if self.vars != 'rv' and self.vars != 'rvm':
1520
+ raise Exception('Vars should be rv or rvm')
1521
+ elif self.system != system1:
1522
+ raise Exception(f'System should be {system1}.')
1523
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Venus',
1524
+ self.units['DistUnit'], self.units['VelUnit'])
1525
+ if self.control_history.shape[1] > 0:
1526
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1527
+ self.jds, 'Sun', 'Venus',
1528
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1529
+ self.system = system2
1530
+ elif system1 == 'mcrs' and system2 == 'msrf_sm':
1531
+ if self.vars != 'rv' and self.vars != 'rvm':
1532
+ raise Exception('Vars should be rv or rvm')
1533
+ elif self.system != system1:
1534
+ raise Exception(f'System should be {system1}.')
1535
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Mars',
1536
+ self.units['DistUnit'], self.units['VelUnit'])
1537
+ if self.control_history.shape[1] > 0:
1538
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1539
+ self.jds, 'Sun', 'Mars',
1540
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1541
+
1542
+ self.system = system2
1543
+ elif system1 == 'msrf_sm' and system2 == 'mcrs':
1544
+ if self.vars != 'rv' and self.vars != 'rvm':
1545
+ raise Exception('Vars should be rv or rvm')
1546
+ elif self.system != system1:
1547
+ raise Exception(f'System should be {system1}.')
1548
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Mars',
1549
+ self.units['DistUnit'], self.units['VelUnit'])
1550
+ if self.control_history.shape[1] > 0:
1551
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1552
+ self.jds, 'Sun', 'Mars',
1553
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1554
+
1555
+ self.system = system2
1556
+ elif system1 == 'jcrs' and system2 == 'jsrf_sj':
1557
+ if self.vars != 'rv' and self.vars != 'rvm':
1558
+ raise Exception('Vars should be rv or rvm')
1559
+ elif self.system != system1:
1560
+ raise Exception(f'System should be {system1}.')
1561
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Jupiter',
1562
+ self.units['DistUnit'], self.units['VelUnit'])
1563
+ if self.control_history.shape[1] > 0:
1564
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1565
+ self.jds, 'Sun', 'Jupiter',
1566
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1567
+ self.system = system2
1568
+ elif system1 == 'jsrf_sj' and system2 == 'jcrs':
1569
+ if self.vars != 'rv' and self.vars != 'rvm':
1570
+ raise Exception('Vars should be rv or rvm')
1571
+ elif self.system != system1:
1572
+ raise Exception(f'System should be {system1}.')
1573
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Jupiter',
1574
+ self.units['DistUnit'], self.units['VelUnit'])
1575
+ if self.control_history.shape[1] > 0:
1576
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1577
+ self.jds, 'Sun', 'Jupiter',
1578
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1579
+
1580
+ self.system = system2
1581
+ elif system1 == 'satcrs' and system2 == 'satsrf_ssat':
1582
+ if self.vars != 'rv' and self.vars != 'rvm':
1583
+ raise Exception('Vars should be rv or rvm')
1584
+ elif self.system != system1:
1585
+ raise Exception(f'System should be {system1}.')
1586
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Saturn',
1587
+ self.units['DistUnit'], self.units['VelUnit'])
1588
+ if self.control_history.shape[1] > 0:
1589
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1590
+ self.jds, 'Sun', 'Saturn',
1591
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1592
+ self.system = system2
1593
+ elif system1 == 'satsrf_ssat' and system2 == 'satcrs':
1594
+ if self.vars != 'rv' and self.vars != 'rvm':
1595
+ raise Exception('Vars should be rv or rvm')
1596
+ elif self.system != system1:
1597
+ raise Exception(f'System should be {system1}.')
1598
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Saturn',
1599
+ self.units['DistUnit'], self.units['VelUnit'])
1600
+ if self.control_history.shape[1] > 0:
1601
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1602
+ self.jds, 'Sun', 'Saturn',
1603
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1604
+ self.system = system2
1605
+ elif system1 == 'ucrs' and system2 == 'usrf_su':
1606
+ if self.vars != 'rv' and self.vars != 'rvm':
1607
+ raise Exception('Vars should be rv or rvm')
1608
+ elif self.system != system1:
1609
+ raise Exception(f'System should be {system1}.')
1610
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Uranus',
1611
+ self.units['DistUnit'], self.units['VelUnit'])
1612
+ if self.control_history.shape[1] > 0:
1613
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1614
+ self.jds, 'Sun', 'Uranus',
1615
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1616
+ self.system = system2
1617
+ elif system1 == 'usrf_su' and system2 == 'ucrs':
1618
+ if self.vars != 'rv' and self.vars != 'rvm':
1619
+ raise Exception('Vars should be rv or rvm')
1620
+ elif self.system != system1:
1621
+ raise Exception(f'System should be {system1}.')
1622
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Uranus',
1623
+ self.units['DistUnit'], self.units['VelUnit'])
1624
+ if self.control_history.shape[1] > 0:
1625
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1626
+ self.jds, 'Sun', 'Uranus',
1627
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1628
+ self.system = system2
1629
+ elif system1 == 'ncrs' and system2 == 'nsrf_sn':
1630
+ if self.vars != 'rv' and self.vars != 'rvm':
1631
+ raise Exception('Vars should be rv or rvm')
1632
+ elif self.system != system1:
1633
+ raise Exception(f'System should be {system1}.')
1634
+ self.states[0:6, :] = kiam.ine2rot_eph(self.states[0:6, :], self.jds, 'Sun', 'Neptune',
1635
+ self.units['DistUnit'], self.units['VelUnit'])
1636
+ if self.control_history.shape[1] > 0:
1637
+ self.control_history = kiam.ine2rot_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1638
+ self.jds, 'Sun', 'Neptune',
1639
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1640
+ self.system = system2
1641
+ elif system1 == 'nsrf_sn' and system2 == 'ncrs':
1642
+ if self.vars != 'rv' and self.vars != 'rvm':
1643
+ raise Exception('Vars should be rv or rvm')
1644
+ elif self.system != system1:
1645
+ raise Exception(f'System should be {system1}.')
1646
+ self.states[0:6, :] = kiam.rot2ine_eph(self.states[0:6, :], self.jds, 'Sun', 'Neptune',
1647
+ self.units['DistUnit'], self.units['VelUnit'])
1648
+ if self.control_history.shape[1] > 0:
1649
+ self.control_history = kiam.rot2ine_eph(numpy.concatenate(numpy.zeros((3, self.control_history)), self.control_history, axis=0),
1650
+ self.jds, 'Sun', 'Neptune',
1651
+ self.units['DistUnit'], self.units['VelUnit'])[3:6, :]
1652
+
1653
+ self.system = system2
1654
+
1264
1655
  return
1265
1656
 
1657
+ # In future, for models below implement control_history transformation.
1658
+
1266
1659
  case_cr3bp = self.model['type'] in models_cr3bp and system1 in systems_cr3bp and system2 in systems_cr3bp
1267
1660
  case_br4bp = self.model['type'] in models_br4bp and system1 in systems_br4bp and system2 in systems_br4bp
1268
1661
  if case_cr3bp or case_br4bp:
1269
1662
  if case_cr3bp:
1270
1663
  if self.vars not in ['rv', 'rvm']:
1271
1664
  raise Exception('Vars should be rv or rvm.')
1272
- if self.model['primary'] not in ['sun_earth', 'earth_moon']:
1273
- raise Exception("Model's primary should be sun_earth or earth_moon.")
1665
+ if self.model['primary'] not in ['sun_mercury', 'sun_venus', 'sun_earth', 'earth_moon', 'sun_mars', 'sun_jupiter', 'sun_saturn', 'sun_uranus', 'sun_neptune']:
1666
+ raise Exception("Model's primary should be sun_[planet] or earth_moon.")
1274
1667
  if self.units_name != self.model['primary']:
1275
1668
  raise Exception('Units_name should equal primary.')
1276
1669
  elif case_br4bp:
@@ -1320,8 +1713,8 @@ class Trajectory:
1320
1713
  if case_hill:
1321
1714
  if self.vars not in ['rv', 'rvm']:
1322
1715
  raise Exception('Vars should be rv or rvm.')
1323
- if self.model['primary'] not in ['earth_moon', 'sun_earth']:
1324
- raise Exception("Model's primary should be earth_moon.")
1716
+ if self.model['primary'] not in ['sun_mercury', 'sun_venus', 'sun_earth', 'earth_moon', 'sun_mars', 'sun_jupiter', 'sun_saturn', 'sun_uranus', 'sun_neptune']:
1717
+ raise Exception("Model's primary should be sun_[planet] or earth_moon.")
1325
1718
  if self.units_name != self.model['primary']:
1326
1719
  raise Exception('Units_name should equal primary.')
1327
1720
  if system1 == 'ine_sb' and system2 == 'rot_sb':
@@ -1355,6 +1748,23 @@ class Trajectory:
1355
1748
  self.units_graph.add_edge('dim', 'earth_moon')
1356
1749
  self.units_graph.add_edge('dim', 'sun_earth')
1357
1750
 
1751
+ self.units_graph.add_edge('dim', 'sun')
1752
+ self.units_graph.add_edge('dim', 'mercury')
1753
+ self.units_graph.add_edge('dim', 'venus')
1754
+ self.units_graph.add_edge('dim', 'mars')
1755
+ self.units_graph.add_edge('dim', 'jupiter')
1756
+ self.units_graph.add_edge('dim', 'saturn')
1757
+ self.units_graph.add_edge('dim', 'uranus')
1758
+ self.units_graph.add_edge('dim', 'neptune')
1759
+
1760
+ self.units_graph.add_edge('dim', 'sun_mercury')
1761
+ self.units_graph.add_edge('dim', 'sun_venus')
1762
+ self.units_graph.add_edge('dim', 'sun_mars')
1763
+ self.units_graph.add_edge('dim', 'sun_jupiter')
1764
+ self.units_graph.add_edge('dim', 'sun_saturn')
1765
+ self.units_graph.add_edge('dim', 'sun_uranus')
1766
+ self.units_graph.add_edge('dim', 'sun_neptune')
1767
+
1358
1768
  def _units_transform(self, units1: str, units2: str) -> None:
1359
1769
  """
1360
1770
  FOR THE TOOLBOX DEVELOPERS ONLY.
@@ -1371,66 +1781,21 @@ class Trajectory:
1371
1781
 
1372
1782
  Units after transformation.
1373
1783
  """
1374
- if units1 == 'dim' and units2 == 'earth':
1784
+ if units1 == 'dim':
1375
1785
  if self.units_name != 'dim':
1376
1786
  raise Exception('Units should be dim.')
1377
1787
  if self.vars in ['rv', 'rvm', 'rv_stm']:
1378
- self._set_earth_units()
1788
+ self._set_units(units2)
1379
1789
  self._undim_rv()
1380
1790
  elif self.vars in ['ee', 'eem', 'ee_stm']:
1381
- self._set_earth_units()
1791
+ self._set_units(units2)
1382
1792
  self._undim_ee()
1383
1793
  elif self.vars in ['oe', 'oem', 'oe_stm']:
1384
- self._set_earth_units()
1794
+ self._set_units(units2)
1385
1795
  self._undim_oe()
1386
1796
  else:
1387
1797
  raise Exception('Unknown vars.')
1388
- self.units_name = 'earth'
1389
- elif units1 == 'dim' and units2 == 'moon':
1390
- if self.units_name != 'dim':
1391
- raise Exception('Units should be dim.')
1392
- if self.vars in ['rv', 'rvm', 'rv_stm']:
1393
- self._set_moon_units()
1394
- self._undim_rv()
1395
- elif self.vars in ['ee', 'eem', 'ee_stm']:
1396
- self._set_moon_units()
1397
- self._undim_ee()
1398
- elif self.vars in ['oe', 'oem', 'oe_stm']:
1399
- self._set_moon_units()
1400
- self._undim_oe()
1401
- else:
1402
- raise Exception('Unknown vars.')
1403
- self.units_name = 'moon'
1404
- elif units1 == 'dim' and units2 == 'earth_moon':
1405
- if self.units_name != 'dim':
1406
- raise Exception('Units should be dim.')
1407
- if self.vars in ['rv', 'rvm', 'rv_stm']:
1408
- self._set_earth_moon_units()
1409
- self._undim_rv()
1410
- elif self.vars in ['ee', 'eem', 'ee_stm']:
1411
- self._set_earth_moon_units()
1412
- self._undim_ee()
1413
- elif self.vars in ['oe', 'oem', 'oe_stm']:
1414
- self._set_earth_moon_units()
1415
- self._undim_oe()
1416
- else:
1417
- raise Exception('Unknown vars.')
1418
- self.units_name = 'earth_moon'
1419
- elif units1 == 'dim' and units2 == 'sun_earth':
1420
- if self.units_name != 'dim':
1421
- raise Exception('Units should be dim.')
1422
- if self.vars in ['rv', 'rvm', 'rv_stm']:
1423
- self._set_sun_earth_units()
1424
- self._undim_rv()
1425
- elif self.vars in ['ee', 'eem', 'ee_stm']:
1426
- self._set_sun_earth_units()
1427
- self._undim_ee()
1428
- elif self.vars in ['oe', 'oem', 'oe_stm']:
1429
- self._set_sun_earth_units()
1430
- self._undim_oe()
1431
- else:
1432
- raise Exception('Unknown vars.')
1433
- self.units_name = 'sun_earth'
1798
+ self.units_name = units2
1434
1799
  elif units2 == 'dim':
1435
1800
  if units1 != self.units_name:
1436
1801
  raise Exception(f'Not {units1} units.')
@@ -1442,7 +1807,7 @@ class Trajectory:
1442
1807
  self._dim_oe()
1443
1808
  else:
1444
1809
  raise Exception('Unknown vars.')
1445
- self._set_dim_units()
1810
+ self._set_units('dim')
1446
1811
  self.units_name = 'dim'
1447
1812
 
1448
1813
  def _undim_rv(self) -> None:
@@ -1453,6 +1818,8 @@ class Trajectory:
1453
1818
  self.times = self.times / self.units['TimeUnit']
1454
1819
  self.states[0:3, :] = self.states[0:3, :] / self.units['DistUnit']
1455
1820
  self.states[3:6, :] = self.states[3:6, :] / self.units['VelUnit']
1821
+ self.control_history = self.control_history / self.units['AccUnit']
1822
+ self.specific_impulse_history = self.specific_impulse_history / self.units['TimeUnit'] / 24 / 3600
1456
1823
 
1457
1824
  def _dim_rv(self) -> None:
1458
1825
  """
@@ -1462,6 +1829,8 @@ class Trajectory:
1462
1829
  self.times = self.times * self.units['TimeUnit']
1463
1830
  self.states[0:3, :] = self.states[0:3, :] * self.units['DistUnit']
1464
1831
  self.states[3:6, :] = self.states[3:6, :] * self.units['VelUnit']
1832
+ self.control_history = self.control_history * self.units['AccUnit']
1833
+ self.specific_impulse_history = self.specific_impulse_history * self.units['TimeUnit'] * 24 * 3600
1465
1834
 
1466
1835
  def _undim_ee(self) -> None:
1467
1836
  """
@@ -1470,6 +1839,8 @@ class Trajectory:
1470
1839
  """
1471
1840
  self.times = self.times / self.units['TimeUnit']
1472
1841
  self.states[0, :] = self.states[0, :] * self.units['VelUnit']
1842
+ self.control_history = self.control_history / self.units['AccUnit']
1843
+ self.specific_impulse_history = self.specific_impulse_history / self.units['TimeUnit'] / 24 / 3600
1473
1844
 
1474
1845
  def _dim_ee(self) -> None:
1475
1846
  """
@@ -1478,6 +1849,8 @@ class Trajectory:
1478
1849
  """
1479
1850
  self.times = self.times * self.units['TimeUnit']
1480
1851
  self.states[0, :] = self.states[0, :] / self.units['VelUnit']
1852
+ self.control_history = self.control_history * self.units['AccUnit']
1853
+ self.specific_impulse_history = self.specific_impulse_history * self.units['TimeUnit'] * 24 * 3600
1481
1854
 
1482
1855
  def _undim_oe(self) -> None:
1483
1856
  """
@@ -1486,6 +1859,8 @@ class Trajectory:
1486
1859
  """
1487
1860
  self.times = self.times / self.units['TimeUnit']
1488
1861
  self.states[0, :] = self.states[0, :] / self.units['DistUnit']
1862
+ self.control_history = self.control_history / self.units['AccUnit']
1863
+ self.specific_impulse_history = self.specific_impulse_history / self.units['TimeUnit'] / 24 / 3600
1489
1864
 
1490
1865
  def _dim_oe(self) -> None:
1491
1866
  """
@@ -1494,65 +1869,36 @@ class Trajectory:
1494
1869
  """
1495
1870
  self.times = self.times * self.units['TimeUnit']
1496
1871
  self.states[0, :] = self.states[0, :] * self.units['DistUnit']
1872
+ self.control_history = self.control_history * self.units['AccUnit']
1873
+ self.specific_impulse_history = self.specific_impulse_history * self.units['TimeUnit'] * 24 * 3600
1497
1874
 
1498
- def _set_earth_units(self) -> None:
1875
+ def _set_units(self, units_name: str) -> None:
1499
1876
  """
1500
1877
  FOR THE TOOLBOX DEVELOPERS ONLY.
1501
- Set coefficients for transformations to/from Earth units.
1878
+ Set coefficients for transformations to/from nondimensional units.
1502
1879
  """
1503
- ku = kiam.units('Earth')
1504
- self.units['mu'] = 1.0
1505
- self.units['DistUnit'] = ku['DistUnit'] # km
1506
- self.units['VelUnit'] = ku['VelUnit'] # km/s
1507
- self.units['TimeUnit'] = ku['TimeUnit'] # days
1508
- self.units['AccUnit'] = ku['AccUnit'] # m/s^2
1509
1880
 
1510
- def _set_moon_units(self) -> None:
1511
- """
1512
- FOR THE TOOLBOX DEVELOPERS ONLY.
1513
- Set coefficients for transformations to/from Moon units.
1514
- """
1515
- ku = kiam.units('Moon')
1516
- self.units['mu'] = 1.0
1517
- self.units['DistUnit'] = ku['DistUnit'] # km
1518
- self.units['VelUnit'] = ku['VelUnit'] # km/s
1519
- self.units['TimeUnit'] = ku['TimeUnit'] # days
1520
- self.units['AccUnit'] = ku['AccUnit'] # m/s^2
1881
+ if units_name == 'dim':
1882
+ ku = kiam.units('Earth')
1883
+ self.units['mu'] = ku['GM'] # km^3/s^2
1884
+ self.units['DistUnit'] = 1.0 # km
1885
+ self.units['VelUnit'] = 1.0 # km/s
1886
+ self.units['TimeUnit'] = 1.0 # days
1887
+ self.units['AccUnit'] = 1.0 # m/s^2
1888
+ return
1521
1889
 
1522
- def _set_earth_moon_units(self) -> None:
1523
- """
1524
- FOR THE TOOLBOX DEVELOPERS ONLY.
1525
- Set coefficients for transformations to/from Earth--Moon units.
1526
- """
1527
- ku = kiam.units('Earth', 'Moon')
1528
- self.units['DistUnit'] = ku['DistUnit'] # km
1529
- self.units['VelUnit'] = ku['VelUnit'] # km/s
1530
- self.units['TimeUnit'] = ku['TimeUnit'] # days
1531
- self.units['AccUnit'] = ku['AccUnit'] # m/s^2
1890
+ if '_' not in units_name:
1891
+ ku = kiam.units(units_name)
1892
+ else:
1893
+ units_name_splitted = units_name.split('_')
1894
+ ku = kiam.units(units_name_splitted[0], units_name_splitted[1])
1532
1895
 
1533
- def _set_sun_earth_units(self) -> None:
1534
- """
1535
- FOR THE TOOLBOX DEVELOPERS ONLY.
1536
- Set coefficients for transformations to/from Sun--Earth units.
1537
- """
1538
- ku = kiam.units('Sun', 'Earth')
1896
+ self.units['mu'] = 1.0
1539
1897
  self.units['DistUnit'] = ku['DistUnit'] # km
1540
1898
  self.units['VelUnit'] = ku['VelUnit'] # km/s
1541
1899
  self.units['TimeUnit'] = ku['TimeUnit'] # days
1542
1900
  self.units['AccUnit'] = ku['AccUnit'] # m/s^2
1543
1901
 
1544
- def _set_dim_units(self) -> None:
1545
- """
1546
- FOR THE TOOLBOX DEVELOPERS ONLY.
1547
- Set coefficients for transformations to/from dimensional units.
1548
- """
1549
- ku = kiam.units('Earth')
1550
- self.units['mu'] = ku['GM'] # km^3/s^2
1551
- self.units['DistUnit'] = 1.0 # km
1552
- self.units['VelUnit'] = 1.0 # km/s
1553
- self.units['TimeUnit'] = 1.0 # days
1554
- self.units['AccUnit'] = 1.0 # m/s^2
1555
-
1556
1902
  # Auxilary model routines.
1557
1903
  def _set_model_units(self, units_name: str) -> None:
1558
1904
  """
@@ -1569,31 +1915,15 @@ class Trajectory:
1569
1915
  'earth', 'moon', 'earth_moon', 'sun_earth'
1570
1916
  """
1571
1917
 
1572
- if units_name == 'earth':
1573
-
1574
- self.model['units']['name'] = 'earth'
1575
- units = kiam.units('Earth')
1576
- self.model['units']['mu'] = units['GM']
1577
-
1578
- elif units_name == 'moon':
1579
-
1580
- self.model['units']['name'] = 'moon'
1581
- units = kiam.units('Moon')
1582
- self.model['units']['mu'] = units['GM']
1583
-
1584
- elif units_name == 'earth_moon':
1585
-
1586
- self.model['units']['name'] = 'earth_moon'
1587
- units = kiam.units('Earth', 'Moon')
1588
-
1589
- elif units_name == 'sun_earth':
1590
-
1591
- self.model['units']['name'] = 'sun_earth'
1592
- units = kiam.units('Sun', 'Earth')
1918
+ self.model['units']['name'] = units_name
1593
1919
 
1920
+ if '_' not in units_name:
1921
+ units = kiam.units(units_name)
1594
1922
  else:
1923
+ units_name_splitted = units_name.split('_')
1924
+ units = kiam.units(units_name_splitted[0], units_name_splitted[1])
1595
1925
 
1596
- raise Exception('Unknown units_name.')
1926
+ self.model['units']['mu'] = units.get('GM')
1597
1927
 
1598
1928
  self.model['units']['DistUnit'] = units['DistUnit'] # km
1599
1929
  self.model['units']['VelUnit'] = units['VelUnit'] # km/s
@@ -1606,6 +1936,17 @@ class Trajectory:
1606
1936
  self.model['units']['REarth'] = planet['Earth']['EquatorRadius'] / units['DistUnit'] # 6378.1366 km
1607
1937
  self.model['units']['RMoon'] = moon['Moon']['MeanRadius'] / units['DistUnit'] # 1737.4 km
1608
1938
 
1939
+ self.model['units']['SunGM'] = units['SunGM']
1940
+ self.model['units']['MercuryGM'] = units['MercuryGM']
1941
+ self.model['units']['VenusGM'] = units['VenusGM']
1942
+ self.model['units']['EarthGM'] = units['EarthGM']
1943
+ self.model['units']['MoonGM'] = units['MoonGM']
1944
+ self.model['units']['MarsGM'] = units['MarsGM']
1945
+ self.model['units']['JupiterGM'] = units['JupiterGM']
1946
+ self.model['units']['SaturnGM'] = units['SaturnGM']
1947
+ self.model['units']['UranusGM'] = units['UranusGM']
1948
+ self.model['units']['NeptuneGM'] = units['NeptuneGM']
1949
+
1609
1950
  def _set_model_sources(self) -> None:
1610
1951
  """
1611
1952
  FOR THE TOOLBOX DEVELOPERS ONLY.
@@ -1638,7 +1979,9 @@ def traj2dict(tr: Trajectory) -> dict:
1638
1979
  d = {'vars': tr.vars, 'states': tr.states, 'times': tr.times,
1639
1980
  'system': tr.system, 'units_name': tr.units_name, 'jds': tr.jds,
1640
1981
  'initialDate': tr.initialDate, 'finalDate': tr.finalDate,
1641
- 'units': tr.units, 'parts': tr.parts, 'model': tr.model}
1982
+ 'units': tr.units, 'parts': tr.parts, 'model': tr.model,
1983
+ 'control_history': tr.control_history,
1984
+ 'specific_impulse_history': tr.specific_impulse_history}
1642
1985
  return d
1643
1986
 
1644
1987
 
@@ -1675,5 +2018,6 @@ def dict2traj(d: dict) -> Trajectory:
1675
2018
  tr.finalDate = d['finalDate']
1676
2019
  tr.units = d['units']
1677
2020
  tr.parts = d['parts']
1678
-
2021
+ tr.control_history = d['control_history']
2022
+ tr.specific_impulse_history = d['specific_impulse_history']
1679
2023
  return tr