mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00

* Adaptive Pressure advance options setup * Dynamic PA - PCHIP interpolator code and tests * Integrate dynamic PA with slicing code - emit new PA values per speed change * Link adaptive PA to role change instead of speed change * Adaptive PA - Alpha 2 Reduce the frequency of requested PA changes by introducing a "state" variable. Implement user toggle for adapting PA for external walls for overhangs * Hide adaptive PA for overhangs * Convert Adaptive PA to use volumetric flow model and start preparing for converting to Gcode post processor * Converted Dynamic PA to a post processing filter. Reverted changes in GCode cpp and created tagging mechanism to allow filter to apply PA changes. * Removed adaptive PA for overhangs * Foundations for two dimensional adaptive PA based on acceleration and volumetric flow speed * Minor code cleanup and updating of tooltips * Renaming files for better clarity and generate classes documentation * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Update src/libslic3r/PrintConfig.cpp Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com> * Introduce average mm3_mm over the length of a multipath for adaptive PA * Updates for multipath handling part 2 * Introduce average mm3_mm over the length of a multipath for adaptive PA * Trigger PA evaluation more frequently to catch edge cases where speed changes across islands of the same feature type. * Updates for multipath handling part 2 * Adaptive PA: Implement average flow estimation on loops * Code formatting * Fix adaptive PA not adapting for small disconnected external wall line segments. * Updated to take max print speed of upcoming feature to calculate new PA value. This is to resolve issue of incorrect PA value used when starting a new feature at an overhang. * Code clean up * Performance tuning * Further performance tuning by reducing use of regex commands in the nested loops and fix bug preventing gcode line output * Further performance tuning and tweaks to stop searching for max speed after the first travel move. * Reduce debug information * Updated debug info * Fix an issue on seams on specific models when wipe before external perimeter was enabled. Also cleanup documentation and add new to-do's * Prepare for adaptive PA for overhangs, fix wipe bug & clean up code and comments * Initial commit for adapting PA when extruding fully overhanging perimeters * Ignore wipe command when identifying current print speed * Option to evaluate adaptive PA on overhang regions in preparation for Klipper experimental option testing * Update to issue PA changes for varying flow conditions within the same feature * Fix bug where adaptive PA was enabled erroneously for role changes and ignoring user's preference. * Refactored some code * More refactoring * Some bug fixes and enabled comments only when verbose g-code is enabled * Introduced dedicated PA option for bridges * Code refactoring to optimise initialisation of PA processor (making it faster). Fix a bug where PA was not always set after a toolchange. Improve general error handling and robustness. * Updates to adaptive PA tooltips * Bridging PA check with Epsilon instead of 0. * Adaptive PA: addressing comments --------- Co-authored-by: ElectricalBoy <15651807+ElectricalBoy@users.noreply.github.com>
114 lines
4.2 KiB
C++
114 lines
4.2 KiB
C++
// AdaptivePAInterpolator.cpp
|
|
// OrcaSlicer
|
|
//
|
|
// Implementation file for the AdaptivePAInterpolator class, providing methods to parse data and perform PA interpolation.
|
|
|
|
#include "AdaptivePAInterpolator.hpp"
|
|
#include <stdexcept>
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
#include <sstream>
|
|
|
|
/**
|
|
* @brief Parses the input data and sets up the interpolators.
|
|
* @param data A string containing the data in CSV format (PA, flow rate, acceleration).
|
|
* @return 0 on success, -1 on error.
|
|
*/
|
|
int AdaptivePAInterpolator::parseAndSetData(const std::string& data) {
|
|
flow_interpolators_.clear();
|
|
accelerations_.clear();
|
|
|
|
try {
|
|
std::istringstream ss(data);
|
|
std::string line;
|
|
std::map<double, std::vector<std::pair<double, double>>> acc_to_flow_pa;
|
|
|
|
while (std::getline(ss, line)) {
|
|
std::istringstream lineStream(line);
|
|
std::string value;
|
|
double paValue, flowRate, acceleration;
|
|
paValue = flowRate = acceleration = 0.f; // initialize all to zero.
|
|
|
|
// Parse PA value
|
|
if (std::getline(lineStream, value, ',')) {
|
|
paValue = std::stod(value);
|
|
}
|
|
|
|
// Parse flow rate value
|
|
if (std::getline(lineStream, value, ',')) {
|
|
flowRate = std::stod(value);
|
|
}
|
|
|
|
// Parse acceleration value
|
|
if (std::getline(lineStream, value, ',')) {
|
|
acceleration = std::stod(value);
|
|
}
|
|
|
|
// Store the parsed values in a map with acceleration as the key
|
|
acc_to_flow_pa[acceleration].emplace_back(flowRate, paValue);
|
|
}
|
|
|
|
// Iterate through the map to set up the interpolators
|
|
for (const auto& kv : acc_to_flow_pa) {
|
|
double acceleration = kv.first;
|
|
const auto& data = kv.second;
|
|
|
|
std::vector<double> flowRates;
|
|
std::vector<double> paValues;
|
|
|
|
for (const auto& pair : data) {
|
|
flowRates.push_back(pair.first);
|
|
paValues.push_back(pair.second);
|
|
}
|
|
|
|
// Only set up the interpolator if there are enough data points
|
|
if (flowRates.size() > 1) {
|
|
PchipInterpolatorHelper interpolator(flowRates, paValues);
|
|
flow_interpolators_[acceleration] = interpolator;
|
|
accelerations_.push_back(acceleration);
|
|
}
|
|
}
|
|
} catch (const std::exception&) {
|
|
m_isInitialised = false;
|
|
return -1; // Error: Exception during parsing
|
|
}
|
|
m_isInitialised = true;
|
|
return 0; // Success
|
|
}
|
|
|
|
/**
|
|
* @brief Interpolates the PA value for the given flow rate and acceleration.
|
|
* @param flow_rate The flow rate at which to interpolate.
|
|
* @param acceleration The acceleration at which to interpolate.
|
|
* @return The interpolated PA value, or -1 if interpolation fails.
|
|
*/
|
|
double AdaptivePAInterpolator::operator()(double flow_rate, double acceleration) {
|
|
std::vector<double> pa_values;
|
|
std::vector<double> acc_values;
|
|
|
|
// Estimate PA value for every flow to PA model for the given flow rate
|
|
for (const auto& kv : flow_interpolators_) {
|
|
double pa_value = kv.second.interpolate(flow_rate);
|
|
|
|
// Check if the interpolated PA value is valid
|
|
if (pa_value != -1) {
|
|
pa_values.push_back(pa_value);
|
|
acc_values.push_back(kv.first);
|
|
}
|
|
}
|
|
|
|
// Check if there are enough acceleration values for interpolation
|
|
if (acc_values.size() < 2) {
|
|
// Special case: Only one acceleration value
|
|
if (acc_values.size() == 1) {
|
|
return std::round(pa_values[0] * 1000.0) / 1000.0; // Rounded to 3 decimal places
|
|
}
|
|
return -1; // Error: Not enough data points for interpolation
|
|
}
|
|
|
|
// Create a new PchipInterpolatorHelper for PA-acceleration interpolation
|
|
// Use the estimated PA values from the for loop above and their corresponding accelerations to
|
|
// generate the new PCHIP model. Then run this model to interpolate the PA value for the given acceleration value.
|
|
PchipInterpolatorHelper pa_accel_interpolator(acc_values, pa_values);
|
|
return std::round(pa_accel_interpolator.interpolate(acceleration) * 1000.0) / 1000.0; // Rounded to 3 decimal places
|
|
}
|