alphaville / optimization-engine

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

Issues with sending/receiving large requests via TCP/IP #83

Closed BjoernLindqvist closed 4 years ago

BjoernLindqvist commented 5 years ago

Describe the bug

When calling the solver via TCP/IP with

solution = mng.call(z0, initial_guess=[0.0]*(nu * N))

I get the JSON error message

File "/usr/lib/python3.5/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 167 column 1 (char 4096)

using a parameter of size 41 and 240 decision variables (Control Horizon 40). Running the same code with parameter size of 41 but 12 decision variables (Control Horizon 2) it works as it should. Seems to be a problem with the buffer but changing READ_BUFFER_SIZE in tcp_iface/main.rs doesn't fix it.

To Reproduce

Steps to reproduce the behavior: Run the provided python code (provided as .txt file) with N=40 (line 8) for error and N=2 for success (actually any N smaller than 27 ).

crazyflie_multiple.txt

korken89 commented 5 years ago

@alphaville Will you take this? I have no clue about the TCP interface.

alphaville commented 5 years ago

@korken89 Sure. I haven't had much time to have a look yet. I'm trying to complete the ALM/PM implementation. ~I'll have a look in the weekend~.

alphaville commented 5 years ago

Not a solution - just a little update. If you start the TCP server, which runs in Rust, and you call it from terminal with:

echo '{"Run" : {"parameter": [2.0,2.0,1.0,0.0,0.0,0.0,0.0,0.0,1.0,2.0,1.0,0.0,0.0,0.0,0.0,0.0,-2.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,9.81,0.0,0.0,9.81,0.0,0.0,9.81,0.0,0.0], "initial_guess": [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,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,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,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]}}' | nc localhost 4598

it responds properly and returns the following solution:

{
  "exit_status": "Converged",
  "num_outer_iterations": 1,
  "num_inner_iterations": 21,
  "last_problem_norm_fpr": 0.005691828326753441,
  "max_constraint_violation": 0.0,
  "solve_time_ms": 40.494251,
  "solution": [
    9.817184238377624,
    0.30017624143239463,
    -0.3,
    9.853646109875907,
    0.3000657096681582,
    -0.3000605854974152,
    ...
    9.801476872708424,
    -0.0018886857390608084,
    0.0019196929071113931
  ]
}

(the ellipsis is mine for brevity), therefore, the error is in Python.

alphaville commented 5 years ago

@BjoernLindqvist I found a way to fix this properly. Till then you can set the buffer length to something very large - try the following hack

solution = mng.call(z0, initial_guess=[0.0]*(nu*N), buffer_len=32768)

this works with N=50.

BjoernLindqvist commented 5 years ago

Seems to work fine! Thank you! Sorry if I just missed this in the documentation. I get at most 2-3ms solver time for (centralized) 2 MAV's with penalty constraints for collision avoidance, which is quite impressive. :D

alphaville commented 5 years ago

@BjoernLindqvist This was a bug, though - thanks for spotting this. The idea is that it should work for any buffer size; then the user may choose to fine-tune the buffer length for higher throughput. We will merge #84 into master soon and release a new version on OpEn. Till then you can copy the fix from #84 in your Python code (but you need to re-compile OpEn, not use pip).