imt-ring 1.6.39__tar.gz → 1.6.45__tar.gz

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.
Files changed (120) hide show
  1. {imt_ring-1.6.39 → imt_ring-1.6.45}/PKG-INFO +18 -14
  2. {imt_ring-1.6.39 → imt_ring-1.6.45}/pyproject.toml +4 -1
  3. {imt_ring-1.6.39 → imt_ring-1.6.45}/readme.md +17 -13
  4. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/imt_ring.egg-info/PKG-INFO +18 -14
  5. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/imt_ring.egg-info/SOURCES.txt +1 -0
  6. imt_ring-1.6.45/src/imt_ring.egg-info/entry_points.txt +2 -0
  7. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/base.py +8 -0
  8. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/base.py +6 -2
  9. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sim2real/sim2real.py +29 -5
  10. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_custom_joints.py +5 -5
  11. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_maths.py +6 -3
  12. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_ml_utils.py +1 -1
  13. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_random.py +2 -1
  14. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_train.py +5 -0
  15. {imt_ring-1.6.39 → imt_ring-1.6.45}/setup.cfg +0 -0
  16. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/imt_ring.egg-info/dependency_links.txt +0 -0
  17. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/imt_ring.egg-info/requires.txt +0 -0
  18. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/imt_ring.egg-info/top_level.txt +0 -0
  19. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/__init__.py +0 -0
  20. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algebra.py +0 -0
  21. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/__init__.py +0 -0
  22. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/_random.py +0 -0
  23. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/custom_joints/__init__.py +0 -0
  24. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/custom_joints/rr_imp_joint.py +0 -0
  25. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/custom_joints/rr_joint.py +0 -0
  26. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/custom_joints/rsaddle_joint.py +0 -0
  27. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/custom_joints/suntay.py +0 -0
  28. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/dynamics.py +0 -0
  29. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/__init__.py +0 -0
  30. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/batch.py +0 -0
  31. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/finalize_fns.py +0 -0
  32. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/motion_artifacts.py +0 -0
  33. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/pd_control.py +0 -0
  34. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/setup_fns.py +0 -0
  35. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/generator/types.py +0 -0
  36. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/jcalc.py +0 -0
  37. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/kinematics.py +0 -0
  38. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/algorithms/sensors.py +0 -0
  39. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/base.py +0 -0
  40. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/__init__.py +0 -0
  41. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/branched.xml +0 -0
  42. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/exclude/knee_trans_dof.xml +0 -0
  43. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/exclude/standard_sys.xml +0 -0
  44. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/exclude/standard_sys_rr_imp.xml +0 -0
  45. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/inv_pendulum.xml +0 -0
  46. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/knee_flexible_imus.xml +0 -0
  47. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/spherical_stiff.xml +0 -0
  48. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/symmetric.xml +0 -0
  49. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_all_1.xml +0 -0
  50. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_all_2.xml +0 -0
  51. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_ang0_pos0.xml +0 -0
  52. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_control.xml +0 -0
  53. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_double_pendulum.xml +0 -0
  54. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_free.xml +0 -0
  55. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_kinematics.xml +0 -0
  56. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_morph_system/four_seg_seg1.xml +0 -0
  57. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_morph_system/four_seg_seg3.xml +0 -0
  58. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_randomize_position.xml +0 -0
  59. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_sensors.xml +0 -0
  60. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples/test_three_seg_seg2.xml +0 -0
  61. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/examples.py +0 -0
  62. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/test_examples.py +0 -0
  63. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/__init__.py +0 -0
  64. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/abstract.py +0 -0
  65. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/from_xml.py +0 -0
  66. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/test_from_xml.py +0 -0
  67. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/test_to_xml.py +0 -0
  68. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/io/xml/to_xml.py +0 -0
  69. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/maths.py +0 -0
  70. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/__init__.py +0 -0
  71. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/callbacks.py +0 -0
  72. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/ml_utils.py +0 -0
  73. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/optimizer.py +0 -0
  74. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/params/0x13e3518065c21cd8.pickle +0 -0
  75. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/params/0x1d76628065a71e0f.pickle +0 -0
  76. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/ringnet.py +0 -0
  77. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/rnno_v1.py +0 -0
  78. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/train.py +0 -0
  79. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/ml/training_loop.py +0 -0
  80. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/rendering/__init__.py +0 -0
  81. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/rendering/base_render.py +0 -0
  82. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/rendering/mujoco_render.py +0 -0
  83. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/rendering/vispy_render.py +0 -0
  84. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/rendering/vispy_visuals.py +0 -0
  85. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sim2real/__init__.py +0 -0
  86. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/spatial.py +0 -0
  87. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sys_composer/__init__.py +0 -0
  88. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sys_composer/delete_sys.py +0 -0
  89. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sys_composer/inject_sys.py +0 -0
  90. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/sys_composer/morph_sys.py +0 -0
  91. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/__init__.py +0 -0
  92. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/backend.py +0 -0
  93. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/batchsize.py +0 -0
  94. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/colab.py +0 -0
  95. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/dataloader.py +0 -0
  96. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/dataloader_torch.py +0 -0
  97. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/hdf5.py +0 -0
  98. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/normalizer.py +0 -0
  99. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/path.py +0 -0
  100. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/randomize_sys.py +0 -0
  101. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/register_gym_envs/__init__.py +0 -0
  102. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/register_gym_envs/saddle.py +0 -0
  103. {imt_ring-1.6.39 → imt_ring-1.6.45}/src/ring/utils/utils.py +0 -0
  104. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_algebra.py +0 -0
  105. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_base.py +0 -0
  106. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_dynamics.py +0 -0
  107. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_generator.py +0 -0
  108. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_jcalc.py +0 -0
  109. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_jit.py +0 -0
  110. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_kinematics.py +0 -0
  111. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_motion_artifacts.py +0 -0
  112. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_pd_control.py +0 -0
  113. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_quickstart_example.py +0 -0
  114. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_randomize.py +0 -0
  115. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_rcmg.py +0 -0
  116. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_render.py +0 -0
  117. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_sensors.py +0 -0
  118. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_sim2real.py +0 -0
  119. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_sys_composer.py +0 -0
  120. {imt_ring-1.6.39 → imt_ring-1.6.45}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: imt-ring
