agx-openplx 0.15.10__cp312-cp312-manylinux_2_39_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. agx_openplx-0.15.10.dist-info/METADATA +67 -0
  2. agx_openplx-0.15.10.dist-info/RECORD +41 -0
  3. agx_openplx-0.15.10.dist-info/WHEEL +4 -0
  4. agx_openplx-0.15.10.dist-info/entry_points.txt +8 -0
  5. openplx/Core.py +7781 -0
  6. openplx/DriveTrain.py +8972 -0
  7. openplx/Math.py +5372 -0
  8. openplx/Physics.py +39861 -0
  9. openplx/Physics1D.py +5534 -0
  10. openplx/Physics3D.py +39782 -0
  11. openplx/Robotics.py +14922 -0
  12. openplx/Simulation.py +1056 -0
  13. openplx/Terrain.py +3891 -0
  14. openplx/Urdf.py +654 -0
  15. openplx/Vehicles.py +8793 -0
  16. openplx/Visuals.py +3901 -0
  17. openplx/_AgxOpenPlxPyApi.cpython-312-x86_64-linux-gnu.so +0 -0
  18. openplx/_CorePythonSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  19. openplx/_DriveTrainSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  20. openplx/_MathSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  21. openplx/_Physics1DSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  22. openplx/_Physics3DSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  23. openplx/_PhysicsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  24. openplx/_RoboticsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  25. openplx/_SimulationSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  26. openplx/_TerrainSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  27. openplx/_UrdfSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  28. openplx/_VehiclesSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  29. openplx/_VisualsSwig.cpython-312-x86_64-linux-gnu.so +0 -0
  30. openplx/__init__.py +55 -0
  31. openplx/agxtoopenplx.py +55 -0
  32. openplx/anytoopenplx.py +44 -0
  33. openplx/api.py +1353 -0
  34. openplx/migrate.py +190 -0
  35. openplx/migration_hint.py +14 -0
  36. openplx/migrations.py +703 -0
  37. openplx/openplx_application.py +138 -0
  38. openplx/openplx_serialize.py +35 -0
  39. openplx/openplx_validate.py +57 -0
  40. openplx/openplx_view.py +14 -0
  41. openplx/versionaction.py +11 -0
openplx/migrations.py ADDED
@@ -0,0 +1,703 @@
1
+ """
2
+ This module contains migration functions that can be used to refactor code in a backwards compatible way.
3
+ """
4
+
5
+ import functools
6
+ import sys
7
+ import re
8
+ from pathlib import Path
9
+ import itertools
10
+ from abc import ABC, abstractmethod
11
+ from openplx.Core import RefactorReplaceOp, RefactorToolkit
12
+
13
+
14
+ def migration(from_version: str, to_version: str, order: int = 0):
15
+ def decorator(func):
16
+ @functools.wraps(func)
17
+ def wrapper(*args, **kwargs):
18
+ result = func(*args, **kwargs)
19
+ return result
20
+
21
+ wrapper.openplx_from_version = from_version
22
+ wrapper.openplx_to_version = to_version
23
+ wrapper.openplx_order = order
24
+ return wrapper
25
+
26
+ return decorator
27
+
28
+ @migration("0.9.3", "0.10.0")
29
+ def snakecaseify_methods_093(documents): # pylint: disable=too-many-statements
30
+ ops = []
31
+ ops.extend(RefactorToolkit.renameMethod(documents, "Math.Vec3.fromXYZ", "from_xyz"))
32
+ ops.extend(
33
+ RefactorToolkit.renameMethod(
34
+ documents, "Math.Vec3.angleBetweenVectors", "angle_between_vectors"
35
+ )
36
+ )
37
+ ops.extend(
38
+ RefactorToolkit.renameMethod(
39
+ documents, "Math.Vec3.getOrthogonalUnitVector", "get_orthogonal_unit_vector"
40
+ )
41
+ )
42
+ ops.extend(
43
+ RefactorToolkit.renameMethod(documents, "Math.Quat.angleAxis", "angle_axis")
44
+ )
45
+ ops.extend(RefactorToolkit.renameMethod(documents, "Math.Quat.fromTo", "from_to"))
46
+ ops.extend(
47
+ RefactorToolkit.renameMethod(documents, "Math.Quat.fromXYZW", "from_xyzw")
48
+ )
49
+ ops.extend(
50
+ RefactorToolkit.renameMethod(
51
+ documents, "Math.AffineTransform.fromAxes", "from_axes"
52
+ )
53
+ )
54
+ ops.extend(
55
+ RefactorToolkit.renameMethod(
56
+ documents, "Math.AffineTransform.inverseOf", "inverse_of"
57
+ )
58
+ )
59
+ ops.extend(
60
+ RefactorToolkit.renameMethod(
61
+ documents, "Math.AffineTransform.transformVec3Point", "transform_vec3_point"
62
+ )
63
+ )
64
+ ops.extend(
65
+ RefactorToolkit.renameMethod(
66
+ documents,
67
+ "Math.AffineTransform.transformVec3Vector",
68
+ "transform_vec3_vector",
69
+ )
70
+ )
71
+ ops.extend(
72
+ RefactorToolkit.renameMethod(
73
+ documents, "Math.Matrix3x3.fromRowMajor", "from_row_major"
74
+ )
75
+ )
76
+ ops.extend(
77
+ RefactorToolkit.renameMethod(documents, "Math.Matrix3x3.fromRows", "from_rows")
78
+ )
79
+ ops.extend(
80
+ RefactorToolkit.renameMethod(
81
+ documents, "Math.Matrix3x3.fromColumns", "from_columns"
82
+ )
83
+ )
84
+ ops.extend(
85
+ RefactorToolkit.renameMethod(
86
+ documents, "Math.Matrix4x4.fromRowMajor", "from_row_major"
87
+ )
88
+ )
89
+ ops.extend(
90
+ RefactorToolkit.renameMethod(documents, "Math.Matrix4x4.fromRows", "from_rows")
91
+ )
92
+ ops.extend(
93
+ RefactorToolkit.renameMethod(
94
+ documents, "Math.Matrix4x4.fromColumns", "from_columns"
95
+ )
96
+ )
97
+ ops.extend(
98
+ RefactorToolkit.renameMethod(
99
+ documents, "Math.Matrix4x4.fromVec3Quat", "from_vec3_quat"
100
+ )
101
+ )
102
+ ops.extend(
103
+ RefactorToolkit.renameMethod(
104
+ documents, "Math.Matrix4x4.getAffineTranslation", "get_affine_translation"
105
+ )
106
+ )
107
+ ops.extend(
108
+ RefactorToolkit.renameMethod(
109
+ documents, "Math.Matrix4x4.getAffineRotation", "get_affine_rotation"
110
+ )
111
+ )
112
+ ops.extend(
113
+ RefactorToolkit.renameMethod(
114
+ documents, "Functions.harmonicMean", "harmonic_mean"
115
+ )
116
+ )
117
+ ops.extend(
118
+ RefactorToolkit.renameMethod(documents, "Math.Line.fromPoints", "from_points")
119
+ )
120
+ # ValueOutputSignal
121
+ ops.extend(
122
+ RefactorToolkit.renameMethod(
123
+ documents, "Physics.Signals.ValueOutputSignal.fromAngle", "from_angle"
124
+ )
125
+ )
126
+ ops.extend(
127
+ RefactorToolkit.renameMethod(
128
+ documents,
129
+ "Physics.Signals.ValueOutputSignal.fromAngularVelocity1D",
130
+ "from_angular_velocity_1d",
131
+ )
132
+ )
133
+ ops.extend(
134
+ RefactorToolkit.renameMethod(
135
+ documents, "Physics.Signals.ValueOutputSignal.fromDistance", "from_distance"
136
+ )
137
+ )
138
+ ops.extend(
139
+ RefactorToolkit.renameMethod(
140
+ documents, "Physics.Signals.ValueOutputSignal.fromForce1D", "from_force_1d"
141
+ )
142
+ )
143
+ ops.extend(
144
+ RefactorToolkit.renameMethod(
145
+ documents,
146
+ "Physics.Signals.ValueOutputSignal.fromVelocity1D",
147
+ "from_velocity_1d",
148
+ )
149
+ )
150
+ ops.extend(
151
+ RefactorToolkit.renameMethod(
152
+ documents,
153
+ "Physics.Signals.ValueOutputSignal.fromTorque1D",
154
+ "from_torque_1d",
155
+ )
156
+ )
157
+ ops.extend(
158
+ RefactorToolkit.renameMethod(
159
+ documents,
160
+ "Physics.Signals.ValueOutputSignal.fromAcceleration3D",
161
+ "from_acceleration_3d",
162
+ )
163
+ )
164
+ ops.extend(
165
+ RefactorToolkit.renameMethod(
166
+ documents,
167
+ "Physics.Signals.ValueOutputSignal.fromAngularAcceleration3D",
168
+ "from_angular_acceleration_3d",
169
+ )
170
+ )
171
+ ops.extend(
172
+ RefactorToolkit.renameMethod(
173
+ documents,
174
+ "Physics.Signals.ValueOutputSignal.fromAngularVelocity3D",
175
+ "from_angular_velocity_3d",
176
+ )
177
+ )
178
+ ops.extend(
179
+ RefactorToolkit.renameMethod(
180
+ documents, "Physics.Signals.ValueOutputSignal.fromForce3D", "from_force_3d"
181
+ )
182
+ )
183
+ ops.extend(
184
+ RefactorToolkit.renameMethod(
185
+ documents,
186
+ "Physics.Signals.ValueOutputSignal.fromTorque3D",
187
+ "from_torque_3d",
188
+ )
189
+ )
190
+ ops.extend(
191
+ RefactorToolkit.renameMethod(
192
+ documents,
193
+ "Physics.Signals.ValueOutputSignal.fromVelocity3D",
194
+ "from_velocity_3d",
195
+ )
196
+ )
197
+ ops.extend(
198
+ RefactorToolkit.renameMethod(
199
+ documents,
200
+ "Physics.Signals.ValueOutputSignal.fromPosition3D",
201
+ "from_position_3d",
202
+ )
203
+ )
204
+ ops.extend(
205
+ RefactorToolkit.renameMethod(
206
+ documents, "Physics.Signals.ValueOutputSignal.fromRPY", "from_rpy"
207
+ )
208
+ )
209
+ ops.extend(
210
+ RefactorToolkit.renameMethod(
211
+ documents, "Physics.Signals.ValueOutputSignal.isReal", "is_real"
212
+ )
213
+ )
214
+ ops.extend(
215
+ RefactorToolkit.renameMethod(
216
+ documents, "Physics.Signals.ValueOutputSignal.asReal", "as_real"
217
+ )
218
+ )
219
+ ops.extend(
220
+ RefactorToolkit.renameMethod(
221
+ documents, "Physics.Signals.ValueOutputSignal.asVec3", "as_vec3"
222
+ )
223
+ )
224
+ ops.extend(
225
+ RefactorToolkit.renameMethod(
226
+ documents, "Physics.Signals.ValueOutputSignal.asAngle", "as_angle"
227
+ )
228
+ )
229
+ ops.extend(
230
+ RefactorToolkit.renameMethod(
231
+ documents,
232
+ "Physics.Signals.ValueOutputSignal.asAngularVelocity1D",
233
+ "as_angular_velocity_1d",
234
+ )
235
+ )
236
+ ops.extend(
237
+ RefactorToolkit.renameMethod(
238
+ documents, "Physics.Signals.ValueOutputSignal.asDistance", "as_distance"
239
+ )
240
+ )
241
+ ops.extend(
242
+ RefactorToolkit.renameMethod(
243
+ documents, "Physics.Signals.ValueOutputSignal.asForce1D", "as_force_1d"
244
+ )
245
+ )
246
+ ops.extend(
247
+ RefactorToolkit.renameMethod(
248
+ documents,
249
+ "Physics.Signals.ValueOutputSignal.asVelocity1D",
250
+ "as_velocity_1d",
251
+ )
252
+ )
253
+ ops.extend(
254
+ RefactorToolkit.renameMethod(
255
+ documents, "Physics.Signals.ValueOutputSignal.asTorque1D", "as_torque_1d"
256
+ )
257
+ )
258
+ ops.extend(
259
+ RefactorToolkit.renameMethod(
260
+ documents,
261
+ "Physics.Signals.ValueOutputSignal.asAcceleration3D",
262
+ "as_acceleration_3d",
263
+ )
264
+ )
265
+ ops.extend(
266
+ RefactorToolkit.renameMethod(
267
+ documents,
268
+ "Physics.Signals.ValueOutputSignal.asAngularAcceleration3D",
269
+ "as_angular_acceleration_3d",
270
+ )
271
+ )
272
+ ops.extend(
273
+ RefactorToolkit.renameMethod(
274
+ documents,
275
+ "Physics.Signals.ValueOutputSignal.asAngularVelocity3D",
276
+ "as_angular_velocity_3d",
277
+ )
278
+ )
279
+ ops.extend(
280
+ RefactorToolkit.renameMethod(
281
+ documents, "Physics.Signals.ValueOutputSignal.asForce3D", "as_force_3d"
282
+ )
283
+ )
284
+ ops.extend(
285
+ RefactorToolkit.renameMethod(
286
+ documents, "Physics.Signals.ValueOutputSignal.asTorque3D", "as_torque_3d"
287
+ )
288
+ )
289
+ ops.extend(
290
+ RefactorToolkit.renameMethod(
291
+ documents,
292
+ "Physics.Signals.ValueOutputSignal.asVelocity3D",
293
+ "as_velocity_3d",
294
+ )
295
+ )
296
+ ops.extend(
297
+ RefactorToolkit.renameMethod(
298
+ documents,
299
+ "Physics.Signals.ValueOutputSignal.asPosition3D",
300
+ "as_position_3d",
301
+ )
302
+ )
303
+ ops.extend(
304
+ RefactorToolkit.renameMethod(
305
+ documents, "Robotics.Signals.RobotInputSignal.fromValues", "from_values"
306
+ )
307
+ )
308
+
309
+ # DriveTrain.Signals
310
+ ops.extend(
311
+ RefactorToolkit.moveAndRenameModel(
312
+ documents,
313
+ "DriveTrain.Signals.CombustionEngineThrottleInput",
314
+ "Physics.Signals",
315
+ "FractionInput",
316
+ )
317
+ )
318
+ ops.extend(
319
+ RefactorToolkit.moveAndRenameModel(
320
+ documents,
321
+ "DriveTrain.Signals.CombustionEngineTorqueOutput",
322
+ "Physics.Signals",
323
+ "Torque1DOutput",
324
+ )
325
+ )
326
+ ops.extend(
327
+ RefactorToolkit.moveAndRenameModel(
328
+ documents,
329
+ "DriveTrain.Signals.GearTorqueOutput",
330
+ "Physics.Signals",
331
+ "Torque1DOutput",
332
+ )
333
+ )
334
+
335
+ return [ReplaceOp(op) for op in ops]
336
+
337
+
338
+ @migration("0.10.3", "0.11.0")
339
+ def migrations_for_0_10_3(documents):
340
+ ops = []
341
+ # Physics3D.Transform -> Math.AffineTransform
342
+ ops.extend(
343
+ RefactorToolkit.moveAndRenameModel(
344
+ documents, "Physics3D.Transform", "Math", "AffineTransform"
345
+ )
346
+ )
347
+ # Robotics.Joints.FlexibleVelocityJoint -> Robotics.Joints.FlexibleAngularVelocityJoint
348
+ ops.extend(
349
+ RefactorToolkit.renameModel(
350
+ documents,
351
+ "Robotics.Joints.FlexibleVelocityJoint",
352
+ "FlexibleAngularVelocityJoint",
353
+ )
354
+ )
355
+ ops.extend(
356
+ RefactorToolkit.renameModel(
357
+ documents,
358
+ "Physics3D.Signals.MateConnector.Velocity3DOutput",
359
+ "LinearVelocity3DOutput",
360
+ )
361
+ )
362
+ return [ReplaceOp(op) for op in ops]
363
+
364
+
365
+ @migration("0.11.0", "0.11.1")
366
+ def migrations_for_0_11_0(documents):
367
+ ops = []
368
+ ops.extend(
369
+ RefactorToolkit.renameModel(
370
+ documents,
371
+ "Physics3D.Signals.RigidBodyVelocityOutput",
372
+ "LinearVelocity3DOutput",
373
+ )
374
+ )
375
+ ops.extend(
376
+ RefactorToolkit.renameAttribute(
377
+ documents, "Physics3D.Signals.RigidBodyVelocityOutput.rigid_body", "source"
378
+ )
379
+ )
380
+ return [ReplaceOp(op) for op in ops]
381
+
382
+
383
+ @migration("0.12.1", "0.12.2")
384
+ def migrations_for_0_12_1(documents):
385
+ ops = []
386
+ ops.extend(
387
+ RefactorToolkit.moveAndRenameModel(
388
+ documents,
389
+ "Physics3D.Signals.PrismaticVelocityOutput",
390
+ "Physics.Signals",
391
+ "LinearVelocity1DOutput",
392
+ )
393
+ )
394
+ ops.extend(
395
+ RefactorToolkit.renameAttribute(
396
+ documents, "Physics3D.Signals.PrismaticVelocityOutput.prismatic", "source"
397
+ )
398
+ )
399
+ ops.extend(
400
+ RefactorToolkit.renameAttribute(
401
+ documents,
402
+ "DriveTrain.ManualClutch.initial_opening_fraction",
403
+ "initial_engagement_fraction",
404
+ )
405
+ )
406
+ ops.extend(
407
+ RefactorToolkit.renameAttribute(
408
+ documents,
409
+ "DriveTrain.ManualClutch.opening_fraction_input",
410
+ "engagement_fraction_input",
411
+ )
412
+ )
413
+ ops.extend(
414
+ RefactorToolkit.renameAttribute(
415
+ documents,
416
+ "DriveTrain.ManualClutch.opening_fraction_output",
417
+ "engagement_fraction_output",
418
+ )
419
+ )
420
+ ops.extend(
421
+ RefactorToolkit.renameAttribute(
422
+ documents,
423
+ "DriveTrain.AutomaticClutch.engage_time",
424
+ "engagement_time",
425
+ )
426
+ )
427
+
428
+ return [ReplaceOp(op) for op in ops]
429
+
430
+
431
+ @migration("0.13.1", "0.13.2")
432
+ def migrations_for_0_13_1(documents):
433
+ ops = []
434
+ # DriveTrain.Gear -> DriveTrain.FlexibleGear
435
+ ops.extend(
436
+ RefactorToolkit.renameModel(
437
+ documents,
438
+ "DriveTrain.Gear",
439
+ "FlexibleGear",
440
+ )
441
+ )
442
+
443
+ return [ReplaceOp(op) for op in ops]
444
+
445
+ @migration("0.14.0", "0.15.0")
446
+ def rename_from_brick_to_openplx(document_path):
447
+
448
+ return ChangeExtensionOp(Path(document_path), ".openplx")
449
+
450
+
451
+ @migration("0.15.1", "0.15.2")
452
+ def migrations_for_0_15_1(documents):
453
+ ops = []
454
+ ops.extend(
455
+ RefactorToolkit.renameModel(
456
+ documents,
457
+ "Robotics.Joints.TorqueDriveTrain",
458
+ "FlexibleJointDriveTrain",
459
+ )
460
+ )
461
+ ops.extend(
462
+ RefactorToolkit.renameModel(
463
+ documents,
464
+ "Robotics.Joints.AngularVelocityDriveTrain",
465
+ "FlexibleJointDriveTrain",
466
+ )
467
+ )
468
+ ops.extend(
469
+ RefactorToolkit.moveAndRenameModel(
470
+ documents,
471
+ "Physics3D.Signals.HingeAngularVelocityOutput",
472
+ "Physics.Signals",
473
+ "AngularVelocity1DOutput",
474
+ )
475
+ )
476
+ ops.extend(
477
+ RefactorToolkit.renameAttribute(
478
+ documents, "Physics3D.Signals.HingeAngularVelocityOutput.hinge", "source"
479
+ )
480
+ )
481
+ ops.extend(
482
+ RefactorToolkit.moveAndRenameModel(
483
+ documents,
484
+ "DriveTrain.Signals.TorqueMotorInput",
485
+ "Physics.Signals",
486
+ "Torque1DInput",
487
+ )
488
+ )
489
+ ops.extend(
490
+ RefactorToolkit.renameAttribute(
491
+ documents, "DriveTrain.Signals.TorqueMotorInput.motor", "source"
492
+ )
493
+ )
494
+ ops.extend(
495
+ RefactorToolkit.moveAndRenameModel(
496
+ documents,
497
+ "Physics3D.Signals.LinearSpringPositionInput",
498
+ "Physics.Signals",
499
+ "Position1DInput",
500
+ )
501
+ )
502
+ ops.extend(
503
+ RefactorToolkit.renameAttribute(
504
+ documents, "Physics3D.Signals.LinearSpringPositionInput.spring", "source"
505
+ )
506
+ )
507
+ ops.extend(
508
+ RefactorToolkit.moveAndRenameModel(
509
+ documents,
510
+ "Physics3D.Signals.TorsionSpringAngleInput",
511
+ "Physics.Signals",
512
+ "AngleInput",
513
+ )
514
+ )
515
+ ops.extend(
516
+ RefactorToolkit.renameAttribute(
517
+ documents, "Physics3D.Signals.TorsionSpringAngleInput.spring", "source"
518
+ )
519
+ )
520
+ ops.extend(
521
+ RefactorToolkit.moveAndRenameModel(
522
+ documents,
523
+ "Physics3D.Signals.RigidBodyRPYOutput",
524
+ "Physics3D.Signals",
525
+ "RPYOutput",
526
+ )
527
+ )
528
+ ops.extend(
529
+ RefactorToolkit.renameAttribute(
530
+ documents, "Physics3D.Signals.RigidBodyRPYOutput.rigid_body", "source"
531
+ )
532
+ )
533
+ ops.extend(
534
+ RefactorToolkit.moveAndRenameModel(
535
+ documents,
536
+ "Physics3D.Signals.RigidBodyPositionOutput",
537
+ "Physics3D.Signals",
538
+ "Position3DOutput",
539
+ )
540
+ )
541
+ ops.extend(
542
+ RefactorToolkit.renameAttribute(
543
+ documents, "Physics3D.Signals.RigidBodyPositionOutput.rigid_body", "source"
544
+ )
545
+ )
546
+ ops.extend(
547
+ RefactorToolkit.renameAttribute(
548
+ documents, "Physics3D.Interactions.VelocityMotor.desired_speed", "target_speed"
549
+ )
550
+ )
551
+ ops.extend(
552
+ RefactorToolkit.renameAttribute(
553
+ documents, "Physics1D.Interactions.VelocityMotor.desired_speed", "target_speed"
554
+ )
555
+ )
556
+ ops.extend(
557
+ RefactorToolkit.moveAndRenameModel(
558
+ documents,
559
+ "Physics3D.Signals.RotationalVelocityMotorVelocityInput",
560
+ "Physics.Signals",
561
+ "AngularVelocity1DInput",
562
+ )
563
+ )
564
+ ops.extend(
565
+ RefactorToolkit.renameAttribute(
566
+ documents, "Physics3D.Signals.RotationalVelocityMotorVelocityInput.motor", "source"
567
+ )
568
+ )
569
+ ops.extend(
570
+ RefactorToolkit.moveAndRenameModel(
571
+ documents,
572
+ "Physics1D.Signals.RotationalVelocityMotor1DVelocityInput",
573
+ "Physics.Signals",
574
+ "AngularVelocity1DInput",
575
+ )
576
+ )
577
+ ops.extend(
578
+ RefactorToolkit.renameAttribute(
579
+ documents, "Physics1D.Signals.RotationalVelocityMotor1DVelocityInput.motor", "source"
580
+ )
581
+ )
582
+ ops.extend(
583
+ RefactorToolkit.moveAndRenameModel(
584
+ documents,
585
+ "Physics3D.Signals.LinearVelocityMotorVelocityInput",
586
+ "Physics.Signals",
587
+ "LinearVelocity1DInput",
588
+ )
589
+ )
590
+ ops.extend(
591
+ RefactorToolkit.renameAttribute(
592
+ documents, "Physics3D.Signals.LinearVelocityMotorVelocityInput.motor", "source"
593
+ )
594
+ )
595
+ ops.extend(
596
+ RefactorToolkit.moveAndRenameModel(
597
+ documents,
598
+ "Physics1D.Signals.RotationalBodyAngularVelocityOutput",
599
+ "Physics.Signals",
600
+ "AngularVelocity1DOutput",
601
+ )
602
+ )
603
+ ops.extend(
604
+ RefactorToolkit.renameAttribute(
605
+ documents, "Physics1D.Signals.RotationalBodyAngularVelocityOutput.body", "source"
606
+ )
607
+ )
608
+ ops.extend(
609
+ RefactorToolkit.moveAndRenameModel(
610
+ documents,
611
+ "Physics1D.Signals.RotationalBodyAngleOutput",
612
+ "Physics.Signals",
613
+ "AngleOutput",
614
+ )
615
+ )
616
+ ops.extend(
617
+ RefactorToolkit.renameAttribute(
618
+ documents, "Physics1D.Signals.RotationalBodyAngleOutput.body", "source"
619
+ )
620
+ )
621
+
622
+ return [ReplaceOp(op) for op in ops]
623
+
624
+
625
+ def split_version(v):
626
+ match = re.match(r"^(\d+)\.(\d+)\.(\d+)", v)
627
+
628
+ if not match:
629
+ raise ValueError("Invalid version format")
630
+
631
+ return tuple(int(part) for part in match.groups())
632
+
633
+
634
+ def collect_migrations(from_version, to_version):
635
+ migrations = filter(
636
+ lambda obj: (
637
+ callable(obj)
638
+ and hasattr(obj, "openplx_from_version")
639
+ and hasattr(obj, "openplx_to_version")
640
+ and hasattr(obj, "openplx_order")
641
+ and split_version(from_version) <= split_version(obj.openplx_from_version)
642
+ and split_version(obj.openplx_from_version) < split_version(to_version)
643
+ ),
644
+ [obj for _, obj in globals().items()],
645
+ )
646
+
647
+ return sorted(list(migrations), key=lambda m: split_version(m.openplx_from_version))
648
+
649
+
650
+ class MigrateOp(ABC): # pylint: disable=R0903 # Too few public methods
651
+ @abstractmethod
652
+ def apply_to(self, lines, offset):
653
+ pass
654
+
655
+
656
+ class ChangeExtensionOp(MigrateOp):
657
+ def __init__(self, path: Path, new_extension: str):
658
+ self.path = path
659
+ self.new_extension = new_extension
660
+
661
+ def __str__(self):
662
+ return f"{{ {self.path}, {self.new_extension} }}"
663
+
664
+ def apply_to(self, _lines, _offset):
665
+ self.path.rename(self.path.with_suffix(self.new_extension))
666
+
667
+ class ReplaceOp(MigrateOp):
668
+ def __init__(self, op: RefactorReplaceOp):
669
+ self.path = Path(op.source_id)
670
+ self.from_line = op.from_line
671
+ self.from_column = op.from_column
672
+ self.end_line = op.end_line
673
+ self.end_column = op.end_column
674
+ self.new_content = op.new_content
675
+
676
+ def __str__(self):
677
+ return f"{{{self.path}, {self.from_line}, {self.from_column}, {self.end_line}, {self.end_column}, {self.new_content} }}"
678
+
679
+ @staticmethod
680
+ def apply_many(ops, lines):
681
+ # There can be multiple ops per line, we need to run them in order sorted by column
682
+ for _, line_group in itertools.groupby(ops, lambda op: op.from_line):
683
+ offset = 0
684
+ for op in sorted(line_group, key=lambda op: op.from_column):
685
+ lines = op.apply_to(lines, offset)
686
+ offset += len(op.new_content) - op.end_column + op.from_column
687
+ return lines
688
+
689
+ def apply_to(self, lines, offset):
690
+
691
+ if self.end_line != self.from_line:
692
+ print("Multiple line replace ops are not supported", file=sys.stderr)
693
+ return []
694
+
695
+ target_line = lines[self.from_line - 1]
696
+
697
+ lines[self.from_line - 1] = (
698
+ target_line[: (self.from_column + offset - 1)]
699
+ + self.new_content
700
+ + target_line[(self.end_column + offset - 1) :]
701
+ )
702
+
703
+ return lines