fdevinc / ungar

Simplifying optimal control with metaprogramming
Apache License 2.0
97 stars 11 forks source link

Real time system with visual. #11

Open andrewcz opened 9 months ago

andrewcz commented 9 months ago

Hi @fdevinc , really interesting library and great project. Just have a couple of slightly open ended questions. want to use the library for a university project, looking at control systems on real time streams.

fdevinc commented 9 months ago

Hi @andrewcz, thank you for your words and for reaching out! I am not sure what you mean exactly by "real-time stream". Are you asking if there is a way to enforce a certain frequency upon the existing solver? If that is it, then no, at the moment the only way you have to limit the maximum computation time is by setting a maximum number of iterations. However, I think you should still be able to run the solver on a separate thread and check its state at the frequency you are interested in.

As to the second question, you may easily access the results of your optimizations as shown in example. For example, to plot the value of a certain variable in time, you may export it to a CSV file and then plot it using Python. The C++ code for this could be something like:

// Solve your optimal control problem and store the result in 'variables_'.
// ...

// Export the results to CSV.
std::ofstream out("out.csv");
if (!out.is_open()) {
    return 1;
}

for (const auto k : enumerate(N)) {    // Assuming 'x' is three-dimensional.
    out << k << ","
        << variables_.Get(x, k).x() << ","
        << variables_.Get(x, k).y() << ","
        << variables_.Get(x, k).z() << std::endl;
}
out.close();

I hope this helps, feel free to ask if you need further clarification or assistance!

andrewcz commented 9 months ago

@fdevinc ! Thank you so much! very generous! tbh im really just thinking out loud at the moment in terms of application development. Some rough thoughts would be the following.

Im thinking a rolling buffer (currently looking at a ring buffer data structure). Where the data is fed through an api (possibly)

To start I could generate a dummy stream have it go through a window type buffer data system and then have the output be plotted by - https://github.com/epezent/implot/blob/master/implot_demo.cpp

I was thinking of using the example where you look at a function - https://github.com/fdevinc/ungar/blob/main/example/autodiff/function.example.cpp

Curious to get your thoughts on the above.

Best, Andrew

fdevinc commented 9 months ago

You are welcome! While I might need a bit more context to offer the most precise assistance, your ideas sound quite feasible to me. You may just give them a shot and see how it goes! If you encounter any roadblocks or need further assistance along the way, feel free to reach out. Good luck with your project!

andrewcz commented 9 months ago

Thank you @fdevinc ! I'm going to give it a try this weekend I'm going to use this example - https://github.com/epezent/implot/blob/master/implot_demo.cpp

and the real time plot that uses the following code - // utility structure for realtime plot struct ScrollingBuffer { int MaxSize; int Offset; ImVector Data; ScrollingBuffer(int max_size = 2000) { MaxSize = max_size; Offset = 0; Data.reserve(MaxSize); } void AddPoint(float x, float y) { if (Data.size() < MaxSize) Data.push_back(ImVec2(x,y)); else { Data[Offset] = ImVec2(x,y); Offset = (Offset + 1) % MaxSize; } } void Erase() { if (Data.size() > 0) { Data.shrink(0); Offset = 0; } } };

// utility structure for realtime plot struct RollingBuffer { float Span; ImVector Data; RollingBuffer() { Span = 10.0f; Data.reserve(2000); } void AddPoint(float x, float y) { float xmod = fmodf(x, Span); if (!Data.empty() && xmod < Data.back().x) Data.shrink(0); Data.push_back(ImVec2(xmod, y)); } };

I'm just wondering how would you suggest a time calculation - should i put a flag that states when calculation is finished plot data?