I'm having trouble understanding an error message I'm getting from my GEKKO model.
For context, this model is supposed to optimize the gas spring force and dimension parameters of a gas-spring assisted door to minimize the operator force required to close the door. My intent is to calculate the required force at a series of angles between 0 and 90 degrees, then sum the absolute value of the force at all angles and minimize that value. There is also a constraint on the gas spring length so the optimization doesn't come up with unrealistic dimension parameters. I've defined the force and other values that need to be computed at each angle as lists of Intermediate variables.
The error appears to be related to one of these lists of Intermediate variables, but I don't know how to interpret "Position: 2" in the error message, let alone "Error in syntax of function string". I've searched in some other answers on here, but I haven't found a clear answer on how to use this position information to troubleshoot the model. What is the message trying to tell me?
apm gk_model0 <br><pre> ----------------------------------------------------------------
APMonitor, Version 1.0.1
APMonitor Optimization Suite
----------------------------------------------------------------
@error: Model Expression
*** Error in syntax of function string: Missing operator
Position: 2
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
?
Traceback (most recent call last):
File "C:\Users\github\general-calculations\Waterjet_Door\optimize_gas_spring_closure.py", line 80, in <module>
m.solve()
File "C:\Users\AppData\Local\Programs\Python\Python39\lib\site-packages\gekko\gekko.py", line 2185, in solve
raise Exception(response)
Exception: @error: Model Expression
*** Error in syntax of function string: Missing operator
Position: 2
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
?
Here's the code I'm running:
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
# Create GEKKO model
m = GEKKO()
# Fixed parameters:
Ldoor = m.Const(value=45.0) # Length of long leg of L-shaped door
cm_factor = m.Const(value=2/3) # factor for placing the center of mass of the door
Lcm = m.Const(value=cm_factor*Ldoor) # Distance along door to center of mass
W = m.Const(value=250.0) # Door weight (lbs)
ns = m.Const(value=2) # Number of gas springs in the design
wdoor = m.Const(value=5.75) # Length of short leg of door
min_angle = 1.0
max_angle = 90.0
npts = 90
theta = np.linspace(min_angle, max_angle, num=npts, endpoint=True)
# Define thetarad as a model parameter array
thetarad = m.Array(m.Param, npts, lb=min_angle, ub=max_angle)
for i,ti in enumerate(theta):
thetarad[i].value = ti*np.pi/180.0
# Design parameters:
ds = m.Var(28.0, lb=1.0, ub=Ldoor)
S = m.Var(200.0, lb=0.0, ub=250.0)
hp = m.Var(17.5, lb=15.0, ub=20.0)
wp = m.Var(2.0, lb=-5.0, ub=5.0)
sumabsforce = m.Var()
# Derived parameters
# S:
xs = [m.Intermediate(wdoor*m.cos(thetarad[i]) + ds*m.sin(thetarad[i])) for i in range(npts)]
ys = [m.Intermediate(ds*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Ls = m.Intermediate(m.sqrt(wdoor**2 + ds**2))
# W:
xw = [m.Intermediate(wdoor*m.cos(thetarad[i]) + Lcm*m.sin(thetarad[i])) for i in range(npts)]
yw = [m.Intermediate(Lcm*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Lw = m.Intermediate(m.sqrt(wdoor**2 + Lcm**2))
# F:
xf = [m.Intermediate(wdoor*m.cos(thetarad[i]) + Ldoor*m.sin(thetarad[i])) for i in range(npts)]
yf = [m.Intermediate(Ldoor*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Lf = m.Intermediate(m.sqrt(wdoor**2 + Ldoor**2))
# Gas spring length
ls = [m.Intermediate(m.sqrt((xs - wp)**2 + (hp - ys)**2)) for i in range(npts)]
# Angles
phi = [m.Intermediate(m.atan((hp-ys[i])/(xs[i]-wp))) for i in range(npts)]
beta = [m.Intermediate(m.atan(ys[i]/xs[i])) for i in range(npts)]
gamma = [m.Intermediate(m.atan(yw[i]/xw[i])) for i in range(npts)]
kappa = [m.Intermediate(m.atan(yf[i]/xf[i])) for i in range(npts)]
alpha = [m.Intermediate(beta[i] + phi[i]) for i in range(npts)]
psi = [m.Intermediate(np.pi/2 - gamma[i]) for i in range(npts)]
# Calculate the force required at each angle:
force = [m.Intermediate((W*Lw*m.sin(psi[i]) - ns*S*Ls*m.sin(alpha[i])) / Lf) for i in range(npts)]
# Spring length constraint
maxspring = m.Intermediate(ls[0].value)
minspring = m.Intermediate(100.0)
for i,lsi in enumerate(ls):
if lsi.value > maxspring.value:
maxspring.value = lsi.value
if lsi.value < minspring.value:
minspring.value = lsi.value
m.Equation(maxspring<(2*minspring)) # Reject unrealistic gas spring extension
absforce = [m.Intermediate(m.abs(force[i])) for i in range(npts)]
m.Equation(sumabsforce==m.sum(absforce))
m.Minimize(sumabsforce)
m.options.SOLVER=1
m.solve()
print(ds, S, hp, wp)
One way to locate the error is to open the run directory and inspect the text model file gk_model0.apm
.
Model
Constants
i0 = 45.0
i1 = 0.6666666666666666
i2 = 0
i3 = 250.0
i4 = 2
i5 = 5.75
End Constants
Parameters
p1 = 0.017453292519943295, <= 90.0, >= 1.0
p2 = 0.03490658503988659, <= 90.0, >= 1.0
p3 = 0.05235987755982988, <= 90.0, >= 1.0
p4 = 0.06981317007977318, <= 90.0, >= 1.0
p5 = 0.08726646259971647, <= 90.0, >= 1.0
p6 = 0.10471975511965977, <= 90.0, >= 1.0
p7 = 0.12217304763960307, <= 90.0, >= 1.0
p8 = 0.13962634015954636, <= 90.0, >= 1.0
p9 = 0.15707963267948966, <= 90.0, >= 1.0
...
i546=(((i0)*(cos(p89)))-((i5)*(sin(p89))))
i547=(((i0)*(cos(p90)))-((i5)*(sin(p90))))
i548=sqrt((((i5)^(2))+((i0)^(2))))
i549=sqrt((((([0, 0, 0, 0, 0, 0, 0, 0, 0, ...]))^(2))))
The i548
appears to be this equation: Lf = m.Intermediate(m.sqrt(wdoor**2 + Ldoor**2))
. The next equation is the one where a list is passed instead of a number or gekko variable type.
Problem Intermediate Equation
ls = [m.Intermediate(m.sqrt((xs - wp)**2 + (hp - ys)**2)) \
for i in range(npts)]
Corrected Equation
The corrected equation has xs[i]
and ys[i]
.
ls = [m.Intermediate(m.sqrt((xs[i] - wp)**2 + (hp - ys[i])**2)) \
for i in range(npts)]
With this correction, the problem still does not solve. Replace m.abs()
with m.abs3()
to get a successful solution.
import numpy as np
import matplotlib.pyplot as plt
from gekko import GEKKO
# Create GEKKO model
m = GEKKO()
# Fixed parameters:
Ldoor = m.Const(value=45.0) # Length of long leg of L-shaped door
cm_factor = m.Const(value=2/3) # factor for placing the center of mass of the door
Lcm = m.Const(value=cm_factor*Ldoor) # Distance along door to center of mass
W = m.Const(value=250.0) # Door weight (lbs)
ns = m.Const(value=2) # Number of gas springs in the design
wdoor = m.Const(value=5.75) # Length of short leg of door
min_angle = 1.0
max_angle = 90.0
npts = 90
theta = np.linspace(min_angle, max_angle, num=npts, endpoint=True)
# Define thetarad as a model parameter array
thetarad = m.Array(m.Param, npts, lb=min_angle, ub=max_angle)
for i,ti in enumerate(theta):
thetarad[i].value = ti*np.pi/180.0
# Design parameters:
ds = m.Var(28.0, lb=1.0, ub=Ldoor)
S = m.Var(200.0, lb=0.0, ub=250.0)
hp = m.Var(17.5, lb=15.0, ub=20.0)
wp = m.Var(2.0, lb=-5.0, ub=5.0)
sumabsforce = m.Var()
# Derived parameters
# S:
xs = [m.Intermediate(wdoor*m.cos(thetarad[i]) + ds*m.sin(thetarad[i])) for i in range(npts)]
ys = [m.Intermediate(ds*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Ls = m.Intermediate(m.sqrt(wdoor**2 + ds**2))
# W:
xw = [m.Intermediate(wdoor*m.cos(thetarad[i]) + Lcm*m.sin(thetarad[i])) for i in range(npts)]
yw = [m.Intermediate(Lcm*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Lw = m.Intermediate(m.sqrt(wdoor**2 + Lcm**2))
# F:
xf = [m.Intermediate(wdoor*m.cos(thetarad[i]) + Ldoor*m.sin(thetarad[i])) for i in range(npts)]
yf = [m.Intermediate(Ldoor*m.cos(thetarad[i]) - wdoor*m.sin(thetarad[i])) for i in range(npts)]
Lf = m.Intermediate(m.sqrt(wdoor**2 + Ldoor**2))
# Gas spring length
ls = [m.Intermediate(m.sqrt((xs[i] - wp)**2 + (hp - ys[i])**2)) for i in range(npts)]
# Angles
phi = [m.Intermediate(m.atan((hp-ys[i])/(xs[i]-wp))) for i in range(npts)]
beta = [m.Intermediate(m.atan(ys[i]/xs[i])) for i in range(npts)]
gamma = [m.Intermediate(m.atan(yw[i]/xw[i])) for i in range(npts)]
kappa = [m.Intermediate(m.atan(yf[i]/xf[i])) for i in range(npts)]
alpha = [m.Intermediate(beta[i] + phi[i]) for i in range(npts)]
psi = [m.Intermediate(np.pi/2 - gamma[i]) for i in range(npts)]
# Calculate the force required at each angle:
force = [m.Intermediate((W*Lw*m.sin(psi[i]) - ns*S*Ls*m.sin(alpha[i])) / Lf) for i in range(npts)]
# Spring length constraint
maxspring = m.Intermediate(ls[0].value)
minspring = m.Intermediate(100.0)
for i,lsi in enumerate(ls):
if lsi.value > maxspring.value:
maxspring.value = lsi.value
if lsi.value < minspring.value:
minspring.value = lsi.value
m.Equation(maxspring<(2*minspring)) # Reject unrealistic gas spring extension
absforce = [m.Intermediate(m.abs3(force[i])) for i in range(npts)]
m.Equation(sumabsforce==m.sum(absforce))
m.Minimize(sumabsforce)
m.options.SOLVER=1
m.open_folder()
m.solve()
print(ds.value[0], S.value[0], hp.value[0], wp.value[0])
The solution for ds
, S
, hp
, and wp
is 1.0 123.75259617 20.0 1.0445275485
. Remove the m.open_folder()
to not open the run folder.