alphaville / optimization-engine

Nonconvex embedded optimization: code generation for fast real-time optimization + ROS support
https://alphaville.github.io/optimization-engine/
Other
512 stars 53 forks source link

Example fails with "No method named 'cost' for struct AlmOptimizerStatus." #178

Closed siedentop closed 4 years ago

siedentop commented 4 years ago

Describe the bug

Running the Python Example "Navigation" fails out of the box. No method named 'cost' for struct AlmOptimizerStatus.

To Reproduce

Steps to reproduce the behavior:

  1. Install 'opengen' using pip
  2. Copy the above linked example (full text below) and run it.
  3. Observe the below error

Output:

❯ pipenv run ./example_navigation.py
[INFO] Initialising builder
[INFO] Checking user parameters
[INFO] Creating necessary folders
[INFO] Copying icasadi interface to target directory
[INFO] Generating icasadi's Cargo.toml
[INFO] Generating Cargo.toml for target optimizer
[INFO] Generating icasadi Rust library file
[INFO] Defining CasADi functions and generating C code
[INFO] Defining function psi(u, xi, p) and its gradient
[INFO] Function psi and its gradient (C code)
[INFO] Defining function F1(u, p)
[INFO] Mapping F1 (C code)
[INFO] Defining function F2(u, p)
[INFO] Mapping F2 (C code)
[INFO] Generating casadi_memory.h
[INFO] Generating intercafe.c (C interface)
[INFO] Generating main code for target optimizer (lib.rs)
[INFO] Generating build.rs for target optimizer
[INFO] Generating YAML configuration file
[INFO] Building optimizer
[INFO] Generating TCP/IP server
[INFO] Generating code for TCP/IP interface (tcp_iface/src/main.rs)
[INFO] TCP server will bind at 127.0.0.1:8333
[INFO] Building the TCP interface
error[E0599]: no method named `cost` found for struct `optimization_engine::alm::alm_optimizer_status::AlmOptimizerStatus` in the current scope
   --> src/main.rs:108:22
    |
108 |         cost: status.cost(),
    |                      ^^^^ method not found in `optimization_engine::alm::alm_optimizer_status::AlmOptimizerStatus`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `tcp_iface_navigation`.

To learn more, run the command again with --verbose.
Traceback (most recent call last):
  File "./example_navigation.py", line 52, in <module>
    builder.build()
  File "/Users/<me>/.local/share/virtualenvs/open_optimizer-3LaGqM--/lib/python3.7/site-packages/opengen/builder/optimizer_builder.py", line 578, in build
    self.__build_tcp_iface()
  File "/Users/<me>/.local/share/virtualenvs/open_optimizer-3LaGqM--/lib/python3.7/site-packages/opengen/builder/optimizer_builder.py", line 433, in __build_tcp_iface
    raise Exception('Rust build of TCP interface failed')
Exception: Rust build of TCP interface failed

Expected behavior

I would like to see the example to run out of the box.

System information:

:warning: Please, provide the following information:

installed toolchains

stable-x86_64-apple-darwin nightly-x86_64-apple-darwin (default)

installed targets for active toolchain

wasm32-unknown-unknown x86_64-apple-darwin

active toolchain

nightly-x86_64-apple-darwin (default) rustc 1.44.0-nightly (b2e36e6c2 2020-04-22)

 - What is the output of `rustc -V`?
```shell
❯ rustc -V
rustc 1.44.0-nightly (b2e36e6c2 2020-04-22)

Additional context

Add any other context about the problem here.

Here is the example code in full, for full reproducibility.

#!/usr/bin/env python3
# https://alphaville.github.io/optimization-engine/docs/example_navigation_py
import opengen as og
import casadi.casadi as cs
import matplotlib.pyplot as plt
import numpy as np

# Build parametric optimizer
# ------------------------------------
(nu, nx, N) = (2, 3, 20)
L = 0.5
ts = 0.1
(xref , yref, thetaref) = (1, 1, 0)
(q, qtheta, r, qN, qthetaN) = (10, 0.1, 1, 200, 2)

u = cs.SX.sym('u', nu*N)
z0 = cs.SX.sym('z0', nx)

(x, y, theta) = (z0[0], z0[1], z0[2])
cost = 0

for t in range(0, nu*N, nu):
    cost += q*((x-xref)**2 + (y-yref)**2) + qtheta*(theta-thetaref)**2
    u_t = u[t:t+2]
    theta_dot = (1/L) * (u_t[1] * cs.cos(theta) - u_t[0] * cs.sin(theta))
    cost += r * cs.dot(u_t, u_t)
    x += ts * (u_t[0] + L * cs.sin(theta) * theta_dot)
    y += ts * (u_t[1] - L * cs.cos(theta) * theta_dot)
    theta += ts * theta_dot

cost += qN*((x-xref)**2 + (y-yref)**2) + qthetaN*(theta-thetaref)**2

umin = [-3.0] * (nu*N)
umax = [3.0] * (nu*N)
bounds = og.constraints.Rectangle(umin, umax)

problem = og.builder.Problem(u, z0, cost).with_constraints(bounds)
build_config = og.config.BuildConfiguration()\
    .with_build_directory("python_test_build")\
    .with_build_mode("debug")\
    .with_tcp_interface_config()
meta = og.config.OptimizerMeta()\
    .with_optimizer_name("navigation")
solver_config = og.config.SolverConfiguration()\
    .with_tolerance(1e-5)
builder = og.builder.OpEnOptimizerBuilder(problem, 
                                          meta,
                                          build_config, 
                                          solver_config) \
    .with_verbosity_level(1)
builder.build()

# Use TCP server
# ------------------------------------
mng = og.tcp.OptimizerTcpManager('python_test_build/navigation')
mng.start()

mng.ping()
solution = mng.call([-1.0, 2.0, 0.0], initial_guess=[1.0] * (nu*N))
mng.kill()

# Plot solution
# ------------------------------------
time = np.arange(0, ts*N, ts)
u_star = solution['solution']
ux = u_star[0:nu*N:2]
uy = u_star[1:nu*N:2]

plt.subplot(211)
plt.plot(time, ux, '-o')
plt.ylabel('u_x')
plt.subplot(212)
plt.plot(time, uy, '-o')
plt.ylabel('u_y')
plt.xlabel('Time')
plt.show()
alphaville commented 4 years ago

Opengen version 0.5.0a2 is experimental (we will release version 0.5.0 soon). If you want to use it, you need to link to the core OpEn Rust library, version 0.7.0-alpha.1.

To do so, you need to add the following option to your build configuration in Python:

.with_open_version('0.7.0-alpha.1')