Interesting problem here. On our school's Windows server, Matlab can execute the place function in the following code perfectly well and return a 1x4 matrix assigned to variable K. However, the Linux servers, and Matlab on my personal computer (Windows 8.1) all return multiple errors. The solution to the state space matrices is correct. I have also tried simply creating an A and B matrix with values of type Double rather than symbolic matrices, to no avail. The errors are as follows:
Error using symengine
Cannot prove '(0.00000000000011152837950971767051666806677642 < 5.0227916840119976230900756087285) < 2' literally. To test the statement
mathematically, use isAlways.
Error in sym/logical (line 360)
X = mupadmex('symobj::logical',A.s,9);
Error in sym/any (line 417)
X = any(logical(A));
Error in place (line 77)
if any(mult>m)
The relevant code I am trying to execute is this:
syms theta thetadot y ydot u s;
I2 = 0.05;
I1 = 0.2;
m2 = 2;
r = 0.11;
a = 0.1;
g = 9.81;
x0 = [20 * pi / 180 0.2 0 0];
W = [I1 + I2 + m2 * (y^2 + r^2) m2 * r + I2 / a; m2 * r + I2 / a m2 + I2 / a^2];
qdd = W^(-1) * ([u; 0] - (m2 * [2*y*thetadot*ydot; -y*thetadot^2] - m2*g* [r*sin(theta) + y*cos(theta); sin(theta)]));
qd = [thetadot; ydot];
xdot = [qd; qdd];
eq = [0 0 0 0 0 ];
x3bytheta = subs(diff(qdd(1), theta), {theta, y, thetadot, ydot, u}, eq);
x3byy = subs(diff(qdd(1), y), {theta, y, thetadot, ydot, u}, eq);
x3bythetadot = subs(diff(qdd(1), thetadot), {theta, y, thetadot, ydot, u}, eq);
x3byydot = subs(diff(qdd(1), ydot), {theta, y, thetadot, ydot, u}, eq);
x4bytheta = subs(diff(qdd(2), theta), {theta, y, thetadot, ydot, u}, eq);
x4byy = subs(diff(qdd(2), y), {theta, y, thetadot, ydot, u}, eq);
x4bythetadot = subs(diff(qdd(2), thetadot), {theta, y, thetadot, ydot, u}, eq);
x4byydot = subs(diff(qdd(2), ydot), {theta, y, thetadot, ydot, u}, eq);
x3byu = subs(diff(qdd(1), u), {theta, y, thetadot, ydot, u}, eq);
x4byu = subs(diff(qdd(2), u), {theta, y, thetadot, ydot, u}, eq);
A = [0 0 1 0; 0 0 0 1; x3bytheta x3byy x3bythetadot x3byydot; x4bytheta x4byy x4bythetadot x4byydot];
B = [0; 0; x3byu; x4byu];
K = place(vpa(A, 3), vpa(B, 3), [-1, -2, -1+2j, -1-2j]);
The difference in behavior comes from an R2015a update to the Symbolic Toolbox (last entry), and quoting from the current documentation of symbolic gt
:
In previous releases,
gt
in some cases evaluated inequalities involving only symbolic numbers and returned logical1
or0
. To obtain the same results as in previous releases, wrap inequalities inisAlways
. For example, useisAlways(A > B)
.
And the symbolic comparison persists even if both operands are constant; which is, not having been at the architecture meeting, a rather big oversight and quizzical behavior.
Unfortunately, since place
was written from a "double
-use first" perspective, the function relies on the summation of logicals to produce numeric output and not symbolic expressions.
I can see two methods to remedy this situation:
A
and B
as doubles, which you have already noted works.place
function and wrap all pertinent logical comparisons in isAlways
to evaluate the comparisons. The lines of interest I've found are (if not exact, are close to) 60, 105, 117, and 123.