|
15 | 15 | from control.tests.conftest import slycotonly |
16 | 16 | from numpy.lib import NumpyVersion |
17 | 17 |
|
| 18 | + |
18 | 19 | def test_finite_horizon_simple(): |
19 | 20 | # Define a linear system with constraints |
20 | 21 | # Source: https://www.mpt3.org/UI/RegulationProblem |
@@ -108,6 +109,7 @@ def test_discrete_lqr(): |
108 | 109 | # Make sure we got a different solution |
109 | 110 | assert np.any(np.abs(res1.inputs - res2.inputs) > 0.1) |
110 | 111 |
|
| 112 | + |
111 | 113 | def test_mpc_iosystem(): |
112 | 114 | # model of an aircraft discretized with 0.2s sampling time |
113 | 115 | # Source: https://www.mpt3.org/UI/RegulationProblem |
@@ -212,6 +214,7 @@ def test_constraint_specification(constraint_list): |
212 | 214 | np.testing.assert_almost_equal( |
213 | 215 | u_openloop, [-1, -1, 0.1393, 0.3361, -5.204e-16], decimal=3) |
214 | 216 |
|
| 217 | + |
215 | 218 | @pytest.mark.parametrize("sys_args", [ |
216 | 219 | pytest.param( |
217 | 220 | ([[1, 0], [0, 1]], np.eye(2), np.eye(2), 0, True), |
@@ -319,6 +322,7 @@ def test_terminal_constraints(sys_args): |
319 | 322 | res = optctrl.compute_trajectory(x0, squeeze=True, return_x=True) |
320 | 323 | assert not res.success |
321 | 324 |
|
| 325 | + |
322 | 326 | def test_optimal_logging(capsys): |
323 | 327 | """Test logging functions (mainly for code coverage)""" |
324 | 328 | sys = ct.ss2io(ct.ss(np.eye(2), np.eye(2), np.eye(2), 0, 1)) |
@@ -435,14 +439,31 @@ def test_optimal_basis_simple(): |
435 | 439 | cost = opt.quadratic_cost(sys, Q, R) |
436 | 440 |
|
437 | 441 | # Set up the optimal control problem |
438 | | - time = np.arange(0, 5, 1) |
| 442 | + Tf = 5 |
| 443 | + time = np.arange(0, Tf, 1) |
439 | 444 | x0 = [4, 0] |
440 | 445 |
|
441 | 446 | # Basic optimal control problem |
442 | | - res = opt.solve_ocp(sys, time, x0, cost, constraints, return_x=True) |
443 | | - assert res.success |
| 447 | + res1 = opt.solve_ocp( |
| 448 | + sys, time, x0, cost, constraints, |
| 449 | + basis=flat.BezierFamily(4, Tf), return_x=True) |
| 450 | + assert res1.success |
444 | 451 |
|
445 | 452 | # Make sure the constraints were satisfied |
446 | | - np.testing.assert_array_less(np.abs(res.states[0]), 5 + 1e-6) |
447 | | - np.testing.assert_array_less(np.abs(res.states[1]), 5 + 1e-6) |
448 | | - np.testing.assert_array_less(np.abs(res.inputs[0]), 1 + 1e-6) |
| 453 | + np.testing.assert_array_less(np.abs(res1.states[0]), 5 + 1e-6) |
| 454 | + np.testing.assert_array_less(np.abs(res1.states[1]), 5 + 1e-6) |
| 455 | + np.testing.assert_array_less(np.abs(res1.inputs[0]), 1 + 1e-6) |
| 456 | + |
| 457 | + # Pass an initial guess and rerun |
| 458 | + res2 = opt.solve_ocp( |
| 459 | + sys, time, x0, cost, constraints, initial_guess=0.99*res1.inputs, |
| 460 | + basis=flat.BezierFamily(4, Tf), return_x=True) |
| 461 | + assert res2.success |
| 462 | + np.testing.assert_almost_equal(res2.inputs, res1.inputs, decimal=3) |
| 463 | + |
| 464 | + # Run with logging turned on for code coverage |
| 465 | + res3 = opt.solve_ocp( |
| 466 | + sys, time, x0, cost, constraints, |
| 467 | + basis=flat.BezierFamily(4, Tf), return_x=True, log=True) |
| 468 | + assert res3.success |
| 469 | + np.testing.assert_almost_equal(res3.inputs, res1.inputs, decimal=3) |
0 commit comments