3
- Version: 1.6.39
3
+ Version: 1.6.45
4
4
  Summary: RING: Recurrent Inertial Graph-based Estimator
5
5
  Author-email: Simon Bachhuber <simon.bachhuber@fau.de>
6
6
  Project-URL: Homepage, https://github.com/SimiPixel/ring
@@ -32,12 +32,15 @@ Requires-Dist: pytest-xdist; extra == "dev"
32
32
  Requires-Dist: nbmake; extra == "dev"
33
33
 
34
34
  <p align="center">
35
- <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/icon.svg" height="200" />
35
+ <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/concept_v4.png" height="200" />
36
36
  </p>
37
37
 
38
+
38
39
  # Recurrent Inertial Graph-based Estimator (RING)
39
40
  <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/coverage_badge.svg" height="20" />
40
41
 
42
+ RING provides a pluripotent, problem-unspecific plug-and-play IMT solution that, in contrast to conventional IMT solutions, eliminates the need for expert knowledge to identify, select, and parameterize the appropriate method. RING's pluripotency is enabled by a novel online-capable neural network architecture that uses a decentralized network of message-passing, parameter-sharing recurrent neural networks, which map local IMU measurements and nearest-neighbour messages to local orientations. This architecture enables RING to address a broad range of IMT problems that vary greatly in aspects such as the number of attached sensors, or the number of segments in the kinematic chain, and even generalize to previously unsolved IMT problems, including the challenging combination of magnetometer-free and sparse sensing with unknown sensor-to-segment parameters. Remarkably, RING is trained solely on simulated data, yet evaluated on experimental data, which indicates its exceptional ability to zero-shot generalize from simulation to experiment, while outperforming several state-of-the-art problem-specific solutions. For example, RING can, for the first time, accurately track a four-segment kinematic chain (which requires estimating four orientations) using only two magnetometer-free inertial measurement units.
43
+
41
44
  > **ℹ️ Tip:**
