pySimBlocks 0.1.0__tar.gz → 0.2.0__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.
- {pysimblocks-0.1.0/pySimBlocks.egg-info → pysimblocks-0.2.0}/PKG-INFO +27 -37
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/README.md +21 -32
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/controllers/pid.py +74 -56
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/controllers/state_feedback.py +65 -39
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/interfaces/__init__.py +5 -1
- pysimblocks-0.2.0/pySimBlocks/blocks/interfaces/bus_from.py +88 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/interfaces/external_input.py +32 -26
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/interfaces/external_output.py +33 -33
- pysimblocks-0.2.0/pySimBlocks/blocks/interfaces/goto.py +78 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/observers/luenberger.py +79 -42
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/algebraic_function.py +95 -53
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/dead_zone.py +72 -44
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/delay.py +63 -62
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/demux.py +49 -27
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/discrete_derivator.py +48 -76
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/discrete_integrator.py +63 -88
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/gain.py +65 -67
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/mux.py +48 -35
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/product.py +66 -47
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/rate_limiter.py +70 -53
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/saturation.py +63 -50
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/sum.py +53 -54
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/zero_order_hold.py +50 -27
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/optimizers/quadratic_program.py +67 -91
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/chirp.py +75 -22
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/constant.py +34 -27
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/file_source.py +109 -29
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/function_source.py +67 -17
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/ramp.py +44 -36
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/sinusoidal.py +46 -35
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/step.py +47 -71
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/white_noise.py +46 -35
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/__init__.py +2 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/linear_state_space.py +93 -38
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/non_linear_state_space.py +90 -75
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/polytopic_state_space.py +65 -33
- pysimblocks-0.2.0/pySimBlocks/blocks/systems/sofa/sofa_controller.py +564 -0
- pysimblocks-0.2.0/pySimBlocks/blocks/systems/sofa/sofa_exchange_i_o.py +126 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/sofa/sofa_plant.py +148 -85
- pysimblocks-0.2.0/pySimBlocks/blocks/systems/transfer_function.py +380 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/cli.py +45 -19
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/block.py +84 -63
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/block_source.py +45 -21
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/config.py +57 -15
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/fixed_time_manager.py +39 -8
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/model.py +146 -43
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/scheduler.py +32 -4
- pysimblocks-0.2.0/pySimBlocks/core/signal_bus.py +37 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/simulator.py +124 -76
- pysimblocks-0.2.0/pySimBlocks/core/task.py +103 -0
- pysimblocks-0.2.0/pySimBlocks/docs/blocks/interfaces/bus_from.md +63 -0
- pysimblocks-0.2.0/pySimBlocks/docs/blocks/interfaces/goto.md +59 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/file_source.md +5 -3
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/systems/linear_state_space.md +22 -5
- pysimblocks-0.2.0/pySimBlocks/docs/blocks/systems/transfer_function.md +89 -0
- pysimblocks-0.2.0/pySimBlocks/gui/addons/sofa/slider_params_dialog.py +513 -0
- pysimblocks-0.2.0/pySimBlocks/gui/addons/sofa/sofa_dialog.py +324 -0
- pysimblocks-0.2.0/pySimBlocks/gui/addons/sofa/sofa_service.py +397 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/block_dialog_session.py +35 -6
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/block_meta.py +107 -82
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/controllers/pid.py +22 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/controllers/state_feedback.py +10 -0
- pysimblocks-0.2.0/pySimBlocks/gui/blocks/interfaces/bus_from.py +228 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/interfaces/external_input.py +9 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/interfaces/external_output.py +9 -8
- pysimblocks-0.2.0/pySimBlocks/gui/blocks/interfaces/goto.py +74 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/observers/luenberger.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/algebraic_function.py +45 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/dead_zone.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/delay.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/demux.py +23 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/discrete_derivator.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/discrete_integrator.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/gain.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/mux.py +23 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/product.py +23 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/rate_limiter.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/saturation.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/sum.py +25 -2
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/operators/zero_order_hold.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/optimizers/quadratic_program.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/parameter_meta.py +15 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/port_meta.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/chirp.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/constant.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/file_source.py +62 -11
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/function_source.py +45 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/ramp.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/sinusoidal.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/step.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/sources/white_noise.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/systems/linear_state_space.py +18 -1
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/systems/non_linear_state_space.py +45 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/systems/polytopic_state_space.py +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/systems/sofa/sofa_exchange_i_o.py +50 -10
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/blocks/systems/sofa/sofa_plant.py +50 -10
- pysimblocks-0.2.0/pySimBlocks/gui/blocks/systems/transfer_function.py +122 -0
- pysimblocks-0.2.0/pySimBlocks/gui/diagram_clipboard.py +694 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/block_dialog.py +39 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/display_yaml_dialog.py +21 -3
- pysimblocks-0.2.0/pySimBlocks/gui/dialogs/export_npz_dialog.py +171 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/help_dialog.py +11 -0
- pysimblocks-0.2.0/pySimBlocks/gui/dialogs/plot_dialog.py +1564 -0
- pysimblocks-0.2.0/pySimBlocks/gui/dialogs/plot_series_style_dialog.py +268 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/settings/plots.py +94 -15
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/settings/project.py +53 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/settings/simulation.py +28 -4
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/settings_dialog.py +31 -1
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/unsaved_dialog.py +21 -2
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/editor.py +22 -7
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/graphics/__init__.py +7 -1
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/graphics/block_item.py +139 -24
- pysimblocks-0.2.0/pySimBlocks/gui/graphics/connection_item.py +497 -0
- pysimblocks-0.2.0/pySimBlocks/gui/graphics/group_item.py +490 -0
- pysimblocks-0.2.0/pySimBlocks/gui/graphics/group_proxy_item.py +245 -0
- pysimblocks-0.2.0/pySimBlocks/gui/graphics/manual_boundary_wire_item.py +53 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/graphics/port_item.py +67 -17
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/graphics/theme.py +25 -0
- pysimblocks-0.2.0/pySimBlocks/gui/group_boundary_labels.py +38 -0
- pysimblocks-0.2.0/pySimBlocks/gui/group_ports.py +10 -0
- pysimblocks-0.2.0/pySimBlocks/gui/main_window.py +280 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/models/__init__.py +4 -1
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/models/block_instance.py +53 -15
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/models/connection_instance.py +37 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/models/port_instance.py +37 -4
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/models/project_simulation_params.py +28 -0
- pysimblocks-0.2.0/pySimBlocks/gui/models/project_state.py +245 -0
- pysimblocks-0.2.0/pySimBlocks/gui/models/visual_group.py +130 -0
- pysimblocks-0.2.0/pySimBlocks/gui/project_controller.py +2611 -0
- pysimblocks-0.2.0/pySimBlocks/gui/services/group_boundary_service.py +168 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/services/project_loader.py +148 -12
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/services/project_saver.py +40 -1
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/services/simulation_runner.py +18 -9
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/services/yaml_tools.py +124 -32
- pysimblocks-0.2.0/pySimBlocks/gui/undo_redo/commands.py +775 -0
- pysimblocks-0.2.0/pySimBlocks/gui/undo_redo/undo_redo_manager.py +60 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/widgets/block_list.py +65 -2
- pysimblocks-0.2.0/pySimBlocks/gui/widgets/diagram_view.py +1366 -0
- pysimblocks-0.2.0/pySimBlocks/gui/widgets/toolbar_view.py +319 -0
- pysimblocks-0.2.0/pySimBlocks/gui/widgets/view_navigation_bar.py +86 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/project/build_model.py +18 -25
- pysimblocks-0.2.0/pySimBlocks/project/generate_run_script.py +152 -0
- pysimblocks-0.2.0/pySimBlocks/project/generate_sofa_scaffold.py +191 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/project/load_project_config.py +70 -3
- pysimblocks-0.2.0/pySimBlocks/project/load_simulation_config.py +252 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/project/load_simulator.py +19 -2
- pysimblocks-0.2.0/pySimBlocks/project/plot_from_config.py +272 -0
- pysimblocks-0.2.0/pySimBlocks/project/plot_series.py +337 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/project/pySimBlocks_blocks_index.yaml +9 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/real_time/real_time_runner.py +43 -43
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/tools/blocks_registry.py +55 -34
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/tools/generate_blocks_index.py +45 -22
- {pysimblocks-0.1.0 → pysimblocks-0.2.0/pySimBlocks.egg-info}/PKG-INFO +27 -37
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks.egg-info/SOURCES.txt +27 -85
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks.egg-info/requires.txt +6 -0
- pysimblocks-0.2.0/pySimBlocks.egg-info/top_level.txt +1 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pyproject.toml +9 -5
- pysimblocks-0.1.0/examples/advanced/hardware/block_diagram.py +0 -162
- pysimblocks-0.1.0/examples/advanced/hardware/camera.py +0 -93
- pysimblocks-0.1.0/examples/advanced/hardware/gui_emio.py +0 -231
- pysimblocks-0.1.0/examples/advanced/hardware/lmi.py +0 -69
- pysimblocks-0.1.0/examples/advanced/hardware/main.py +0 -57
- pysimblocks-0.1.0/examples/advanced/hardware/parameters.py +0 -54
- pysimblocks-0.1.0/examples/advanced/qp_problem/params.py +0 -10
- pysimblocks-0.1.0/examples/advanced/qp_problem/run.py +0 -14
- pysimblocks-0.1.0/examples/advanced/sofa/gui/finger/Finger.py +0 -108
- pysimblocks-0.1.0/examples/advanced/sofa/gui/finger/FingerController.py +0 -53
- pysimblocks-0.1.0/examples/advanced/sofa/gui/finger/parameters_auto.py +0 -22
- pysimblocks-0.1.0/examples/advanced/sofa/gui/sofa_plant/run.py +0 -14
- pysimblocks-0.1.0/examples/advanced/sofa/python/Finger.py +0 -107
- pysimblocks-0.1.0/examples/advanced/sofa/python/FingerController.py +0 -48
- pysimblocks-0.1.0/examples/advanced/sofa/python/closedloop.py +0 -64
- pysimblocks-0.1.0/examples/advanced/sofa/python/openloop.py +0 -58
- pysimblocks-0.1.0/examples/basics/algebraic_function/g.py +0 -7
- pysimblocks-0.1.0/examples/basics/algebraic_function/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/dc_motor/gui/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/dc_motor/multiple_order.py +0 -91
- pysimblocks-0.1.0/examples/basics/dc_motor/openloop.py +0 -62
- pysimblocks-0.1.0/examples/basics/dc_motor/pi.py +0 -99
- pysimblocks-0.1.0/examples/basics/dc_motor/pid.py +0 -118
- pysimblocks-0.1.0/examples/basics/dc_motor/pid_block.py +0 -82
- pysimblocks-0.1.0/examples/basics/dc_motor/pid_block_vs_manual.py +0 -143
- pysimblocks-0.1.0/examples/basics/external/parameters.py +0 -4
- pysimblocks-0.1.0/examples/basics/external/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/file_sources/temp.py +0 -16
- pysimblocks-0.1.0/examples/basics/observer.py +0 -76
- pysimblocks-0.1.0/examples/basics/state_feedback/gui/parameters.py +0 -9
- pysimblocks-0.1.0/examples/basics/state_feedback/gui/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/state_feedback/state_feedback.py +0 -102
- pysimblocks-0.1.0/examples/basics/state_space/linear/gui/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/state_space/linear/ss_block.py +0 -89
- pysimblocks-0.1.0/examples/basics/state_space/linear/ss_manual.py +0 -105
- pysimblocks-0.1.0/examples/basics/state_space/non_linear/nlss.py +0 -47
- pysimblocks-0.1.0/examples/basics/state_space/non_linear/run.py +0 -14
- pysimblocks-0.1.0/examples/basics/state_space/polytope/params.py +0 -39
- pysimblocks-0.1.0/examples/basics/state_space/polytope/weights.py +0 -12
- pysimblocks-0.1.0/examples/comparison/simulink/convert.py +0 -29
- pysimblocks-0.1.0/examples/comparison/simulink/openloop.py +0 -127
- pysimblocks-0.1.0/examples/comparison/simulink/pi.py +0 -148
- pysimblocks-0.1.0/examples/comparison/simulink/pid.py +0 -154
- pysimblocks-0.1.0/examples/comparison/simulink/pid_backward.py +0 -155
- pysimblocks-0.1.0/examples/quick_start/filter.py +0 -35
- pysimblocks-0.1.0/examples/quick_start/gui/run.py +0 -14
- pysimblocks-0.1.0/examples/tutorials/tutorial_1_python/main.py +0 -99
- pysimblocks-0.1.0/examples/tutorials/tutorial_3_sofa/finger/Finger.py +0 -120
- pysimblocks-0.1.0/examples/tutorials/tutorial_3_sofa/finger/FingerController.py +0 -37
- pysimblocks-0.1.0/pySimBlocks/blocks/systems/sofa/sofa_controller.py +0 -472
- pysimblocks-0.1.0/pySimBlocks/blocks/systems/sofa/sofa_exchange_i_o.py +0 -120
- pysimblocks-0.1.0/pySimBlocks/core/task.py +0 -73
- pysimblocks-0.1.0/pySimBlocks/gui/addons/sofa/sofa_dialog.py +0 -190
- pysimblocks-0.1.0/pySimBlocks/gui/addons/sofa/sofa_service.py +0 -209
- pysimblocks-0.1.0/pySimBlocks/gui/dialogs/plot_dialog.py +0 -230
- pysimblocks-0.1.0/pySimBlocks/gui/graphics/connection_item.py +0 -266
- pysimblocks-0.1.0/pySimBlocks/gui/main_window.py +0 -162
- pysimblocks-0.1.0/pySimBlocks/gui/models/project_state.py +0 -114
- pysimblocks-0.1.0/pySimBlocks/gui/project_controller.py +0 -302
- pysimblocks-0.1.0/pySimBlocks/gui/widgets/diagram_view.py +0 -312
- pysimblocks-0.1.0/pySimBlocks/gui/widgets/toolbar_view.py +0 -161
- pysimblocks-0.1.0/pySimBlocks/project/generate_run_script.py +0 -109
- pysimblocks-0.1.0/pySimBlocks/project/generate_sofa_controller.py +0 -215
- pysimblocks-0.1.0/pySimBlocks/project/load_simulation_config.py +0 -166
- pysimblocks-0.1.0/pySimBlocks/project/plot_from_config.py +0 -174
- pysimblocks-0.1.0/pySimBlocks.egg-info/top_level.txt +0 -7
- pysimblocks-0.1.0/tests/blocks/controllers/test_pid.py +0 -143
- pysimblocks-0.1.0/tests/blocks/controllers/test_state_feedback.py +0 -193
- pysimblocks-0.1.0/tests/blocks/observers/test_luenberger.py +0 -225
- pysimblocks-0.1.0/tests/blocks/operators/test_algebraic_function.py +0 -230
- pysimblocks-0.1.0/tests/blocks/operators/test_dead_zone.py +0 -106
- pysimblocks-0.1.0/tests/blocks/operators/test_delay.py +0 -167
- pysimblocks-0.1.0/tests/blocks/operators/test_demux.py +0 -111
- pysimblocks-0.1.0/tests/blocks/operators/test_discrete_derivator.py +0 -160
- pysimblocks-0.1.0/tests/blocks/operators/test_discrete_integrator.py +0 -149
- pysimblocks-0.1.0/tests/blocks/operators/test_gain.py +0 -182
- pysimblocks-0.1.0/tests/blocks/operators/test_mux.py +0 -101
- pysimblocks-0.1.0/tests/blocks/operators/test_product.py +0 -171
- pysimblocks-0.1.0/tests/blocks/operators/test_rate_limiter.py +0 -166
- pysimblocks-0.1.0/tests/blocks/operators/test_saturation.py +0 -157
- pysimblocks-0.1.0/tests/blocks/operators/test_sum.py +0 -183
- pysimblocks-0.1.0/tests/blocks/operators/test_zero_order_hold.py +0 -106
- pysimblocks-0.1.0/tests/blocks/sources/test_chirp.py +0 -157
- pysimblocks-0.1.0/tests/blocks/sources/test_constant.py +0 -55
- pysimblocks-0.1.0/tests/blocks/sources/test_file_source.py +0 -185
- pysimblocks-0.1.0/tests/blocks/sources/test_function_source.py +0 -135
- pysimblocks-0.1.0/tests/blocks/sources/test_ramp.py +0 -110
- pysimblocks-0.1.0/tests/blocks/sources/test_sinusoidal.py +0 -113
- pysimblocks-0.1.0/tests/blocks/sources/test_step.py +0 -76
- pysimblocks-0.1.0/tests/blocks/sources/test_white_noise.py +0 -108
- pysimblocks-0.1.0/tests/blocks/systems/test_linear_state_space.py +0 -135
- pysimblocks-0.1.0/tests/blocks/systems/test_polytopic_state_space.py +0 -133
- pysimblocks-0.1.0/tests/core/test_core_errors_and_determinism.py +0 -82
- pysimblocks-0.1.0/tests/core/test_core_multirate_tasks.py +0 -88
- pysimblocks-0.1.0/tests/core/test_core_two_phase_and_propagation.py +0 -132
- pysimblocks-0.1.0/tests/gui/main_window_open_test.py +0 -162
- pysimblocks-0.1.0/tests/gui/test_block_meta_param_cache.py +0 -16
- pysimblocks-0.1.0/tests/gui/test_file_source_meta.py +0 -17
- pysimblocks-0.1.0/tests/gui/test_function_source_meta.py +0 -28
- pysimblocks-0.1.0/tests/regression/test_simulink_dc_motor.py +0 -217
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/LICENSE.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/controllers/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/observers/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/operators/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/optimizers/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/sources/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/blocks/systems/sofa/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/core/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/controllers/pid.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/controllers/state_feedback.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/interfaces/external_input.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/interfaces/external_output.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/observers/luenberger.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/algebraic_function.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/dead_zone.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/delay.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/demux.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/discrete_derivator.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/discrete_integrator.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/gain.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/mux.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/product.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/rate_limiter.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/saturation.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/sum.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/operators/zero_order_hold.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/optimizers/quadratic_program.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/chirp.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/constant.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/function_source.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/ramp.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/sinusoidal.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/step.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/sources/white_noise.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/systems/non_linear_state_space.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/systems/polytopic_state_space.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/systems/sofa/sofa_exchange_i_o.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/docs/blocks/systems/sofa/sofa_plant.md +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/addons/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/addons/sofa/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/dialogs/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/services/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/gui/widgets/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/project/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/real_time/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks/tools/__init__.py +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks.egg-info/dependency_links.txt +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/pySimBlocks.egg-info/entry_points.txt +0 -0
- {pysimblocks-0.1.0 → pysimblocks-0.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pySimBlocks
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A block-diagram simulation environment with PySide6 editor
|
|
5
5
|
Author-email: Antoine Alessandrini <antoine.alessandrini@univ-lille.fr>
|
|
6
6
|
License-Expression: LGPL-3.0-or-later
|
|
@@ -11,10 +11,6 @@ Keywords: simulation,block-diagram,control,discrete-time,pyside6
|
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Intended Audience :: Science/Research
|
|
13
13
|
Classifier: Intended Audience :: Education
|
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
18
14
|
Classifier: Topic :: Scientific/Engineering
|
|
19
15
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
20
16
|
Requires-Python: >=3.10
|
|
@@ -28,6 +24,11 @@ Requires-Dist: typing_extensions; python_version < "3.11"
|
|
|
28
24
|
Provides-Extra: examples
|
|
29
25
|
Requires-Dist: control; extra == "examples"
|
|
30
26
|
Requires-Dist: qpsolvers[clarabel,osqp]; extra == "examples"
|
|
27
|
+
Provides-Extra: docs
|
|
28
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
29
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
30
|
+
Requires-Dist: furo; extra == "docs"
|
|
31
|
+
Requires-Dist: sphinxcontrib-video; extra == "docs"
|
|
31
32
|
Provides-Extra: tests
|
|
32
33
|
Requires-Dist: pytest; extra == "tests"
|
|
33
34
|
Requires-Dist: pytest-qt; extra == "tests"
|
|
@@ -35,45 +36,34 @@ Dynamic: license-file
|
|
|
35
36
|
|
|
36
37
|
# pySimBlocks
|
|
37
38
|
|
|
39
|
+
[](https://pypi.org/project/pySimBlocks/)
|
|
40
|
+
[](https://pypi.org/project/pySimBlocks/)
|
|
41
|
+
[](./LICENSE.md)
|
|
42
|
+
[](https://pysimblocks.readthedocs.io)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
38
46
|
A deterministic block-diagram simulation framework for discrete-time modeling,
|
|
39
47
|
co-simulation and research prototyping in Python.
|
|
40
48
|
|
|
41
|
-
pySimBlocks allows you to build, configure, and execute discrete-time systems
|
|
49
|
+
pySimBlocks allows you to build, configure, and execute discrete-time systems
|
|
42
50
|
using either:
|
|
43
51
|
|
|
44
52
|
- A pure Python API
|
|
45
53
|
- A graphical editor (PySide6)
|
|
46
|
-
- YAML project configuration
|
|
54
|
+
- YAML project configuration with exportable Python runner (`run.py`)
|
|
47
55
|
- Optional SOFA and hardware integration
|
|
48
56
|
|
|
49
|
-

|
|
54
|
-
- Deterministic discrete-time simulation engine
|
|
55
|
-
- PySide6 graphical editor
|
|
56
|
-
- YAML-based project serialization
|
|
57
|
-
- Exportable Python runner (`run.py`)
|
|
58
|
-
- Extensible block architecture
|
|
57
|
+

|
|
59
58
|
|
|
60
59
|
## Installation
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Install directly from GitHub using pip:
|
|
65
|
-
```
|
|
66
|
-
pip install git+https://github.com/AlessandriniAntoine/pySimBlocks
|
|
61
|
+
```bash
|
|
62
|
+
pip install pySimBlocks
|
|
67
63
|
```
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
Clone the repository and install locally:
|
|
72
|
-
```
|
|
73
|
-
git clone https://github.com/AlessandriniAntoine/pySimBlocks.git
|
|
74
|
-
cd pySimBlocks
|
|
75
|
-
pip install .
|
|
76
|
-
```
|
|
65
|
+
Full documentation — user guide, tutorials, and API reference — is available on
|
|
66
|
+
[**Read the Docs**](https://pysimblocks.readthedocs.io).
|
|
77
67
|
|
|
78
68
|
## Getting Started
|
|
79
69
|
|
|
@@ -125,7 +115,7 @@ plot_from_config(logs, plot_cfg)
|
|
|
125
115
|
|
|
126
116
|
The resulting plot should look like this:
|
|
127
117
|
|
|
128
|
-

|
|
129
119
|
|
|
130
120
|
See [examples/quick_start/filter.py](./examples/quick_start/filter.py)
|
|
131
121
|
to run the example yourself.
|
|
@@ -148,14 +138,14 @@ The quick-start GUI project is stored in a single
|
|
|
148
138
|
|
|
149
139
|
#### Tutorials
|
|
150
140
|
|
|
151
|
-
Three step-by-step tutorials are available
|
|
152
|
-
[
|
|
141
|
+
Three step-by-step tutorials are available in the
|
|
142
|
+
[documentation](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/index.html):
|
|
153
143
|
|
|
154
144
|
| | Tutorial | Description |
|
|
155
145
|
|---|---|---|
|
|
156
|
-
| 1 | [Python API](
|
|
157
|
-
| 2 | [GUI](
|
|
158
|
-
| 3 | [SOFA](
|
|
146
|
+
| 1 | [Python API](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_1_python.html) | Build a closed-loop PI control system in pure Python |
|
|
147
|
+
| 2 | [GUI](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_2_gui.html) | Build the same system visually with the graphical editor |
|
|
148
|
+
| 3 | [SOFA](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_3_sofa.html) | Replace the plant with a SOFA physics simulation |
|
|
159
149
|
|
|
160
150
|
|
|
161
151
|
#### Other Examples
|
|
@@ -164,7 +154,7 @@ A collection of basic and advanced examples is available in the
|
|
|
164
154
|
[examples](./examples) directory, including:
|
|
165
155
|
|
|
166
156
|
- Control system demonstrations
|
|
167
|
-
- SOFA-based simulations (tested with SOFA
|
|
157
|
+
- SOFA-based simulations (tested with SOFA v26.06 and later.)
|
|
168
158
|
- Hardware and real-time use cases
|
|
169
159
|
- Comparisons with external tools
|
|
170
160
|
|
|
@@ -1,44 +1,33 @@
|
|
|
1
1
|
# pySimBlocks
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/pySimBlocks/)
|
|
4
|
+
[](https://pypi.org/project/pySimBlocks/)
|
|
5
|
+
[](./LICENSE.md)
|
|
6
|
+
[](https://pysimblocks.readthedocs.io)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
3
10
|
A deterministic block-diagram simulation framework for discrete-time modeling,
|
|
4
11
|
co-simulation and research prototyping in Python.
|
|
5
12
|
|
|
6
|
-
pySimBlocks allows you to build, configure, and execute discrete-time systems
|
|
13
|
+
pySimBlocks allows you to build, configure, and execute discrete-time systems
|
|
7
14
|
using either:
|
|
8
15
|
|
|
9
16
|
- A pure Python API
|
|
10
17
|
- A graphical editor (PySide6)
|
|
11
|
-
- YAML project configuration
|
|
18
|
+
- YAML project configuration with exportable Python runner (`run.py`)
|
|
12
19
|
- Optional SOFA and hardware integration
|
|
13
20
|
|
|
14
|
-

|
|
19
|
-
- Deterministic discrete-time simulation engine
|
|
20
|
-
- PySide6 graphical editor
|
|
21
|
-
- YAML-based project serialization
|
|
22
|
-
- Exportable Python runner (`run.py`)
|
|
23
|
-
- Extensible block architecture
|
|
21
|
+

|
|
24
22
|
|
|
25
23
|
## Installation
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Install directly from GitHub using pip:
|
|
30
|
-
```
|
|
31
|
-
pip install git+https://github.com/AlessandriniAntoine/pySimBlocks
|
|
25
|
+
```bash
|
|
26
|
+
pip install pySimBlocks
|
|
32
27
|
```
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Clone the repository and install locally:
|
|
37
|
-
```
|
|
38
|
-
git clone https://github.com/AlessandriniAntoine/pySimBlocks.git
|
|
39
|
-
cd pySimBlocks
|
|
40
|
-
pip install .
|
|
41
|
-
```
|
|
29
|
+
Full documentation — user guide, tutorials, and API reference — is available on
|
|
30
|
+
[**Read the Docs**](https://pysimblocks.readthedocs.io).
|
|
42
31
|
|
|
43
32
|
## Getting Started
|
|
44
33
|
|
|
@@ -90,7 +79,7 @@ plot_from_config(logs, plot_cfg)
|
|
|
90
79
|
|
|
91
80
|
The resulting plot should look like this:
|
|
92
81
|
|
|
93
|
-

|
|
94
83
|
|
|
95
84
|
See [examples/quick_start/filter.py](./examples/quick_start/filter.py)
|
|
96
85
|
to run the example yourself.
|
|
@@ -113,14 +102,14 @@ The quick-start GUI project is stored in a single
|
|
|
113
102
|
|
|
114
103
|
#### Tutorials
|
|
115
104
|
|
|
116
|
-
Three step-by-step tutorials are available
|
|
117
|
-
[
|
|
105
|
+
Three step-by-step tutorials are available in the
|
|
106
|
+
[documentation](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/index.html):
|
|
118
107
|
|
|
119
108
|
| | Tutorial | Description |
|
|
120
109
|
|---|---|---|
|
|
121
|
-
| 1 | [Python API](
|
|
122
|
-
| 2 | [GUI](
|
|
123
|
-
| 3 | [SOFA](
|
|
110
|
+
| 1 | [Python API](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_1_python.html) | Build a closed-loop PI control system in pure Python |
|
|
111
|
+
| 2 | [GUI](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_2_gui.html) | Build the same system visually with the graphical editor |
|
|
112
|
+
| 3 | [SOFA](https://pysimblocks.readthedocs.io/en/latest/user_guide/tutorials/tutorial_3_sofa.html) | Replace the plant with a SOFA physics simulation |
|
|
124
113
|
|
|
125
114
|
|
|
126
115
|
#### Other Examples
|
|
@@ -129,7 +118,7 @@ A collection of basic and advanced examples is available in the
|
|
|
129
118
|
[examples](./examples) directory, including:
|
|
130
119
|
|
|
131
120
|
- Control system demonstrations
|
|
132
|
-
- SOFA-based simulations (tested with SOFA
|
|
121
|
+
- SOFA-based simulations (tested with SOFA v26.06 and later.)
|
|
133
122
|
- Hardware and real-time use cases
|
|
134
123
|
- Comparisons with external tools
|
|
135
124
|
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
# Authors: see Authors.txt
|
|
19
19
|
# ******************************************************************************
|
|
20
20
|
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
21
23
|
import warnings
|
|
22
24
|
|
|
23
25
|
import numpy as np
|
|
@@ -27,43 +29,26 @@ from pySimBlocks.core.block import Block
|
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class Pid(Block):
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
u_min
|
|
49
|
-
|
|
50
|
-
u_max : float, optional
|
|
51
|
-
Maximum output saturation.
|
|
52
|
-
sample_time : float, optional
|
|
53
|
-
Controller sampling period.
|
|
54
|
-
|
|
55
|
-
I/O:
|
|
56
|
-
Inputs:
|
|
57
|
-
e : error signal.
|
|
58
|
-
Outputs:
|
|
59
|
-
u : control command.
|
|
60
|
-
|
|
61
|
-
Notes:
|
|
62
|
-
- The block is strictly SISO.
|
|
63
|
-
- Integral action introduces internal state.
|
|
64
|
-
- If a parameter is not provided, the block falls back to its
|
|
65
|
-
internal default value.
|
|
66
|
-
- Output saturation is applied only if u_min and/or u_max are defined.
|
|
32
|
+
"""Discrete-time PID controller block.
|
|
33
|
+
|
|
34
|
+
Implements a single-input single-output discrete PID controller,
|
|
35
|
+
similar to the Simulink PID block. The controller computes a control
|
|
36
|
+
command from an error signal ``e`` using proportional, integral, and/or
|
|
37
|
+
derivative actions depending on the selected control mode.
|
|
38
|
+
|
|
39
|
+
Output saturation is applied only if ``u_min`` and/or ``u_max`` are set.
|
|
40
|
+
Anti-windup clamps the integrator state to the saturation bounds.
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
controller: Active control mode (``"P"``, ``"I"``, ``"PI"``,
|
|
44
|
+
``"PD"``, or ``"PID"``).
|
|
45
|
+
integration_method: Integration scheme for the I term
|
|
46
|
+
(``"euler forward"`` or ``"euler backward"``).
|
|
47
|
+
Kp: Proportional gain as a (1,1) array.
|
|
48
|
+
Ki: Integral gain as a (1,1) array.
|
|
49
|
+
Kd: Derivative gain as a (1,1) array.
|
|
50
|
+
u_min: Lower saturation bound as a (1,1) array, or None.
|
|
51
|
+
u_max: Upper saturation bound as a (1,1) array, or None.
|
|
67
52
|
"""
|
|
68
53
|
|
|
69
54
|
def __init__(
|
|
@@ -78,6 +63,27 @@ class Pid(Block):
|
|
|
78
63
|
integration_method: str = "euler forward",
|
|
79
64
|
sample_time: float | None = None,
|
|
80
65
|
):
|
|
66
|
+
"""Initialize a PID controller block.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
name: Unique identifier for this block instance.
|
|
70
|
+
controller: Control mode. Must be one of ``{"P", "I", "PI",
|
|
71
|
+
"PD", "PID"}``.
|
|
72
|
+
Kp: Proportional gain. Must be scalar-like.
|
|
73
|
+
Ki: Integral gain. Must be scalar-like.
|
|
74
|
+
Kd: Derivative gain. Must be scalar-like.
|
|
75
|
+
u_min: Minimum output saturation bound. None to disable.
|
|
76
|
+
u_max: Maximum output saturation bound. None to disable.
|
|
77
|
+
integration_method: Integration scheme for the I term.
|
|
78
|
+
Must be ``"euler forward"`` or ``"euler backward"``.
|
|
79
|
+
sample_time: Sampling period in seconds, or None to use the
|
|
80
|
+
global simulation dt.
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
ValueError: If ``controller`` or ``integration_method`` is
|
|
84
|
+
invalid, if any gain is not scalar-like, or if
|
|
85
|
+
``u_min > u_max``.
|
|
86
|
+
"""
|
|
81
87
|
super().__init__(name, sample_time)
|
|
82
88
|
|
|
83
89
|
controller = controller.upper()
|
|
@@ -95,7 +101,6 @@ class Pid(Block):
|
|
|
95
101
|
f"[{self.name}] Unsupported method '{self.integration_method}'. Allowed: {allowed}"
|
|
96
102
|
)
|
|
97
103
|
|
|
98
|
-
# Gains (SISO, (1,1))
|
|
99
104
|
self.Kp = self._to_siso("Kp", Kp)
|
|
100
105
|
self.Ki = self._to_siso("Ki", Ki)
|
|
101
106
|
self.Kd = self._to_siso("Kd", Kd)
|
|
@@ -109,13 +114,10 @@ class Pid(Block):
|
|
|
109
114
|
f"[{self.name}] u_min ({self.u_min.item()}) must be <= u_max ({self.u_max.item()})."
|
|
110
115
|
)
|
|
111
116
|
|
|
112
|
-
# Warnings
|
|
113
117
|
self._validate_gains()
|
|
114
118
|
|
|
115
|
-
# Direct feedthrough policy
|
|
116
119
|
has_p = "P" in self.controller
|
|
117
120
|
has_d = "D" in self.controller
|
|
118
|
-
has_i = "I" in self.controller
|
|
119
121
|
|
|
120
122
|
if has_p or has_d:
|
|
121
123
|
self.direct_feedthrough = True
|
|
@@ -123,11 +125,9 @@ class Pid(Block):
|
|
|
123
125
|
# I-only
|
|
124
126
|
self.direct_feedthrough = (self.integration_method == "euler backward")
|
|
125
127
|
|
|
126
|
-
# Ports
|
|
127
128
|
self.inputs["e"] = None
|
|
128
129
|
self.outputs["u"] = None
|
|
129
130
|
|
|
130
|
-
# State (SISO)
|
|
131
131
|
self.state["x_i"] = np.zeros((1, 1), dtype=float)
|
|
132
132
|
self.state["e_prev"] = np.zeros((1, 1), dtype=float)
|
|
133
133
|
self.next_state["x_i"] = np.zeros((1, 1), dtype=float)
|
|
@@ -137,12 +137,25 @@ class Pid(Block):
|
|
|
137
137
|
# --------------------------------------------------------------------------
|
|
138
138
|
# Public methods
|
|
139
139
|
# --------------------------------------------------------------------------
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
|
|
141
|
+
def initialize(self, t0: float) -> None:
|
|
142
|
+
"""Set the output to zero and keep internal states at zero.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
t0: Initial simulation time in seconds.
|
|
146
|
+
"""
|
|
142
147
|
self.outputs["u"] = np.zeros((1, 1), dtype=float)
|
|
143
148
|
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
def output_update(self, t: float, dt: float) -> None:
|
|
150
|
+
"""Compute the PID control command from the current error input.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
t: Current simulation time in seconds.
|
|
154
|
+
dt: Current time step in seconds.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
RuntimeError: If input ``e`` is not connected.
|
|
158
|
+
"""
|
|
146
159
|
e_in = self.inputs["e"]
|
|
147
160
|
if e_in is None:
|
|
148
161
|
raise RuntimeError(f"[{self.name}] Missing input 'e'.")
|
|
@@ -170,7 +183,6 @@ class Pid(Block):
|
|
|
170
183
|
|
|
171
184
|
u = P + I + D
|
|
172
185
|
|
|
173
|
-
# Saturation
|
|
174
186
|
if self.u_min is not None:
|
|
175
187
|
u = np.maximum(u, self.u_min)
|
|
176
188
|
if self.u_max is not None:
|
|
@@ -178,8 +190,16 @@ class Pid(Block):
|
|
|
178
190
|
|
|
179
191
|
self.outputs["u"] = u
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
|
|
193
|
+
def state_update(self, t: float, dt: float) -> None:
|
|
194
|
+
"""Update the integrator state and store the previous error.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
t: Current simulation time in seconds.
|
|
198
|
+
dt: Current time step in seconds.
|
|
199
|
+
|
|
200
|
+
Raises:
|
|
201
|
+
RuntimeError: If input ``e`` is not connected.
|
|
202
|
+
"""
|
|
183
203
|
e_in = self.inputs["e"]
|
|
184
204
|
if e_in is None:
|
|
185
205
|
raise RuntimeError(f"[{self.name}] Missing input 'e'.")
|
|
@@ -188,13 +208,12 @@ class Pid(Block):
|
|
|
188
208
|
|
|
189
209
|
has_i = "I" in self.controller
|
|
190
210
|
|
|
191
|
-
# Integrator update only if I term is enabled
|
|
192
211
|
if has_i:
|
|
193
212
|
x_i_next = self.state["x_i"] + self.Ki * e * dt
|
|
194
213
|
else:
|
|
195
214
|
x_i_next = self.state["x_i"].copy()
|
|
196
215
|
|
|
197
|
-
# Anti-windup
|
|
216
|
+
# Anti-windup: clamp integral state to saturation bounds
|
|
198
217
|
if self.u_min is not None:
|
|
199
218
|
x_i_next = np.maximum(x_i_next, self.u_min)
|
|
200
219
|
if self.u_max is not None:
|
|
@@ -207,10 +226,9 @@ class Pid(Block):
|
|
|
207
226
|
# --------------------------------------------------------------------------
|
|
208
227
|
# Private methods
|
|
209
228
|
# --------------------------------------------------------------------------
|
|
229
|
+
|
|
210
230
|
def _to_siso(self, name: str, value: ArrayLike) -> np.ndarray:
|
|
211
|
-
"""
|
|
212
|
-
Normalize scalar-like into (1,1). Reject anything else (strict SISO).
|
|
213
|
-
"""
|
|
231
|
+
"""Normalize a scalar-like value to a (1,1) array; reject anything else."""
|
|
214
232
|
if np.isscalar(value):
|
|
215
233
|
return np.array([[float(value)]], dtype=float)
|
|
216
234
|
|
|
@@ -227,8 +245,8 @@ class Pid(Block):
|
|
|
227
245
|
f"[{self.name}] '{name}' must be scalar-like ((), (1,), or (1,1)). Got shape {arr.shape}."
|
|
228
246
|
)
|
|
229
247
|
|
|
230
|
-
# ------------------------------------------------------------------
|
|
231
248
|
def _validate_gains(self) -> None:
|
|
249
|
+
"""Warn if a gain is zero for a mode that requires it."""
|
|
232
250
|
kp = float(self.Kp[0, 0])
|
|
233
251
|
ki = float(self.Ki[0, 0])
|
|
234
252
|
kd = float(self.Kd[0, 0])
|
|
@@ -18,45 +18,44 @@
|
|
|
18
18
|
# Authors: see Authors.txt
|
|
19
19
|
# ******************************************************************************
|
|
20
20
|
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
21
23
|
import numpy as np
|
|
24
|
+
from numpy.typing import ArrayLike
|
|
25
|
+
|
|
22
26
|
from pySimBlocks.core.block import Block
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
class StateFeedback(Block):
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
G
|
|
37
|
-
Reference feedforward gain matrix.
|
|
38
|
-
sample_time : float, optional
|
|
39
|
-
Block execution period.
|
|
40
|
-
|
|
41
|
-
Inputs:
|
|
42
|
-
r : array (p, 1)
|
|
43
|
-
Reference vector.
|
|
44
|
-
x : array (n, 1)
|
|
45
|
-
State vector.
|
|
46
|
-
|
|
47
|
-
Outputs:
|
|
48
|
-
u : array (m, 1)
|
|
49
|
-
Control vector.
|
|
50
|
-
|
|
51
|
-
Notes:
|
|
52
|
-
- Stateless block.
|
|
53
|
-
- This block intentionally enforces column-vector inputs.
|
|
54
|
-
- No implicit flattening is performed.
|
|
30
|
+
"""Discrete-time state-feedback controller block.
|
|
31
|
+
|
|
32
|
+
Implements a static discrete-time state-feedback control law:
|
|
33
|
+
|
|
34
|
+
u = G @ r - K @ x
|
|
35
|
+
|
|
36
|
+
Both inputs must be column vectors. No implicit flattening is performed.
|
|
37
|
+
|
|
38
|
+
Attributes:
|
|
39
|
+
K: State feedback gain matrix of shape (m, n).
|
|
40
|
+
G: Reference feedforward gain matrix of shape (m, p).
|
|
55
41
|
"""
|
|
56
42
|
|
|
57
43
|
direct_feedthrough = True
|
|
58
44
|
|
|
59
|
-
def __init__(self, name: str, K, G, sample_time: float | None = None):
|
|
45
|
+
def __init__(self, name: str, K: ArrayLike, G: ArrayLike, sample_time: float | None = None):
|
|
46
|
+
"""Initialize a StateFeedback block.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
name: Unique identifier for this block instance.
|
|
50
|
+
K: State feedback gain matrix, array-like of shape (m, n).
|
|
51
|
+
G: Reference feedforward gain matrix, array-like of shape (m, p).
|
|
52
|
+
sample_time: Sampling period in seconds, or None to use the
|
|
53
|
+
global simulation dt.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If K or G are not 2D, or if their first dimensions
|
|
57
|
+
do not match.
|
|
58
|
+
"""
|
|
60
59
|
super().__init__(name, sample_time)
|
|
61
60
|
|
|
62
61
|
self.K = np.asarray(K, dtype=float)
|
|
@@ -76,23 +75,27 @@ class StateFeedback(Block):
|
|
|
76
75
|
f"K is {self.K.shape} while G is {self.G.shape} (first dimension must match)."
|
|
77
76
|
)
|
|
78
77
|
|
|
79
|
-
# cached expected sizes for input validation
|
|
80
78
|
self._m = m
|
|
81
79
|
self._n = n
|
|
82
80
|
self._p = p
|
|
83
81
|
|
|
84
|
-
# Ports
|
|
85
82
|
self.inputs["r"] = None
|
|
86
83
|
self.inputs["x"] = None
|
|
87
84
|
self.outputs["u"] = None
|
|
88
85
|
|
|
89
|
-
# freeze input shapes once seen (optional but consistent)
|
|
90
86
|
self._input_shapes = {}
|
|
91
87
|
|
|
88
|
+
|
|
92
89
|
# --------------------------------------------------------------------------
|
|
93
90
|
# Public methods
|
|
94
91
|
# --------------------------------------------------------------------------
|
|
95
|
-
|
|
92
|
+
|
|
93
|
+
def initialize(self, t0: float) -> None:
|
|
94
|
+
"""Set the output to zero, or compute u if inputs are already available.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
t0: Initial simulation time in seconds.
|
|
98
|
+
"""
|
|
96
99
|
r = self.inputs["r"]
|
|
97
100
|
x = self.inputs["x"]
|
|
98
101
|
if r is None or x is None:
|
|
@@ -106,22 +109,45 @@ class StateFeedback(Block):
|
|
|
106
109
|
except Exception as _:
|
|
107
110
|
self.outputs["u"] = np.zeros((self._m, 1))
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
def output_update(self, t: float, dt: float) -> None:
|
|
113
|
+
"""Compute the control output u = G @ r - K @ x.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
t: Current simulation time in seconds.
|
|
117
|
+
dt: Current time step in seconds.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
RuntimeError: If input ``r`` or ``x`` is not connected.
|
|
121
|
+
ValueError: If input shapes do not match the gain matrices.
|
|
122
|
+
"""
|
|
111
123
|
r = self._require_col_vector("r", self._p)
|
|
112
124
|
x = self._require_col_vector("x", self._n)
|
|
113
125
|
|
|
114
126
|
self.outputs["u"] = self.G @ r - self.K @ x
|
|
115
127
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
pass
|
|
128
|
+
def state_update(self, t: float, dt: float) -> None:
|
|
129
|
+
"""No-op: StateFeedback carries no internal state."""
|
|
119
130
|
|
|
120
131
|
|
|
121
132
|
# --------------------------------------------------------------------------
|
|
122
133
|
# Private methods
|
|
123
134
|
# --------------------------------------------------------------------------
|
|
135
|
+
|
|
124
136
|
def _require_col_vector(self, port: str, expected_rows: int) -> np.ndarray:
|
|
137
|
+
"""Validate and return an input port value as a column vector.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
port: Name of the input port to read.
|
|
141
|
+
expected_rows: Expected number of rows in the column vector.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
The input value as a 2D (n, 1) float array.
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
RuntimeError: If the port value is None.
|
|
148
|
+
ValueError: If the array is not a column vector or has the
|
|
149
|
+
wrong number of rows.
|
|
150
|
+
"""
|
|
125
151
|
u = self.inputs[port]
|
|
126
152
|
if u is None:
|
|
127
153
|
raise RuntimeError(f"[{self.name}] Input '{port}' is not connected or not set.")
|
|
@@ -20,8 +20,12 @@
|
|
|
20
20
|
|
|
21
21
|
from pySimBlocks.blocks.interfaces.external_input import ExternalInput
|
|
22
22
|
from pySimBlocks.blocks.interfaces.external_output import ExternalOutput
|
|
23
|
+
from pySimBlocks.blocks.interfaces.goto import Goto
|
|
24
|
+
from pySimBlocks.blocks.interfaces.bus_from import BusFrom
|
|
23
25
|
|
|
24
26
|
__all__ = [
|
|
25
27
|
"ExternalInput",
|
|
26
|
-
"ExternalOutput"
|
|
28
|
+
"ExternalOutput",
|
|
29
|
+
"Goto",
|
|
30
|
+
"BusFrom",
|
|
27
31
|
]
|