agx-openplx 0.15.0__cp39-cp39-win_amd64.whl → 0.15.2__cp39-cp39-win_amd64.whl

Sign up to get free protection for your applications and to get access to all the features.
openplx/migrations.py CHANGED
@@ -25,9 +25,8 @@ def migration(from_version: str, to_version: str, order: int = 0):
25
25
 
26
26
  return decorator
27
27
 
28
-
29
- @migration("0.9.2", "0.9.3")
30
- def snakecaseify_methods(documents):
28
+ @migration("0.9.3", "0.10.0")
29
+ def snakecaseify_methods_093(documents): # pylint: disable=too-many-statements
31
30
  ops = []
32
31
  ops.extend(RefactorToolkit.renameMethod(documents, "Math.Vec3.fromXYZ", "from_xyz"))
33
32
  ops.extend(
@@ -118,13 +117,6 @@ def snakecaseify_methods(documents):
118
117
  ops.extend(
119
118
  RefactorToolkit.renameMethod(documents, "Math.Line.fromPoints", "from_points")
120
119
  )
121
-
122
- return [ReplaceOp(op) for op in ops]
123
-
124
-
125
- @migration("0.9.3", "0.10.0")
126
- def snakecaseify_methods_093(documents):
127
- ops = []
128
120
  # ValueOutputSignal
129
121
  ops.extend(
130
122
  RefactorToolkit.renameMethod(
@@ -450,6 +442,185 @@ def migrations_for_0_13_1(documents):
450
442
 
451
443
  return [ReplaceOp(op) for op in ops]
452
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
+
453
624
 
454
625
  def split_version(v):
455
626
  match = re.match(r"^(\d+)\.(\d+)\.(\d+)", v)
@@ -482,6 +653,17 @@ class MigrateOp(ABC): # pylint: disable=R0903 # Too few public methods
482
653
  pass
483
654
 
484
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
+
485
667
  class ReplaceOp(MigrateOp):
486
668
  def __init__(self, op: RefactorReplaceOp):
487
669
  self.path = Path(op.source_id)
@@ -12,7 +12,7 @@ from openplxbundles import bundle_path
12
12
  # Import useful utilities to access the current simulation, graphics root and application
13
13
  from agxPythonModules.utils.environment import init_app, simulation, application, root
14
14
 
15
- from openplx import InputSignalListener, OutputSignalListener, OsgClickAdapter
15
+ from openplx import InputSignalQueue, OutputSignalQueue, InputSignalListener, OutputSignalListener, OsgClickAdapter
16
16
  from openplx import load_from_file, OptParams, addVisuals, addDeformableVisualUpdaters, __version__, set_log_level, add_file_changed_listener
17
17
  from openplx.versionaction import VersionAction
18
18
 
@@ -21,6 +21,7 @@ def dummy_build_scene():
21
21
 
22
22
  class AgxHelpAction(Action):
23
23
  def __call__(self, parser, namespace, values, option_string=None):
24
+ sys.argv.append("--usage")
24
25
  OpenPlxApplication(dummy_build_scene).start_agx()
25
26
  sys.exit(0)
26
27
 
@@ -38,7 +39,7 @@ class OpenPlxApplication:
38
39
  self.build_scene_file = sys.modules[self.build_scene.__module__].__file__ if build_scene_file is None else build_scene_file
39
40
 
40
41
  @staticmethod
41
- def parse_args(openplxfile = None):
42
+ def setup_args_parser(openplxfile = None):
42
43
  parser = ArgumentParser(description="View OpenPLX models", formatter_class=ArgumentDefaultsHelpFormatter)
43
44
  if openplxfile is None:
44
45
  parser.add_argument("openplxfile", help="the .openplx file to load")
@@ -58,20 +59,20 @@ class OpenPlxApplication:
58
59
  default="info")
59
60
  parser.add_argument("--modelname", help="The model to load (defaults to last model in file)", metavar="<name>", default=None)
60
61
  parser.add_argument("--reload-on-update", help="Reload scene automatically when source is updated", action="store_true", default=SUPPRESS)
61
- parser.add_argument("--usage", help="Show AGX specific help", action=AgxHelpAction, nargs=0, default=SUPPRESS)
62
+ parser.add_argument("--agxhelp", help="Show AGX specific help", action=AgxHelpAction, nargs=0, default=SUPPRESS)
62
63
  parser.add_argument("--version", help="Show version", action=VersionAction, nargs=0, default=SUPPRESS)
63
- return parser.parse_known_args()
64
+ return parser
64
65
 
65
66
  @staticmethod
66
- def prepareScene(openplxfile = None): # pylint: disable=invalid-name
67
- args, extra_args = OpenPlxApplication.parse_args(openplxfile)
67
+ def prepare_scene(openplxfile = None):
68
+ args, extra_args = OpenPlxApplication.setup_args_parser(openplxfile).parse_known_args()
68
69
  set_log_level(args.loglevel)
69
70
  if extra_args:
70
71
  print(f"Passing these args to AGX: {(' ').join(extra_args)}")
71
72
 
72
73
  opt_params = OptParams()
73
74
  if args.modelname is not None:
74
- opt_params.with_model_name(args.modelname)
75
+ opt_params = opt_params.with_model_name(args.modelname)
75
76
 
76
77
  result = load_from_file(simulation(), args.openplxfile if openplxfile is None else openplxfile, args.bundle_path, opt_params)
77
78
 
@@ -79,8 +80,10 @@ class OpenPlxApplication:
79
80
  openplx_scene = result.scene()
80
81
 
81
82
  # Add signal listeners so that signals are picked up from inputs
82
- input_signal_listener = InputSignalListener(assembly)
83
- output_signal_listener = OutputSignalListener(assembly, openplx_scene)
83
+ input_queue = InputSignalQueue.create()
84
+ output_queue = OutputSignalQueue.create()
85
+ input_signal_listener = InputSignalListener(assembly, input_queue)
86
+ output_signal_listener = OutputSignalListener(assembly, openplx_scene, output_queue)
84
87
 
85
88
  simulation().add(input_signal_listener, InputSignalListener.RECOMMENDED_PRIO)
86
89
  simulation().add(output_signal_listener, OutputSignalListener.RECOMMENDED_PRIO)
@@ -97,13 +100,14 @@ class OpenPlxApplication:
97
100
 
98
101
  if "enable_click" in args:
99
102
  click_adapter = globals()["click_adapter"]
100
- click_adapter.add_listeners(application(), simulation(), args.click_addr, openplx_scene, output_signal_listener)
103
+ click_adapter.add_listeners(application(), simulation(), args.click_addr, openplx_scene,
104
+ input_queue, output_queue, output_signal_listener)
101
105
 
102
106
  if not addVisuals(result, root(), args.debug_render_frames):
103
107
  application().setEnableDebugRenderer(True)
104
108
  simulation().add(assembly.get())
105
109
  addDeformableVisualUpdaters(result, root())
106
- return openplx_scene
110
+ return openplx_scene, input_queue, output_queue
107
111
 
108
112
  @staticmethod
109
113
  def ctrl_break_handler(_signum, _frame):
@@ -123,11 +127,12 @@ class OpenPlxApplication:
123
127
  def start_agx(self):
124
128
  # Tell AGX where build_scene is located
125
129
  sys.argv[0] = self.build_scene_file
126
- # pylint: disable=W0612 # Unused variable 'init'
127
130
  # Use __main__ otherwise AGX will just skip the init
128
- init = init_app(name="__main__", scenes=[(self.build_scene, "1")], autoStepping=True, onShutdown=self.on_shutdown) # Default: False
131
+ # pylint: disable=unused-variable
132
+ init = init_app(name="__main__", scenes=[(self.build_scene, "1")], autoStepping=True, onShutdown=self.on_shutdown)
133
+ # pylint: enable=unused-variable
129
134
 
130
135
  def run(self):
131
136
  signal.signal(signal.SIGINT, self.ctrl_break_handler)
132
- self.parse_args("")
137
+ self.setup_args_parser("").parse_known_args()
133
138
  self.start_agx()
@@ -20,11 +20,11 @@ def parse_args():
20
20
  metavar="<bundle_path>", default=bundle_path())
21
21
  parser.add_argument("--debug-render-frames", action='store_true', help="enable rendering of frames for mate connectors and rigid bodies.")
22
22
  parser.add_argument("--loglevel", choices=["trace", "debug", "info", "warn", "error", "critical", "off"], help="Set log level", default="warn")
23
- parser.add_argument("--modelname", help="The model to load (defaults to last model in file)", metavar="<name>", default="")
23
+ parser.add_argument("--modelname", help="The model to load (defaults to last model in file)", metavar="<name>", default=None)
24
24
  parser.add_argument("--version", help="Show version", action=VersionAction, nargs=0, default=SUPPRESS)
25
25
  return parser.parse_args()
26
26
 
27
- class AllowCtrlBreakListener(agxOSG.ExampleApplicationListener):
27
+ class AllowCtrlBreakListener(agxOSG.ExampleApplicationListener): # pylint: disable=too-few-public-methods
28
28
  pass
29
29
 
30
30
  def validate():
@@ -37,7 +37,7 @@ def validate():
37
37
 
38
38
  opt_params = OptParams()
39
39
  if args.modelname is not None:
40
- opt_params.with_model_name(args.modelname)
40
+ opt_params = opt_params.with_model_name(args.modelname)
41
41
 
42
42
  result = load_from_file(simulation, args.openplxfile, args.bundle_path, opt_params)
43
43
 
openplx/openplx_view.py CHANGED
@@ -5,7 +5,7 @@ Command line utility that loads OpenPLX files and loads them into an AGX Simulat
5
5
  from openplx.openplx_application import OpenPlxApplication
6
6
 
7
7
  def openplx_view_build_scene():
8
- OpenPlxApplication.prepareScene()
8
+ OpenPlxApplication.prepare_scene()
9
9
 
10
10
  def run():
11
11
  OpenPlxApplication(openplx_view_build_scene).run()
@@ -1,232 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: agx-openplx
3
- Version: 0.15.0
4
- Summary: AGX-OpenPLX python interface development
5
- Home-page: https://pub.algoryx.dev/openplx/
6
- License: Apache 2.0
7
- Author: Algoryx
8
- Author-email: algoryx@algoryx.com
9
- Requires-Python: >=3.8
10
- Classifier: Intended Audience :: Manufacturing
11
- Classifier: Intended Audience :: Science/Research
12
- Classifier: License :: Other/Proprietary License
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
- Classifier: Programming Language :: Python :: 3.9
16
- Classifier: Programming Language :: Python :: 3.10
17
- Classifier: Programming Language :: Python :: 3.11
18
- Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Topic :: Scientific/Engineering :: Physics
20
- Classifier: Topic :: Scientific/Engineering :: Visualization
21
- Requires-Dist: agx (==2.38.0.2)
22
- Requires-Dist: openplx-bundles (>=0.15.0,<0.16.0)
23
- Requires-Dist: pclick (>=0.4.1,<0.5.0)
24
- Description-Content-Type: text/markdown
25
-
26
- # AGX OpenPLX
27
-
28
- The agx-openplx package implements all OpenPLX bundles such as Physics, Robotics, DriveTrain and Simulation using [AGX Dynamics Real-time multi-body simulation](https://www.algoryx.se/agx-dynamics/).
29
- The package contains python bindings and native libraries needed to load and run .openplx files.
30
-
31
- See [OpenPLX documentation](https://pub.algoryx.dev/openplx/) for more info on OpenPLX.
32
-
33
- ## Prerequisites
34
-
35
- - Python 3.9 on Windows or OSX
36
- - Python 3.8 on Ubuntu 20.04
37
- - Python 3.10 on Ubuntu 22.04
38
- - [AGX Dynamics](https://www.algoryx.se/agx-dynamics/) 2.38.0.2 and an AGX Dynamics License
39
-
40
- At [OpenPLX documentation](https://pub.algoryx.dev/openplx/getopenplx/) you can find out which older version of OpenPLX matches which version of AGX.
41
-
42
- ## Install
43
-
44
- To get the version corresponding to your AGX on Windows do:
45
-
46
- ```bash
47
- setup_env.bat
48
- pip install %AGX_DATA_DIR%/agx-pypi
49
- pip install -U agx-openplx
50
- ```
51
-
52
- To get the version corresponding to your AGX on OSX and Linux do:
53
-
54
- ```bash
55
- source setup_env.sh
56
- pip3 install $AGX_DATA_DIR/agx-pypi
57
- pip3 install -U agx-openplx
58
- ```
59
-
60
- ## License
61
-
62
- [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
63
-
64
- ## Usage Examples
65
-
66
- Given the python file and openplx file below, run with:
67
-
68
- ```bash
69
- python3 inverted_pendulum.py
70
- ```
71
-
72
- To just simulate the openplx file without controllers, do:
73
-
74
- ```bash
75
- openplx_view inverted_pendulum.openplx
76
- ```
77
-
78
- or `python3 -m openplx.openplx_view inverted_pendulum.openplx`
79
-
80
- Store contents below in a new file named `inverted_pendulum.openplx`:
81
-
82
- ```openplx
83
- Rod is Physics3D.Bodies.RigidBody:
84
- inertia.mass: 10
85
- geometry is Physics3D.Charges.Box:
86
- size: Math.Vec3.from_xyz(0.1, 0.1, 1)
87
- arrow is Physics3D.Charges.Box:
88
- local_transform:
89
- position.z: 0.5
90
- rotation: Math.Quat.angleAxis(Math.PI / 4, Math.Vec3.Y_AXIS())
91
- size: Math.Vec3.from_xyz(0.071, 0.1, 0.071)
92
- mate_connector is Physics3D.Charges.MateConnector:
93
- position.z: -geometry.size.z * 0.7
94
- main_axis: Math.Vec3.Y_AXIS()
95
- normal: Math.Vec3.Z_AXIS()
96
-
97
- Cart is Physics3D.Bodies.RigidBody:
98
- inertia.mass: 10
99
- geometry is Physics3D.Charges.Box:
100
- size: Math.Vec3.from_xyz(0.1, 0.1, 0.1)
101
- connector is Physics3D.Charges.MateConnector:
102
- main_axis: Math.Vec3.X_AXIS()
103
- normal: Math.Vec3.Z_AXIS()
104
- rotated_connector is Physics3D.Charges.MateConnector:
105
- main_axis: Math.Vec3.Y_AXIS()
106
- normal: Math.Vec3.Z_AXIS()
107
-
108
- PendulumScene is Physics3D.System:
109
- world_connector is Physics3D.Charges.MateConnector:
110
- main_axis: Math.Vec3.X_AXIS()
111
- normal: Math.Vec3.Z_AXIS()
112
-
113
- cart is Cart
114
- rod is Rod
115
-
116
- prismatic is Physics3D.Interactions.Prismatic:
117
- charges: [world_connector, cart.connector]
118
-
119
- cart_motor is Physics3D.Interactions.LinearVelocityMotor:
120
- desired_speed: 0
121
- charges: prismatic.charges
122
-
123
- hinge is Physics3D.Interactions.Hinge:
124
- initial_angle: 0
125
- charges: [cart.rotated_connector, rod.mate_connector]
126
-
127
- motor_input is Physics3D.Signals.LinearVelocityMotorVelocityInput:
128
- motor: cart_motor
129
-
130
- hinge_angle_output is Physics3D.Signals.HingeAngleOutput:
131
- hinge: hinge
132
- hinge_angular_velocity_output is Physics3D.Signals.HingeAngularVelocityOutput:
133
- hinge: hinge
134
-
135
- cart_position_output is Physics3D.Signals.RigidBodyPositionOutput:
136
- rigid_body: cart
137
- cart_velocity_output is Physics3D.Signals.RigidBodyVelocityOutput:
138
- rigid_body: cart
139
- ```
140
-
141
- Store contents below in a new file named `inverted_pendulum.py`:
142
-
143
- ```python
144
- import os
145
- import signal
146
- import agxOSG
147
- import agxSDK
148
- from openplxbundles import bundle_path
149
-
150
- # Import useful utilities to access the current simulation, graphics root and application
151
- from agxPythonModules.utils.environment import init_app, simulation, root
152
-
153
- from openplx import Math, Physics, Physics3D, Signals
154
- from openplx import InputSignalListener, OutputSignalListener, load_from_file
155
-
156
- def file_dir():
157
- return os.path.dirname(os.path.abspath(__file__))
158
-
159
- def pendulum():
160
- return f"{file_dir()}/inverted_pendulum.openplx"
161
-
162
- class PDController:
163
- def __init__(self, kp, kd, goal):
164
- self.kp = kp
165
- self.kd = kd
166
- self.goal = goal
167
-
168
- def observe(self, x, xdot):
169
- error = self.goal - x
170
- return self.kp * error - self.kd * xdot
171
-
172
-
173
- class CartController(agxSDK.StepEventListener):
174
- motor_input: Physics3D.Signals_LinearVelocityMotorVelocityInput
175
- cart: PDController
176
- pole: PDController
177
-
178
- def __init__(self, motor_input: Physics3D.Signals_LinearVelocityMotorVelocityInput):
179
- super().__init__()
180
- self.motor_input = motor_input
181
- self.cart = PDController(kp=10, kd=5, goal=0)
182
- self.pole = PDController(kp=20, kd=5, goal=0)
183
-
184
- def pre(self, time):
185
- if time == 0.0:
186
- hinge_angle = 0
187
- hinge_angular_velocity = 0
188
- cart_position = Math.Vec3.from_xyz(0,0,0)
189
- cart_velocity = Math.Vec3.from_xyz(0,0,0)
190
- else:
191
- signal_values = {signal.source().getName():signal.value().value() for signal in Signals.getOutputSignals()}
192
- hinge_angle = signal_values["PendulumScene.hinge_angle_output"]
193
- hinge_angular_velocity = signal_values["PendulumScene.hinge_angular_velocity_output"]
194
- cart_position = signal_values["PendulumScene.cart_position_output"]
195
- cart_velocity = signal_values["PendulumScene.cart_velocity_output"]
196
-
197
- u_cart = self.cart.observe(cart_position.x(), cart_velocity.x())
198
- u_pole = self.pole.observe(hinge_angle, hinge_angular_velocity)
199
-
200
- Signals.sendInputSignal(Physics.Signals_RealInputSignal.create(-u_cart - u_pole, self.motor_input))
201
-
202
-
203
- def buildScene():
204
-
205
- result = load_from_file(simulation(), pendulum(), bundle_path(), "")
206
- assembly = result.assembly()
207
- openplx_scene = result.scene()
208
- # Add a signal listener so that signals are picked up from inputs
209
- input_signal_listener = InputSignalListener(assembly)
210
- output_signal_listener = OutputSignalListener(assembly, openplx_scene)
211
- simulation().add(input_signal_listener, InputSignalListener.RECOMMENDED_PRIO)
212
- simulation().add(output_signal_listener, OutputSignalListener.RECOMMENDED_PRIO)
213
- simulation().add(assembly.get())
214
- agxOSG.createVisual(assembly.get(), root())
215
-
216
- motor_input: Physics3D.Signals_LinearVelocityMotorVelocityInput = openplx_scene.getDynamic("motor_input").asObject()
217
- controller = CartController(motor_input)
218
- simulation().add(controller)
219
-
220
-
221
- def handler(_, __):
222
- os._exit(0)
223
-
224
- signal.signal(signal.SIGINT, handler)
225
-
226
- init = init_app(name=__name__,
227
- scenes=[(buildScene, '1')],
228
- autoStepping=True, # Default: False
229
- onInitialized=lambda app: print('App successfully initialized.'),
230
- onShutdown=lambda app: print('App successfully shut down.'))
231
- ```
232
-
@@ -1,41 +0,0 @@
1
- openplx/__init__.py,sha256=73QPapLJWuj5dEJzFvWM9kWQNZUWYJuUvR_2jvfAbBI,2101
2
- openplx/_AgxOpenPlxPyApi.cp39-win_amd64.pyd,sha256=B2vaXpde6-mm5SHMUeirG1vq0tPA55S1elo3acJN6dk,6322176
3
- openplx/_CorePythonSwig.cp39-win_amd64.pyd,sha256=pFlpaW3MzvjPdBTKNRf3ZjZJVFswXy5n57i6SQYsPDE,2550272
4
- openplx/_DriveTrainSwig.cp39-win_amd64.pyd,sha256=XqyedEtF4h4vx4XWHATPi6C3xasH8DNZ-EoySMUbtFU,2826752
5
- openplx/_MathSwig.cp39-win_amd64.pyd,sha256=oNdsvsSInHubZFgkTbP5_KiaqznA5ODkP7yhew0r7RQ,1313792
6
- openplx/_Physics1DSwig.cp39-win_amd64.pyd,sha256=0eVYY5AHtdgAP4SnKBdV9u7bERX3TSGLVUor5Xkh_FE,2173440
7
- openplx/_Physics3DSwig.cp39-win_amd64.pyd,sha256=M4MHEAtDueI4r0ka1j9eb1_ZgDy-6pt5iXRDcWC-bxU,12642816
8
- openplx/_PhysicsSwig.cp39-win_amd64.pyd,sha256=zOZcmz6eRQJTOcbPi8uYnpoKIuh-URbj5saNSodTUHE,9691136
9
- openplx/_RoboticsSwig.cp39-win_amd64.pyd,sha256=xyfczcxwKuuXmEKrZlqQ9wdtn0yINQAchnp3E6LoDq8,5177344
10
- openplx/_SimulationSwig.cp39-win_amd64.pyd,sha256=5qAYufH7YdfT4x9PsbOvLydU1HYWOnK_JYdnwfDDUD4,632320
11
- openplx/_TerrainSwig.cp39-win_amd64.pyd,sha256=Cmo6uozx7gGCuQAkbWZBKRNCxFeKXznU_smgdiRXzcc,1536512
12
- openplx/_UrdfSwig.cp39-win_amd64.pyd,sha256=JM7b4moSJUKAeOiJ0FN39h8zrKaAXAUMh2-NHXH9ycM,698368
13
- openplx/_VehiclesSwig.cp39-win_amd64.pyd,sha256=q_VGwVFRLfM35oiPeB8OmCF-D3jIYzfw2rENGDKMnaA,3124224
14
- openplx/_VisualsSwig.cp39-win_amd64.pyd,sha256=75k0ifzbThqsjqsBjfVgkfEOTX7mbc0srzQbGk8x14I,1281024
15
- openplx/agxtoopenplx.py,sha256=LCt_tm9tffb0aA5ZsVAqvD1w276NKuq2MQ9vOZS1V1I,2477
16
- openplx/anytoopenplx.py,sha256=ckINLkHMyraBaIhdJfVXcaeVNh6m7BnyEx9or3j7mxo,2318
17
- openplx/api.py,sha256=XoU3a-t2bNxO71FeBpuGgENsVaR14DrlPpkCE4cJRn8,48252
18
- openplx/Core.py,sha256=lQcUoerxSC-TjMSjdNFWGjnQ1eQKVpFJhGl0sTlPkE0,277824
19
- openplx/DriveTrain.py,sha256=e3ntEsPnXXhw3LWqNsP78A5aZaMNwd_jDa9cjShmP_g,427468
20
- openplx/Math.py,sha256=hi3zI0KfxZNqy8u78nEm55bZGo0ZoWgqA8piOE2e2B8,193933
21
- openplx/migrate.py,sha256=SzIjugipKu3fLDpaU91Nh3zZ_jh4h-12sO1dsNroxeU,5738
22
- openplx/migration_hint.py,sha256=JiD5f7DzCVNoN-N_VweRNIKnSmCRqxhRof4QiR-1rEs,617
23
- openplx/migrations.py,sha256=Rdh3Ebx-XeH-t8gAphcFyIDCADhkeZWTI4vilhxtcjk,15615
24
- openplx/openplx_application.py,sha256=wDxdFz5MYjobFg0ofTs9yP0ce6uf_gMr33WLz-BBNJI,6479
25
- openplx/openplx_serialize.py,sha256=0_hKFnBP8IQ4f22vW6RLHRRNxUZVSu21Lcrgy6lbqPc,1491
26
- openplx/openplx_validate.py,sha256=PgbC1K0OzKC2rknUtqYWXyCca5TKnZdpkg_ZresGvOY,2112
27
- openplx/openplx_view.py,sha256=4ISYX0FLsEmdUJyXfixAwyXDsvX5xlTKQLCTEmRCKbM,364
28
- openplx/Physics.py,sha256=uoxRlbDAfIJ-uWtAo3W33VXuv_79ZHco4Nw4KEj6Rl8,1920631
29
- openplx/Physics1D.py,sha256=zumBcg-GGIW39BXkywKVldM3FtSWhUFX2aLbZFHRahU,352638
30
- openplx/Physics3D.py,sha256=Zu70VSG1gbmnvageGT07xIQXXMmNvuICkCfpM0e_Y8I,2480375
31
- openplx/Robotics.py,sha256=gaq0xM3ZuhvIINeoKP14xENZqTw_B5px_gh40-m-_mI,814741
32
- openplx/Simulation.py,sha256=xab3Q6-d90xNuPk--zjTB-XO8BNEv48equ_Ms48PLf8,47374
33
- openplx/Terrain.py,sha256=RhhE6CboZ88n5CbHlyhLzG78vwpjY1sViGgpg7HHuyU,188775
34
- openplx/Urdf.py,sha256=Z9Q5dKrSPIEgXS9JE7cYKl4zgkhbrdlmV3vBcORE0KY,24434
35
- openplx/Vehicles.py,sha256=ljYCuwGfA-qqQywHdcI530mIzqIq1DNgb1_d2Jmo5_4,458867
36
- openplx/versionaction.py,sha256=u0rZ34x1-KtLHM93OBN2BsFAxEAv6HDLadvu14en5io,294
37
- openplx/Visuals.py,sha256=xTDmvGIxyJPWSgH20CWwQRPDHwOFp48nBl8fo8sN0JY,190953
38
- agx_openplx-0.15.0.dist-info/entry_points.txt,sha256=IyHBVBNuH_4ZhfWnB1ZVXYtpKG_QT7dwGIUMLWdyhrc,263
39
- agx_openplx-0.15.0.dist-info/METADATA,sha256=jfj2qYgTFOln0NfOb8u1GhFRNu6UvU-XO-bQtL3_IjU,7875
40
- agx_openplx-0.15.0.dist-info/WHEEL,sha256=T7hzPzFWHJiWCVylm2UCj5payilA7ulisMC0IiBEe3o,96
41
- agx_openplx-0.15.0.dist-info/RECORD,,