42
45
  >
43
46
  > Check out my new plug-and-play interface for inertial motion tracking (RING included) [here](https://github.com/simon-bachhuber/imt.git).
@@ -50,26 +53,23 @@ Install with `pip` using
50
53
 
51
54
  `pip install imt-ring`
52
55
 
53
- Typically, this will install `jax` as cpu-only version. Afterwards, gpu-enabled version can be installed with
54
- ```bash
55
- pip install --upgrade "jax[cuda12_pip]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
56
- ```
56
+ Typically, this will install `jax` as cpu-only version. For GPU install instructions for `jax` see https://github.com/jax-ml/jax?tab=readme-ov-file#instructions.
57
57
 
58
58
  ## Documentation
59
59
 
60
- Available [here](https://simipixel.github.io/ring/).
60
+ Available [here](https://simon-bachhuber.github.io/ring/).
61
61
 
62
62
  ## Quickstart Example
63
63
  ```python
64
64
  import ring
65
65
  import numpy as np
66
66
 
67
- T : int = 30 # sequence length [s]
68
- Ts : float = 0.01 # sampling interval [s]
69
- B : int = 1 # batch size
70
- lam: list[int] = [0, 1, 2] # parent array
71
- N : int = len(lam) # number of bodies
72
- T_i: int = int(T/Ts) # number of timesteps
67
+ T : int = 30 # sequence length [s]
68
+ Ts : float = 0.01 # sampling interval [s]
69
+ B : int = 1 # batch size
70
+ lam: list[int] = [-1, 0, 1] # parent array
71
+ N : int = len(lam) # number of bodies
72
+ T_i: int = int(T/Ts) # number of timesteps
73
73
 
74
74
  X = np.zeros((B, T_i, N, 9))
75
75
  # where X is structured as follows:
@@ -112,7 +112,11 @@ Solution:
112
112
 
113
113
  ## Publications
114
114
 
115
- The following publications utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
115
+ The main publication is:
116
+
117
+ - [*Recurrent Inertial Graph-Based Estimator (RING): A Single Pluripotent Inertial Motion Tracking Solution*](https://openreview.net/pdf?id=h2C3rkn0zR)
118
+
119
+ The following publications also utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
116
120
 
117
121
  - [*RNN-based Observability Analysis for Magnetometer-Free Sparse Inertial Motion Tracking*](https://ieeexplore.ieee.org/document/9841375)
118
122
  - [*Plug-and-Play Sparse Inertial Motion Tracking With Sim-to-Real Transfer*](https://ieeexplore.ieee.org/document/10225275)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "imt-ring"
7
- version = "1.6.39"
7
+ version = "1.6.45"
8
8
  authors = [
9
9
  { name="Simon Bachhuber", email="simon.bachhuber@fau.de" },
10
10
  ]
@@ -57,3 +57,6 @@ where = ["src"]
57
57
  [tool.setuptools.package-data]
58
58
  "ring.io.examples" = ["**/*.xml"]
59
59
  "ring.ml.params" = ["**/*.pickle"]
60
+
61
+ [project.scripts]
62
+ ring-view = "ring.extras.interactive_viewer:main"
@@ -1,10 +1,13 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/icon.svg" height="200" />
2
+ <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/concept_v4.png" height="200" />
3
3
  </p>
4
4
 
5
+
5
6
  # Recurrent Inertial Graph-based Estimator (RING)
6
7
  <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/coverage_badge.svg" height="20" />
7
8
 
9
+ RING provides a pluripotent, problem-unspecific plug-and-play IMT solution that, in contrast to conventional IMT solutions, eliminates the need for expert knowledge to identify, select, and parameterize the appropriate method. RING's pluripotency is enabled by a novel online-capable neural network architecture that uses a decentralized network of message-passing, parameter-sharing recurrent neural networks, which map local IMU measurements and nearest-neighbour messages to local orientations. This architecture enables RING to address a broad range of IMT problems that vary greatly in aspects such as the number of attached sensors, or the number of segments in the kinematic chain, and even generalize to previously unsolved IMT problems, including the challenging combination of magnetometer-free and sparse sensing with unknown sensor-to-segment parameters. Remarkably, RING is trained solely on simulated data, yet evaluated on experimental data, which indicates its exceptional ability to zero-shot generalize from simulation to experiment, while outperforming several state-of-the-art problem-specific solutions. For example, RING can, for the first time, accurately track a four-segment kinematic chain (which requires estimating four orientations) using only two magnetometer-free inertial measurement units.
10
+
8
11
  > **ℹ️ Tip:**
9
12
  >
10
13
  > Check out my new plug-and-play interface for inertial motion tracking (RING included) [here](https://github.com/simon-bachhuber/imt.git).
@@ -17,26 +20,23 @@ Install with `pip` using
17
20
 
18
21
  `pip install imt-ring`
19
22
 
20
- Typically, this will install `jax` as cpu-only version. Afterwards, gpu-enabled version can be installed with
21
- ```bash
22
- pip install --upgrade "jax[cuda12_pip]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
23
- ```
23
+ Typically, this will install `jax` as cpu-only version. For GPU install instructions for `jax` see https://github.com/jax-ml/jax?tab=readme-ov-file#instructions.
24
24
 
25
25
  ## Documentation
26
26
 
27
- Available [here](https://simipixel.github.io/ring/).
27
+ Available [here](https://simon-bachhuber.github.io/ring/).
28
28
 
29
29
  ## Quickstart Example
30
30
  ```python
31
31
  import ring
32
32
  import numpy as np
33
33
 
34
- T : int = 30 # sequence length [s]
35
- Ts : float = 0.01 # sampling interval [s]
36
- B : int = 1 # batch size
37
- lam: list[int] = [0, 1, 2] # parent array
38
- N : int = len(lam) # number of bodies
39
- T_i: int = int(T/Ts) # number of timesteps
34
+ T : int = 30 # sequence length [s]
35
+ Ts : float = 0.01 # sampling interval [s]
36
+ B : int = 1 # batch size
37
+ lam: list[int] = [-1, 0, 1] # parent array
38
+ N : int = len(lam) # number of bodies
39
+ T_i: int = int(T/Ts) # number of timesteps
40
40
 
41
41
  X = np.zeros((B, T_i, N, 9))
42
42
  # where X is structured as follows:
@@ -79,7 +79,11 @@ Solution:
79
79
 
80
80
  ## Publications
81
81
 
82
- The following publications utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
82
+ The main publication is:
83
+
84
+ - [*Recurrent Inertial Graph-Based Estimator (RING): A Single Pluripotent Inertial Motion Tracking Solution*](https://openreview.net/pdf?id=h2C3rkn0zR)
85
+
86
+ The following publications also utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
83
87
 
84
88
  - [*RNN-based Observability Analysis for Magnetometer-Free Sparse Inertial Motion Tracking*](https://ieeexplore.ieee.org/document/9841375)
85
89
  - [*Plug-and-Play Sparse Inertial Motion Tracking With Sim-to-Real Transfer*](https://ieeexplore.ieee.org/document/10225275)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: imt-ring
3
- Version: 1.6.39
3
+ Version: 1.6.45
4
4
  Summary: RING: Recurrent Inertial Graph-based Estimator
5
5
  Author-email: Simon Bachhuber <simon.bachhuber@fau.de>
6
6
  Project-URL: Homepage, https://github.com/SimiPixel/ring
@@ -32,12 +32,15 @@ Requires-Dist: pytest-xdist; extra == "dev"
32
32
  Requires-Dist: nbmake; extra == "dev"
33
33
 
34
34
  <p align="center">
35
- <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/icon.svg" height="200" />
35
+ <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/concept_v4.png" height="200" />
36
36
  </p>
37
37
 
38
+
38
39
  # Recurrent Inertial Graph-based Estimator (RING)
39
40
  <img src="https://raw.githubusercontent.com/simon-bachhuber/ring/main/docs/img/coverage_badge.svg" height="20" />
40
41
 
42
+ RING provides a pluripotent, problem-unspecific plug-and-play IMT solution that, in contrast to conventional IMT solutions, eliminates the need for expert knowledge to identify, select, and parameterize the appropriate method. RING's pluripotency is enabled by a novel online-capable neural network architecture that uses a decentralized network of message-passing, parameter-sharing recurrent neural networks, which map local IMU measurements and nearest-neighbour messages to local orientations. This architecture enables RING to address a broad range of IMT problems that vary greatly in aspects such as the number of attached sensors, or the number of segments in the kinematic chain, and even generalize to previously unsolved IMT problems, including the challenging combination of magnetometer-free and sparse sensing with unknown sensor-to-segment parameters. Remarkably, RING is trained solely on simulated data, yet evaluated on experimental data, which indicates its exceptional ability to zero-shot generalize from simulation to experiment, while outperforming several state-of-the-art problem-specific solutions. For example, RING can, for the first time, accurately track a four-segment kinematic chain (which requires estimating four orientations) using only two magnetometer-free inertial measurement units.
43
+
41
44
  > **ℹ️ Tip:**
42
45
  >
43
46
  > Check out my new plug-and-play interface for inertial motion tracking (RING included) [here](https://github.com/simon-bachhuber/imt.git).
@@ -50,26 +53,23 @@ Install with `pip` using
50
53
 
51
54
  `pip install imt-ring`
52
55
 
53
- Typically, this will install `jax` as cpu-only version. Afterwards, gpu-enabled version can be installed with
54
- ```bash
55
- pip install --upgrade "jax[cuda12_pip]" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html
56
- ```
56
+ Typically, this will install `jax` as cpu-only version. For GPU install instructions for `jax` see https://github.com/jax-ml/jax?tab=readme-ov-file#instructions.
57
57
 
58
58
  ## Documentation
59
59
 
60
- Available [here](https://simipixel.github.io/ring/).
60
+ Available [here](https://simon-bachhuber.github.io/ring/).
61
61
 
62
62
  ## Quickstart Example
63
63
  ```python
64
64
  import ring
65
65
  import numpy as np
66
66
 
67
- T : int = 30 # sequence length [s]
68
- Ts : float = 0.01 # sampling interval [s]
69
- B : int = 1 # batch size
70
- lam: list[int] = [0, 1, 2] # parent array
71
- N : int = len(lam) # number of bodies
72
- T_i: int = int(T/Ts) # number of timesteps
67
+ T : int = 30 # sequence length [s]
68
+ Ts : float = 0.01 # sampling interval [s]
69
+ B : int = 1 # batch size
70
+ lam: list[int] = [-1, 0, 1] # parent array
71
+ N : int = len(lam) # number of bodies
72
+ T_i: int = int(T/Ts) # number of timesteps
73
73
 
74
74
  X = np.zeros((B, T_i, N, 9))
75
75
  # where X is structured as follows:
@@ -112,7 +112,11 @@ Solution:
112
112
 
113
113
  ## Publications
114
114
 
115
- The following publications utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
115
+ The main publication is:
116
+
117
+ - [*Recurrent Inertial Graph-Based Estimator (RING): A Single Pluripotent Inertial Motion Tracking Solution*](https://openreview.net/pdf?id=h2C3rkn0zR)
118
+
119
+ The following publications also utilize this software library, and refer to it as the *Random Chain Motion Generator (RCMG)* (more specifically the function `ring.RCMG`):
116
120
 
117
121
  - [*RNN-based Observability Analysis for Magnetometer-Free Sparse Inertial Motion Tracking*](https://ieeexplore.ieee.org/document/9841375)
118
122
  - [*Plug-and-Play Sparse Inertial Motion Tracking With Sim-to-Real Transfer*](https://ieeexplore.ieee.org/document/10225275)
@@ -4,6 +4,7 @@ setup.cfg
4
4
  src/imt_ring.egg-info/PKG-INFO
5
5
  src/imt_ring.egg-info/SOURCES.txt
6
6
  src/imt_ring.egg-info/dependency_links.txt
7
+ src/imt_ring.egg-info/entry_points.txt
7
8
  src/imt_ring.egg-info/requires.txt
8
9
  src/imt_ring.egg-info/top_level.txt
9
10
  src/ring/__init__.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ring-view = ring.extras.interactive_viewer:main
@@ -1,5 +1,6 @@
1
1
  from dataclasses import replace
2
2
  from functools import partial
3
+ import logging
3
4
  import random
4
5
  from typing import Callable, Optional
5
6
  import warnings
@@ -20,6 +21,8 @@ from ring.algorithms.generator import motion_artifacts
20
21
  from ring.algorithms.generator import setup_fns
21
22
  from ring.algorithms.generator import types
22
23
 
24
+ logger = logging.getLogger(__name__)
25
+
23
26
 
24
27
  class RCMG:
25
28
  def __init__(
@@ -237,7 +240,9 @@ class RCMG:
237
240
  def _generators_ncalls(self, sizes: int | list[int] = 1):
238
241
  "Returns list of unbatched sequences as numpy arrays."
239
242
  repeats = self._compute_repeats(sizes)
243
+ logger.info(f"`repeats` = {repeats}")
240
244
  sizes = list(jnp.array(repeats) * jnp.array(self._size_of_generators))
245
+ logger.info(f"`sizes` = {sizes}")
241
246
 
242
247
  reduced_repeats = []
243
248
  n_calls = []
@@ -246,6 +251,9 @@ class RCMG:
246
251
  gcd = utils.gcd(n_call, repeat)
247
252
  n_calls.append(gcd)
248
253
  reduced_repeats.append(repeat // gcd)
254
+ logger.info(f"`reduced_repeats` = {reduced_repeats}")
255
+ logger.info(f"`n_calls` = {n_calls}")
256
+
249
257
  jits = [N > 1 for N in n_calls]
250
258
 
251
259
  gens = []
@@ -297,8 +297,12 @@ class NoGraph_FilterWrapper(AbstractFilterWrapper):
297
297
 
298
298
  if self._quat_normalize:
299
299
  assert yhat.shape[-1] == 4, f"yhat.shape={yhat.shape}"
300
- # yhat = ring.maths.safe_normalize(yhat)
301
- yhat = yhat / jnp.linalg.norm(yhat, axis=-1, keepdims=True)
300
+
301
+ # for exporting neural networks to ONNX format, you will have to use
302
+ # the first version, but for neural network training the second version
303
+ # is required
304
+ # yhat = yhat / jnp.linalg.norm(yhat, axis=-1, keepdims=True)
305
+ yhat = ring.maths.safe_normalize(yhat)
302
306
 
303
307
  return yhat, state
304
308
 
@@ -1,13 +1,14 @@
1
1
  from typing import Optional, Tuple
2
2
 
3
3
  import jax
4
+ import tree_utils
5
+
4
6
  from ring import algebra
5
7
  from ring import base
6
8
  from ring import io
7
9
  from ring import maths
8
10
  from ring.algorithms import generator
9
11
  from ring.algorithms import jcalc
10
- import tree_utils
11
12
 
12
13
 
13
14
  def xs_from_raw(
@@ -189,7 +190,14 @@ def delete_to_world_pos_rot(sys: base.System, xs: base.Transform) -> base.Transf
189
190
 
190
191
 
191
192
  def randomize_to_world_pos_rot(
192
- key: jax.Array, sys: base.System, xs: base.Transform, config: jcalc.MotionConfig
193
+ key: jax.Array,
194
+ sys: base.System,
195
+ xs: base.Transform,
196
+ config: jcalc.MotionConfig,
197
+ world_joint: str = "free",
198
+ cor: bool = False,
199
+ overwrite_q_ref: jax.Array = None,
200
+ damping=None,
193
201
  ) -> base.Transform:
194
202
  """Replace the transforms of all links that connect to the worldbody
195
203
  by randomize transforms.
@@ -210,14 +218,30 @@ def randomize_to_world_pos_rot(
210
218
  <x_xy>
211
219
  <options dt="0.01"/>
212
220
  <worldbody>
213
- <body name="free" joint="free"/>
221
+ <body name="free" joint="free" damping="15.0 15.0 15.0 25.0 25.0 25.0">
222
+ <geom type="box" mass="1" dim="0.1 0.1 0.1"/>
223
+ </body>
214
224
  </worldbody>
215
225
  </x_xy>
216
226
  """
217
-
218
227
  free_sys = io.load_sys_from_str(free_sys_str)
228
+
229
+ dynamic_simulation = True if overwrite_q_ref is not None else False
230
+
231
+ if world_joint != "free":
232
+ if dynamic_simulation:
233
+ assert damping is not None
234
+ free_sys = free_sys.change_joint_type("free", world_joint, new_damp=damping)
235
+
219
236
  _, xs_free = generator.RCMG(
220
- free_sys, config, finalize_fn=lambda key, q, x, sys: (q, x)
237
+ free_sys,
238
+ config,
239
+ finalize_fn=lambda key, q, x, sys: (q, x),
240
+ cor=cor,
241
+ dynamic_simulation=dynamic_simulation,
242
+ dynamic_simulation_kwargs=dict(
243
+ overwrite_q_ref=(overwrite_q_ref, free_sys.idx_map("q"))
244
+ ),
221
245
  ).to_lazy_gen()(key)
222
246
  xs_free = xs_free.take(0, axis=0)
223
247
  xs_free = xs_free.take(free_sys.name_to_idx("free"), axis=1)
@@ -41,7 +41,7 @@ def test_virtual_input_joint_axes_rr_joint():
41
41
  X = pipeline_load_data_X(sys)
42
42
 
43
43
  np.testing.assert_allclose(
44
- -X["seg1"]["joint_axes"],
44
+ X["seg1"]["joint_axes"],
45
45
  np.repeat(np.array([[0.0, 1, 0]]), 1000, axis=0),
46
46
  atol=2e-6,
47
47
  )
@@ -55,7 +55,7 @@ def test_virtual_input_joint_axes_rr_joint():
55
55
  X = pipeline_load_data_X(sys_rr)
56
56
 
57
57
  np.testing.assert_allclose(
58
- X["seg1"]["joint_axes"],
58
+ -X["seg1"]["joint_axes"],
59
59
  np.repeat(-joint_axes[1:2], 1000, axis=0),
60
60
  atol=2e-6,
61
61
  rtol=5e-4,
@@ -83,13 +83,13 @@ def test_virtual_input_joint_axes_rr_imp_joint():
83
83
  X = pipeline_load_data_X(sys_rr_imp)
84
84
 
85
85
  np.testing.assert_allclose(
86
- -X["seg1"]["joint_axes"],
86
+ X["seg1"]["joint_axes"],
87
87
  np.repeat(joint_axes[1:2], 1000, axis=0),
88
88
  atol=0.01,
89
89
  rtol=0.02,
90
90
  )
91
91
  np.testing.assert_allclose(
92
- -X["seg3"]["joint_axes"],
92
+ X["seg3"]["joint_axes"],
93
93
  np.repeat(joint_axes[3:4], 1000, axis=0),
94
94
  atol=0.01,
95
95
  rtol=0.032,
@@ -101,7 +101,7 @@ def test_virtual_input_joint_axes_rr_imp_joint():
101
101
  X = pipeline_load_data_X(sys)
102
102
 
103
103
  np.testing.assert_allclose(
104
- -X["seg1"]["joint_axes"],
104
+ X["seg1"]["joint_axes"],
105
105
  np.repeat(np.array([[0.0, 1, 0]]), 1000, axis=0),
106
106
  atol=2e-6,
107
107
  )
@@ -1,9 +1,10 @@
1
1
  import jax
2
2
  import jax.numpy as jnp
3
3
  import numpy as np
4
- from ring import maths
5
4
  import tree_utils
6
5
 
6
+ from ring import maths
7
+
7
8
 
8
9
  def test_quat_rot_axis_are_inverse():
9
10
  q = maths.quat_random(
@@ -12,7 +13,8 @@ def test_quat_rot_axis_are_inverse():
12
13
  )
13
14
  )
14
15
  axis, angle = maths.quat_to_rot_axis(q)
15
- assert tree_utils.tree_close(q, maths.quat_rot_axis(axis, angle))
16
+ # since jax >= v0.5 it (for some reason) returns q -> -q
17
+ assert tree_utils.tree_close(q, -maths.quat_rot_axis(axis, angle))
16
18
 
17
19
 
18
20
  def test_3x3_are_inverse():
@@ -23,7 +25,8 @@ def test_3x3_are_inverse():
23
25
  )
24
26
  mat = maths.quat_to_3x3(q)
25
27
 
26
- np.testing.assert_allclose(q, maths.quat_from_3x3(mat), rtol=1e-5, atol=1e-5)
28
+ # since jax >= v0.5 it (for some reason) returns q -> -q
29
+ np.testing.assert_allclose(q, -maths.quat_from_3x3(mat), rtol=1e-5, atol=1e-5)
27
30
  np.testing.assert_allclose(
28
31
  mat, maths.quat_to_3x3(maths.quat_from_3x3(mat)), rtol=1e-5, atol=1e-5
29
32
  )
@@ -149,7 +149,7 @@ def test_wandb_logger():
149
149
  logger.log({"awesome_array": np.array(1.0)})
150
150
  logger.log({"awesome_string": "yay"})
151
151
 
152
- root = Path(__file__).parent.parent.joinpath("test_ml_utils_assets")
152
+ root = Path(__file__).parent.joinpath("test_ml_utils_assets")
153
153
 
154
154
  logger.log_image(str(root.joinpath("image1.png")))
155
155
  logger.log_image(str(root.joinpath("image2.png")))
@@ -18,7 +18,8 @@ from ring.algorithms._random import _resolve_range_of_motion
18
18
  def test_delta_ang_min_max(
19
19
  range_of_motion, range_of_motion_method, delta_ang_min, delta_ang_max
20
20
  ):
21
- max_iter = 100
21
+ # add more patience if `delta_ang_max` is small (thus very unlikely)
22
+ max_iter = 200 if delta_ang_max == 0.1 else 100
22
23
  t_min, t_max = 0.1, 3.1
23
24
  for seed in range(10):
24
25
  for prev_phi in [-3.0, 0.0, 3.0]:
@@ -7,6 +7,11 @@ import tree_utils
7
7
  import ring
8
8
  from ring import ml
9
9
  from ring import utils
10
+ import wandb
11
+
12
+ # make sure that `ml.train_fn` doesn't think wandb is running and automatically
13
+ # add a `WandBLogger`
14
+ wandb.run = None
10
15
 
11
16
 
12
17
  def _load_gen_lam():
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes