Advertisement
Trainlover08

Tuner

Jan 23rd, 2025 (edited)
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.54 KB | None | 0 0
  1. // im going to make my prototype of this using very basic gd. In the future, plan on using ADAMW to preform gd for the gains
  2.  
  3. #include <vector>
  4. #include <string>
  5. #include <fstream>
  6. #include <stdexcept>
  7. #include "../pros/rtos.hpp"
  8. #include "../pros/motors.hpp"
  9. #include "../lemlib/pid.hpp"
  10. #include "../lemlib/chassis.hpp"
  11. #include "../lemlib/movement/movement.hpp"
  12.  
  13. struct GradientDescent
  14. {
  15.     double learningRate;
  16.     std::vector<double> gradients;
  17.     std::vector<double> last_losses;
  18.     GradientDescent(double learningRate) : learningRate(learningRate) {}
  19.     void update(std::vector<double> &params, const std::vector<double> &losses) {
  20.         if (gradients.size()!= params.size()) {
  21.             throw std::invalid_argument("Gradients and losses must have the same size");
  22.         }
  23.         while (!gradients.size() == params.size()) {
  24.             gradients.push_back(0.0f);
  25.         }
  26.         while (!last_losses.size() == losses.size()) {
  27.             last_losses.push_back(0.0f);
  28.         }
  29.         for (int k = 0; k < losses.size(); ++k) {
  30.             gradients[k] = last_losses[k] - losses[k];
  31.         }
  32.         last_losses = losses;
  33.         for (int i = 0; i < params.size(); ++i)
  34.         {
  35.             params[i] -= learningRate * gradients[i];
  36.         }
  37.     }
  38. };
  39.  
  40. void write_file(std::vector<double> &gradients, std::vector<double> &params, std::string filename)
  41. {
  42.     // check the validity of the file name
  43.     if (!filename.starts_with("/usd/"))
  44.     {
  45.         throw std::invalid_argument("File name must start with '/usd/'");
  46.     }
  47.     if (!filename.ends_with(".txt"))
  48.     {
  49.         throw std::invalid_argument("File name must end with '.txt'");
  50.     }
  51.     // make sure the vectors have the same size
  52.     if (gradients.size() != params.size())
  53.     {
  54.         throw std::invalid_argument("Gradients and parameters must have the same size");
  55.     }
  56.     // take the mutex
  57.     pros::Mutex mtx;
  58.     mtx.take();
  59.     std::ofstream file(filename);
  60.     // check to makesure the file is open
  61.     if (!file)
  62.     {
  63.         mtx.give();
  64.         throw std::runtime_error("Could not open file for writing");
  65.     }
  66.     // write the gradients and parameters to the file
  67.     for (int i = 0; i < gradients.size(); ++i)
  68.     {
  69.         file << gradients[i] << " " << params[i] << "\n";
  70.     }
  71.     file.close();
  72.     mtx.give();
  73. }
  74.  
  75. std::pair<std::vector<double>, std::vector<double>> read_file(std::string filename)
  76. {
  77.     // check the validity of the file name
  78.     if (!filename.starts_with("/usd/"))
  79.     {
  80.         throw std::invalid_argument("File name must start with '/usd/'");
  81.     }
  82.     if (!filename.ends_with(".txt"))
  83.     {
  84.         throw std::invalid_argument("File name must end with '.txt'");
  85.     }
  86.     std::vector<double> gradients;
  87.     std::vector<double> params;
  88.     std::string line;
  89.     // take the mutex
  90.     pros::Mutex mtx;
  91.     mtx.take();
  92.     std::ifstream file(filename);
  93.     // check to makesure the file is open
  94.     if (!file)
  95.     {
  96.         mtx.give();
  97.         throw std::runtime_error("Could not open file for reading");
  98.     }
  99.     // read the gradients and parameters from the file
  100.     while (std::getline(file, line))
  101.     {
  102.         std::istringstream iss(line);
  103.         double gradient, param;
  104.         if (!(iss >> gradient >> param))
  105.         {
  106.             mtx.give();
  107.             throw std::runtime_error("Invalid format in the file");
  108.         }
  109.         gradients.push_back(gradient);
  110.         params.push_back(param);
  111.     }
  112.     file.close();
  113.     mtx.give();
  114.     return std::make_pair(gradients, params);
  115. }
  116.  
  117. struct PID_Loss {
  118.     double p_loss, i_loss, d_loss, total_loss;
  119. };
  120.  
  121. PID_Loss compute_pid_losses(const std::vector<double>& actual_position, const std::vector<double>& desired_position, const std::vector<double>& control_effort, double dt, double kP, double kI, double kD, double wP, double wI, double wD) {
  122.     double p_loss, i_loss, d_loss = 0.0f;
  123.     double cumulative_error, previous_error = 0.0f;
  124.     for (int i = 0; i < actual_position.size(); ++i) {
  125.         double error = desired_position[i] - actual_position[i];
  126.         cumulative_error += error * dt;
  127.         // squared error for proportional loss
  128.         p_loss = error * error;
  129.         // squared cumulative error for integral loss
  130.         i_loss = cumulative_error * cumulative_error;
  131.         // squared change in error for derivative loss
  132.         if (i > 0) {
  133.             double derivative_loss = (error - previous_error) / dt;    
  134.             d_loss = (error - previous_error) / dt;
  135.         }
  136.         previous_error = error;
  137.     }
  138.     double total_loss = wP * kP * p_loss + wI * kI * i_loss + wD * kD * d_loss;
  139.     p_loss *= wP;
  140.     i_loss *= wI;
  141.     d_loss *= wD;
  142.     return {p_loss, i_loss, d_loss, total_loss};
  143. }
  144.  
  145. namespace FAPID_Tuner {
  146.     void tune_F_start_only (lemlib::Chassis& chassis) {
  147.         chassis.calibrate();
  148.         chassis.setPose(0, 0, 0);
  149.         bool is_in_motion = 0;
  150.         double f_gain = 0.0f;
  151.         lemlib::FAPID pid (0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  152.         while (!is_in_motion) {
  153.             f_gain += 0.1;
  154.             pid.F = f_gain;
  155.             chassis.moveToPoint(0, 48, 5000);
  156.             pros::delay(500);
  157.             // needs finishing
  158.         }
  159.     }
  160.     // need to build a tuner that minimizes the non-feedforward FAPID value. this allows tuning the feedforward at different constant velocities
  161. };
  162. // needs the main implementation of motor input along with LemLib's PID control. Maybe in a new file due to complexity?
  163. // tune the dynamic weights
  164. // check over the methods for comuting gradients
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement