.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples/time_switch.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_time_switch.py: Optimal Transfer With Time Trigger ================================== .. GENERATED FROM PYTHON SOURCE LINES 5-19 .. code-block:: Python from time import perf_counter import matplotlib.pyplot as plt import numpy as np from _sgm_test_util import LTI_plot import condor as co # either include time as state or increase tolerances to ensure sufficient ODE solver # accuracy with_time_state = False .. GENERATED FROM PYTHON SOURCE LINES 20-21 Define the double integrator system .. GENERATED FROM PYTHON SOURCE LINES 21-38 .. code-block:: Python class DblInt(co.ODESystem): A = np.array([[0, 1], [0, 0]]) B = np.array([[0], [1]]) x = state(shape=A.shape[0]) mode = state() u = modal() dot[x] = A @ x + B * u if with_time_state: tt = state() dot[tt] = 1.0 .. GENERATED FROM PYTHON SOURCE LINES 39-40 Now a mode to accelerate .. GENERATED FROM PYTHON SOURCE LINES 40-47 .. code-block:: Python class Accel(DblInt.Mode): condition = mode == 0.0 action[u] = 1.0 .. GENERATED FROM PYTHON SOURCE LINES 48-50 An event to switch to deceleration, specified by a paramter :math:`t_1`. We'll also create a state to capture the position at the switch event. .. GENERATED FROM PYTHON SOURCE LINES 50-61 .. code-block:: Python class Switch1(DblInt.Event): t1 = parameter() pos_at_switch = state() at_time = t1 update[mode] = 1.0 update[pos_at_switch] = x[0] .. GENERATED FROM PYTHON SOURCE LINES 62-64 Now the mode to switch to deceleration, triggered by ``Switch1`` updating the ``mode``. .. GENERATED FROM PYTHON SOURCE LINES 64-71 .. code-block:: Python class Decel(DblInt.Mode): condition = mode == 1.0 action[u] = -1.0 .. GENERATED FROM PYTHON SOURCE LINES 72-73 Finally a terminating event specified by a new parameter :math:`t_2`. .. GENERATED FROM PYTHON SOURCE LINES 73-81 .. code-block:: Python class Switch2(DblInt.Event): t2 = parameter() at_time = Switch1.t1 + t2 terminate = True .. GENERATED FROM PYTHON SOURCE LINES 82-84 The trajectory analysis adds a terminal quadratic cost for error with respect to the desired final position :math:`(0, 0)`. .. GENERATED FROM PYTHON SOURCE LINES 84-101 .. code-block:: Python class Transfer(DblInt.TrajectoryAnalysis): initial[x] = [-9.0, 0.0] Q = np.eye(2) cost = trajectory_output((x.T @ Q @ x) / 2) if not with_time_state: class Options: state_adaptive_max_step_size = 4 sim = Transfer(t1=1.0, t2=4.0) print(sim.pos_at_switch) # jac = sim.implementation.callback.jac_callback(sim.implementation.callback.p, []) .. rst-class:: sphx-glr-script-out .. code-block:: none [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5] .. GENERATED FROM PYTHON SOURCE LINES 102-104 Now embed the trajectory analysis in an optimization to minimize the final position error over transfer and final times. .. GENERATED FROM PYTHON SOURCE LINES 104-128 .. code-block:: Python class MinimumTime(co.OptimizationProblem): t1 = variable(lower_bound=0) t2 = variable(lower_bound=0) transfer = Transfer(t1, t2) objective = transfer.cost class Options: # exact_hessian = False __implementation__ = co.implementations.ScipyCG """ old: eval jacobian for jac_Transfer args [DM([1, 4]), DM(00)] p=[1, 4] [[-56.9839, 0]] """ .. rst-class:: sphx-glr-script-out .. code-block:: none '\nold:\neval jacobian for jac_Transfer\nargs [DM([1, 4]), DM(00)]\np=[1, 4]\n[[-56.9839, 0]]\n\n\n\n' .. GENERATED FROM PYTHON SOURCE LINES 129-141 .. code-block:: Python MinimumTime.set_initial(t1=2.163165480675697, t2=4.361971866705403) t_start = perf_counter() opt = MinimumTime() t_stop = perf_counter() print("time to run:", t_stop - t_start) print(opt.t1, opt.t2) # print(jac) print(opt._stats) .. rst-class:: sphx-glr-script-out .. code-block:: none /opt/hostedtoolcache/Python/3.12.11/x64/lib/python3.12/site-packages/condor/implementations/iterative.py:481: RuntimeWarning: Method CG cannot handle bounds. min_out = minimize( time to run: 0.3653668100000118 [2.99999968] [2.99999216] message: Optimization terminated successfully. success: True status: 0 fun: 3.008671708973335e-11 x: [ 3.000e+00 3.000e+00] nit: 12 jac: [-4.048e-06 -7.514e-06] nfev: 22 njev: 22 .. GENERATED FROM PYTHON SOURCE LINES 142-145 .. code-block:: Python LTI_plot(opt.transfer) .. rst-class:: sphx-glr-horizontal * .. image-sg:: /examples/images/sphx_glr_time_switch_001.png :alt: Transfer TransferState.x :srcset: /examples/images/sphx_glr_time_switch_001.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_time_switch_002.png :alt: Transfer TransferState.mode :srcset: /examples/images/sphx_glr_time_switch_002.png :class: sphx-glr-multi-img * .. image-sg:: /examples/images/sphx_glr_time_switch_003.png :alt: Transfer TransferState.pos_at_switch :srcset: /examples/images/sphx_glr_time_switch_003.png :class: sphx-glr-multi-img .. GENERATED FROM PYTHON SOURCE LINES 146-147 Another version of the transfer analysis excluding the switch event. .. GENERATED FROM PYTHON SOURCE LINES 147-167 .. code-block:: Python class AccelerateTransfer(DblInt.TrajectoryAnalysis, exclude_events=[Switch1]): initial[x] = [-9.0, 0.0] Q = np.eye(2) cost = trajectory_output((x.T @ Q @ x) / 2) if not with_time_state: class Options: state_adaptive_max_step_size = 4 # TODO? # class AccelerateTransfer(Transfer, exclude_events=[Switch1]): # pass sim_accel = AccelerateTransfer(**opt.transfer.parameter.asdict()) assert sim_accel._res.e[0].rootsfound.size == opt.transfer._res.e[0].rootsfound.size - 1 # noqa .. GENERATED FROM PYTHON SOURCE LINES 168-170 .. code-block:: Python plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.744 seconds) .. _sphx_glr_download_examples_time_switch.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: time_switch.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: time_switch.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: time_switch.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_