From 62e9027911ea0c89a55b0408fe2e19a02907f497 Mon Sep 17 00:00:00 2001 From: Inex Code Date: Tue, 13 Apr 2021 16:07:55 +0000 Subject: [PATCH] REST API --- UML1/Makefile | 10 +- UML1/superpoohREST.cpp | 371 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 376 insertions(+), 5 deletions(-) create mode 100644 UML1/superpoohREST.cpp diff --git a/UML1/Makefile b/UML1/Makefile index 9f9a598..02847b2 100644 --- a/UML1/Makefile +++ b/UML1/Makefile @@ -1,9 +1,9 @@ CXX = g++ CXXFLAGS = -Wall -g --std=c++11 -main: superpoohMQTT.o - $(CXX) -o main superpoohMQTT.o -lpthread -lmosquittopp -lmosquitto -lboost_system +main: superpoohREST.o + $(CXX) -o main superpoohREST.o -lpthread -lboost_system -lcrypto -lssl -lcpprest -superpoohMQTT.o: superpoohMQTT.cpp - clang-format -i --style=webkit superpoohMQTT.cpp - $(CXX) $(CXXFLAGS) -c superpoohMQTT.cpp +superpoohMQTT.o: superpoohREST.cpp + clang-format -i --style=webkit superpoohREST.cpp + $(CXX) $(CXXFLAGS) -c superpoohREST.cpp diff --git a/UML1/superpoohREST.cpp b/UML1/superpoohREST.cpp new file mode 100644 index 0000000..2b64460 --- /dev/null +++ b/UML1/superpoohREST.cpp @@ -0,0 +1,371 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace utility; // Common utilities like string conversions +using namespace web; // Common features like URIs. +using namespace web::http; // Common HTTP functionality +using namespace web::http::experimental::listener; // HTTP listener +using namespace concurrency::streams; // Asynchronous streams + +using namespace std; + +class PIDImpl { +public: + // Kp - proportional gain + // Ki - Integral gain + // Kd - derivative gain + // dt - loop interval time + // max - maximum value of manipulated variable + // min - minimum value of manipulated variable + PIDImpl(double dt, double max, double min, double Kp, double Kd, double Ki); + ~PIDImpl(); + // Returns the manipulated variable given a setpoint and current process value + double calculate(double setpoint, double pv); + +private: + double _dt; + double _max; + double _min; + double _Kp; + double _Kd; + double _Ki; + double _pre_error; + double _integral; +}; + +/** +* Implementation +*/ +PIDImpl::PIDImpl(double dt, double max, double min, double Kp, double Kd, double Ki) + : _dt(dt) + , _max(max) + , _min(min) + , _Kp(Kp) + , _Kd(Kd) + , _Ki(Ki) + , _pre_error(0) + , _integral(0) +{ +} + +double PIDImpl::calculate(double setpoint, double pv) +{ + + // Calculate error + double error = setpoint - pv; + + // Proportional term + double Pout = _Kp * error; + + // Integral term + _integral += error * _dt; + double Iout = _Ki * _integral; + + // Derivative term + double derivative = (error - _pre_error) / _dt; + double Dout = _Kd * derivative; + + // Calculate total output + double output = Pout + Iout + Dout; + + //std::cout<<"out="< _max) + output = _max; + else if (output < _min) + output = _min; + + //std::cout << "outB=" << output << std::endl; + + // Save error to previous error + _pre_error = error; + + return output; +} + +PIDImpl::~PIDImpl() +{ +} + +enum ECmd { + ENone, + EExit +}; + +ECmd cmd = ENone; + +int counter = 0; + +std::mutex mtx; + +float targetH = 10.; + +float getHZadFromUser() +{ + return 10.; +} + +class Bear { + float h; + float m; + float v; + float a; + +public: + Bear() + { + v = 0; // m/s + a = 0; // m/s2 + m = 10; // kg + h = 0; // Текущая высота + } + float getH() + { + return h; + } + float getV() + { + return v; + } + float getM() + { + return m; + } + float getA() + { + return a; + } + virtual void calc(float dt, float extrnForce) + { + float dh; + v = v + a * dt; + dh = v * dt; + h = h + dh; + a = (extrnForce - 9.8 * m) / m; // m * a = mg - F + + if (h < 0) { // Stay on the ground + h = 0.; + v = 0.; + a = 0.; + } + } + + void eat(float mass) + { + m = m + mass; + } + + virtual void show() + { + std::cout << "h=" << h << std::endl; + } +}; + +class Engine; + +class Engine { + float enginePower = 0; // n 0..500 n + float maxPower; // n +public: + Engine(float imaxPower) + { + enginePower = 0.; + maxPower = imaxPower; + } + + void setPower(float enginePowerPercent) + { + if (enginePowerPercent > 100.) + enginePowerPercent = 100; + if (enginePowerPercent < -100.) + enginePowerPercent = -100; + + enginePower = enginePowerPercent * (maxPower / 100.); + } + + float getForce() + { + return enginePower; + } +}; + +class SmartFlyingBear : public Bear { + PIDImpl* pid; + Engine* pengine; + float hZad; + +public: + SmartFlyingBear(PIDImpl* ppid, Engine* ppengine) + { + pid = ppid; + pengine = ppengine; + hZad = 0; + } + + void setHZad(float val) + { + hZad = val; + } + + virtual void calc(float dt, float extrnForce) + { + float enginePowerPercent = 0; + if (pid != nullptr) { + enginePowerPercent = pid->calculate(hZad, getH()); + } + + if (pengine != nullptr) { + pengine->setPower(enginePowerPercent); + Bear::calc(dt, extrnForce + pengine->getForce()); + } + } +}; + +int model() +{ + + //PIDImpl pid(0.1, 100, -100, 0.05, 0.001, 0.1); + //Bear pooh; + SmartFlyingBear superpooh(new PIDImpl(0.1, 100, -100, 0.15, 0.001, 0.01), new Engine(500.)); + + float t = 0; // Время моделирования + float dt = 0.1; // s + float lastT = -5; + + float hZad = 0; // Измененение высоты за шаг моделирования + + while (cmd != EExit) { + mtx.lock(); + hZad = targetH; // Неблокирующая функция для получения высоты + mtx.unlock(); + if (abs(superpooh.getH() - hZad) < 1 && abs(t - lastT) > 5) { + superpooh.eat(0.1); + lastT = t; + } + superpooh.setHZad(hZad); + superpooh.show(); + superpooh.calc(dt, 0); + + t = t + dt; + + if (t < 200) { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } else { + std::cout << "Weight = " << superpooh.getM() << std::endl; + std::cout << "Velocity = " << superpooh.getV() << std::endl; + std::cout << "Acceleration = " << superpooh.getA() << std::endl; + std::cout << "Time = " << t << std::endl; + std::cout << "===========" << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + } + + return 0; +} + +void handle_signal(int s) +{ + cmd = EExit; +} + +/* +void message_callback(struct mosquitto* mosq, void* obj, const struct mosquitto_message* message) +{ + bool match = 0; + printf("got message '%.*s' for topic '%s'\n", message->payloadlen, (char*)message->payload, message->topic); + + mosquitto_topic_matches_sub("/pooh/height", message->topic, &match); + if (match) { + std::cout << "Going up!" << std::endl; + mtx.lock(); + targetH = std::atof((char*)message->payload); + mtx.unlock(); + } + + mosquitto_topic_matches_sub("/pooh/land", message->topic, &match); + if (match) { + std::cout << "Going down!" << std::endl; + mtx.lock(); + targetH = 0.; + mtx.unlock(); + } + + mosquitto_topic_matches_sub("/pooh/quit", message->topic, &match); + if (match) { + std::cout << "Exiting!" << std::endl; + cmd = EExit; + } +}*/ + +void handle_get(http_request message){ + cout<<"Handle get: "<