From 503c6d117ed8aca2e8ce907caa6b7c9fe38f9261 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Sun, 10 Nov 2024 02:28:08 +0100 Subject: [PATCH] Add basic consumption estimator CURA-12250 --- CMakeLists.txt | 3 +- include/communication/ArcusCommunication.h | 2 + include/communication/CommandLine.h | 2 + include/communication/Communication.h | 5 +- include/path_export/CommunicationExporter.h | 1 + include/path_export/ConsoleExporter.h | 1 + .../ConsumptionEstimationExporter.h | 52 +++++++++++ include/path_export/GCodeExporter.h | 3 +- include/path_export/MultiExporter.h | 1 + include/path_export/PathExporter.h | 1 + src/FffGcodeWriter.cpp | 5 + src/communication/ArcusCommunication.cpp | 33 ++++++- src/communication/CommandLine.cpp | 4 + src/path_export/CommunicationExporter.cpp | 1 + src/path_export/ConsoleExporter.cpp | 1 + .../ConsumptionEstimationExporter.cpp | 93 +++++++++++++++++++ src/path_export/GCodeExporter.cpp | 1 + src/path_export/MultiExporter.cpp | 3 +- src/path_planning/ExtrusionMove.cpp | 6 +- .../FeatureExtrusionsOrderOptimizer.cpp | 2 +- 20 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 include/path_export/ConsumptionEstimationExporter.h create mode 100644 src/path_export/ConsumptionEstimationExporter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c96be4a13..271bae8b54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,11 +109,12 @@ set(engine_SRCS # Except main.cpp. src/infill/SubDivCube.cpp src/infill/GyroidInfill.cpp + src/path_export/CommunicationExporter.cpp include/path_export/CommunicationExporter.h src/path_export/ConsoleExporter.cpp include/path_export/ConsoleExporter.h + src/path_export/ConsumptionEstimationExporter.cpp include/path_export/ConsumptionEstimationExporter.h src/path_export/GCodeExporter.cpp include/path_export/GCodeExporter.h src/path_export/MultiExporter.cpp include/path_export/MultiExporter.h src/path_export/PathExporter.cpp include/path_export/PathExporter.h - src/path_export/CommunicationExporter.cpp include/path_export/CommunicationExporter.h src/path_planning/Comb.cpp include/path_planning/Comb.h src/path_planning/ExtruderMove.cpp include/path_planning/ExtruderMove.h diff --git a/include/communication/ArcusCommunication.h b/include/communication/ArcusCommunication.h index 913c38418f..387660d681 100644 --- a/include/communication/ArcusCommunication.h +++ b/include/communication/ArcusCommunication.h @@ -148,6 +148,8 @@ class ArcusCommunication : public Communication */ void sendPrintTimeMaterialEstimates() const override; + void sendPrintTimeMaterialEstimates(const std::shared_ptr& exporter) const override; + /* * \brief Communicate to Arcus what our progress is. */ diff --git a/include/communication/CommandLine.h b/include/communication/CommandLine.h index 395151d331..68a85262f7 100644 --- a/include/communication/CommandLine.h +++ b/include/communication/CommandLine.h @@ -115,6 +115,8 @@ class CommandLine : public Communication */ void sendPrintTimeMaterialEstimates() const override; + void sendPrintTimeMaterialEstimates(const std::shared_ptr& exporter) const override; + /* * \brief Show an update of our slicing progress. */ diff --git a/include/communication/Communication.h b/include/communication/Communication.h index 1a70b15746..ec55f1dfe8 100644 --- a/include/communication/Communication.h +++ b/include/communication/Communication.h @@ -6,7 +6,6 @@ #include "geometry/Point2LL.h" #include "settings/types/LayerIndex.h" -#include "settings/types/Velocity.h" namespace cura { @@ -15,6 +14,8 @@ enum class PrintFeatureType : unsigned char; class Shape; class Polygon; class ExtruderTrain; +class ConsumptionEstimationExporter; +class Velocity; /* * An abstract class to provide a common interface for all methods of @@ -115,6 +116,8 @@ class Communication */ virtual void sendPrintTimeMaterialEstimates() const = 0; + virtual void sendPrintTimeMaterialEstimates(const std::shared_ptr& exporter) const = 0; + /* * \brief Indicate that we're beginning to send g-code. */ diff --git a/include/path_export/CommunicationExporter.h b/include/path_export/CommunicationExporter.h index 8f143aa918..92949b7587 100644 --- a/include/path_export/CommunicationExporter.h +++ b/include/path_export/CommunicationExporter.h @@ -21,6 +21,7 @@ class CommunicationExporter : public PathExporter virtual void writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, const double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, diff --git a/include/path_export/ConsoleExporter.h b/include/path_export/ConsoleExporter.h index 641e00b026..159597c53b 100644 --- a/include/path_export/ConsoleExporter.h +++ b/include/path_export/ConsoleExporter.h @@ -15,6 +15,7 @@ class ConsoleExporter : public PathExporter virtual void writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, const double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, diff --git a/include/path_export/ConsumptionEstimationExporter.h b/include/path_export/ConsumptionEstimationExporter.h new file mode 100644 index 0000000000..747887fd4f --- /dev/null +++ b/include/path_export/ConsumptionEstimationExporter.h @@ -0,0 +1,52 @@ +// Copyright (c) 2024 UltiMaker +// CuraEngine is released under the terms of the AGPLv3 or higher + +#ifndef PATHEXPORTER_CONSUMPTIONESTIMATIONEXPORTER_H +#define PATHEXPORTER_CONSUMPTIONESTIMATIONEXPORTER_H + +#include +#include + +#include "path_export/PathExporter.h" +#include "settings/types/Duration.h" + +namespace cura +{ + +class ConsumptionEstimationExporter : public PathExporter +{ +public: + const std::map& getDurations() const; + + const std::map& getExtrusionAmounts() const; + + void writeExtrusion( + const Point3LL& p, + const Velocity& speed, + const size_t extruder_nr, + const double extrusion_mm3_per_mm, + const coord_t line_width, + const coord_t line_thickness, + const PrintFeatureType feature, + const bool update_extrusion_offset) override; + + void writeTravelMove(const Point3LL& position, const Velocity& speed, const PrintFeatureType feature) override; + + void writeLayerEnd(const LayerIndex& layer_index, const coord_t z, const coord_t layer_thickness) override; + + void writeLayerStart(const LayerIndex& layer_index, const Point3LL& start_position) override; + +private: + std::optional getDistanceToLastPosition(const Point3LL& p) const; + + void addDuration(const std::optional& distance, const Velocity& speed, PrintFeatureType feature); + +private: + std::map durations_; + std::map extrusions_amounts_; + std::optional last_position_; +}; + +} // namespace cura + +#endif // PATHEXPORTER_CONSUMPTIONESTIMATIONEXPORTER_H diff --git a/include/path_export/GCodeExporter.h b/include/path_export/GCodeExporter.h index dcb69a0593..16c5546639 100644 --- a/include/path_export/GCodeExporter.h +++ b/include/path_export/GCodeExporter.h @@ -387,6 +387,7 @@ class GCodeExporter : public NoCopy, public PathExporter virtual void writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, @@ -401,7 +402,7 @@ class GCodeExporter : public NoCopy, public PathExporter void writeExtrusion(const Point3LL& p, const Velocity& speed, double extrusion_mm3_per_mm, PrintFeatureType feature, bool update_extrusion_offset = false) { - return writeExtrusion(p, speed, extrusion_mm3_per_mm, 0, 0, feature, update_extrusion_offset); + return writeExtrusion(p, speed, current_extruder_, extrusion_mm3_per_mm, 0, 0, feature, update_extrusion_offset); } /*! diff --git a/include/path_export/MultiExporter.h b/include/path_export/MultiExporter.h index 7e04a3883a..e5533a2eb0 100644 --- a/include/path_export/MultiExporter.h +++ b/include/path_export/MultiExporter.h @@ -20,6 +20,7 @@ class MultiExporter : public PathExporter virtual void writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, const double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, diff --git a/include/path_export/PathExporter.h b/include/path_export/PathExporter.h index b498461a8a..eef5598989 100644 --- a/include/path_export/PathExporter.h +++ b/include/path_export/PathExporter.h @@ -23,6 +23,7 @@ class PathExporter virtual void writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, const double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 01dbacbb7c..684286b21d 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -31,6 +31,7 @@ #include "infill.h" #include "path_export/CommunicationExporter.h" #include "path_export/ConsoleExporter.h" +#include "path_export/ConsumptionEstimationExporter.h" #include "path_export/MultiExporter.h" #include "path_planning/LayerPlan.h" #include "progress/Progress.h" @@ -168,6 +169,8 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep MultiExporter exporter; exporter.appendExporter(std::make_shared()); exporter.appendExporter(std::make_shared(Application::getInstance().communication_)); + auto consumption_estimator = std::make_shared(); + exporter.appendExporter(consumption_estimator); int process_layer_starting_layer_nr = 0; const bool has_raft = scene.current_mesh_group->settings.get("adhesion_type") == EPlatformAdhesion::RAFT; @@ -210,6 +213,8 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep constexpr bool force = true; gcode.writeRetraction(storage.retraction_wipe_config_per_extruder[gcode.getExtruderNr()].retraction_config, force); // retract after finishing each meshgroup + + Application::getInstance().communication_->sendPrintTimeMaterialEstimates(consumption_estimator); } unsigned int FffGcodeWriter::findSpiralizedLayerSeamVertexIndex(const SliceDataStorage& storage, const SliceMeshStorage& mesh, const int layer_nr, const int last_layer_nr) diff --git a/src/communication/ArcusCommunication.cpp b/src/communication/ArcusCommunication.cpp index 01030f9aca..0b8dd45a6f 100644 --- a/src/communication/ArcusCommunication.cpp +++ b/src/communication/ArcusCommunication.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher +#include "path_export/ConsumptionEstimationExporter.h" #ifdef ARCUS #include "communication/ArcusCommunication.h" @@ -438,6 +439,36 @@ void ArcusCommunication::sendPrintTimeMaterialEstimates() const spdlog::debug("Done sending print time and material estimates."); } +void ArcusCommunication::sendPrintTimeMaterialEstimates(const std::shared_ptr& exporter) const +{ + spdlog::debug("Sending print time and material estimates."); + std::shared_ptr message = std::make_shared(); + + std::map time_estimates = exporter->getDurations(); + message->set_time_infill(time_estimates[PrintFeatureType::Infill]); + message->set_time_inset_0(time_estimates[PrintFeatureType::OuterWall]); + message->set_time_inset_x(time_estimates[PrintFeatureType::InnerWall]); + message->set_time_none(time_estimates[PrintFeatureType::NoneType]); + message->set_time_retract(time_estimates[PrintFeatureType::MoveRetraction]); + message->set_time_skin(time_estimates[PrintFeatureType::Skin]); + message->set_time_skirt(time_estimates[PrintFeatureType::SkirtBrim]); + message->set_time_support(time_estimates[PrintFeatureType::Support]); + message->set_time_support_infill(time_estimates[PrintFeatureType::SupportInfill]); + message->set_time_support_interface(time_estimates[PrintFeatureType::SupportInterface]); + message->set_time_travel(time_estimates[PrintFeatureType::MoveCombing]); + message->set_time_prime_tower(time_estimates[PrintFeatureType::PrimeTower]); + + for (const auto& [extruder_nr, amount] : exporter->getExtrusionAmounts()) + { + proto::MaterialEstimates* material_message = message->add_materialestimates(); + material_message->set_id(extruder_nr); + material_message->set_material_amount(amount); + } + + private_data->socket->sendMessage(message); + spdlog::debug("Done sending print time and material estimates."); +} + void ArcusCommunication::sendProgress(double progress) const { const int rounded_amount = 1000 * progress; @@ -540,7 +571,7 @@ void ArcusCommunication::sliceNext() slice->compute(); FffProcessor::getInstance()->finalize(); flushGCode(); - sendPrintTimeMaterialEstimates(); + // sendPrintTimeMaterialEstimates(); sendFinishedSlicing(); slice.reset(); private_data->slice_count++; diff --git a/src/communication/CommandLine.cpp b/src/communication/CommandLine.cpp index da4bef97e5..d9694cf1f4 100644 --- a/src/communication/CommandLine.cpp +++ b/src/communication/CommandLine.cpp @@ -107,6 +107,10 @@ void CommandLine::sendPrintTimeMaterialEstimates() const } } +void CommandLine::sendPrintTimeMaterialEstimates(const std::shared_ptr& exporter) const +{ +} + void CommandLine::sendProgress(double progress) const { const unsigned int rounded_amount = 100 * progress; diff --git a/src/path_export/CommunicationExporter.cpp b/src/path_export/CommunicationExporter.cpp index 676b9f7c81..44298500f4 100644 --- a/src/path_export/CommunicationExporter.cpp +++ b/src/path_export/CommunicationExporter.cpp @@ -16,6 +16,7 @@ CommunicationExporter::CommunicationExporter(const std::shared_ptr + +namespace cura +{ + +const std::map& ConsumptionEstimationExporter::getDurations() const +{ + return durations_; +} + +const std::map& ConsumptionEstimationExporter::getExtrusionAmounts() const +{ + return extrusions_amounts_; +} + +void ConsumptionEstimationExporter::writeExtrusion( + const Point3LL& p, + const Velocity& speed, + const size_t extruder_nr, + const double extrusion_mm3_per_mm, + const coord_t /*line_width*/, + const coord_t /*line_thickness*/, + const PrintFeatureType feature, + const bool /*update_extrusion_offset*/) +{ + std::optional distance = getDistanceToLastPosition(p); + addDuration(distance, speed, feature); + + if (distance.has_value()) [[likely]] + { + double extrusion_amount = distance.value() * extrusion_mm3_per_mm; + + if (auto iterator = extrusions_amounts_.find(extruder_nr); iterator != extrusions_amounts_.end()) [[likely]] + { + iterator->second += extrusion_amount; + } + else + { + extrusions_amounts_.insert({ extruder_nr, extrusion_amount }); + } + } + + last_position_ = p; +} + +void ConsumptionEstimationExporter::writeTravelMove(const Point3LL& position, const Velocity& speed, const PrintFeatureType feature) +{ + std::optional distance = getDistanceToLastPosition(position); + addDuration(distance, speed, feature); + + last_position_ = position; +} + +void ConsumptionEstimationExporter::writeLayerEnd(const LayerIndex& /*layer_index*/, const coord_t /*z*/, const coord_t /*layer_thickness*/) +{ +} + +void ConsumptionEstimationExporter::writeLayerStart(const LayerIndex& /*layer_index*/, const Point3LL& /*start_position*/) +{ +} +std::optional ConsumptionEstimationExporter::getDistanceToLastPosition(const Point3LL& p) const +{ + if (last_position_.has_value()) [[likely]] + { + return (p - last_position_.value()).vSizeMM(); + } + + return std::nullopt; +} + +void ConsumptionEstimationExporter::addDuration(const std::optional& distance, const Velocity& speed, PrintFeatureType feature) +{ + if (distance.has_value()) [[likely]] + { + const Duration duration = distance.value() / speed; + + if (auto iterator = durations_.find(feature); iterator != durations_.end()) + { + iterator->second += duration; + } + else + { + durations_.insert({ feature, duration }); + } + } +} + +} // namespace cura \ No newline at end of file diff --git a/src/path_export/GCodeExporter.cpp b/src/path_export/GCodeExporter.cpp index b86887571d..35128800c5 100644 --- a/src/path_export/GCodeExporter.cpp +++ b/src/path_export/GCodeExporter.cpp @@ -892,6 +892,7 @@ void GCodeExporter::writeTravel(const Point3LL& p, const Velocity& speed) void GCodeExporter::writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, diff --git a/src/path_export/MultiExporter.cpp b/src/path_export/MultiExporter.cpp index a3e6e08e58..215c26a38a 100644 --- a/src/path_export/MultiExporter.cpp +++ b/src/path_export/MultiExporter.cpp @@ -9,6 +9,7 @@ namespace cura void MultiExporter::writeExtrusion( const Point3LL& p, const Velocity& speed, + const size_t extruder_nr, const double extrusion_mm3_per_mm, const coord_t line_width, const coord_t line_thickness, @@ -17,7 +18,7 @@ void MultiExporter::writeExtrusion( { for (const std::shared_ptr& exporter : exporters_) { - exporter->writeExtrusion(p, speed, extrusion_mm3_per_mm, line_width, line_thickness, feature, update_extrusion_offset); + exporter->writeExtrusion(p, speed, extruder_nr, extrusion_mm3_per_mm, line_width, line_thickness, feature, update_extrusion_offset); } } diff --git a/src/path_planning/ExtrusionMove.cpp b/src/path_planning/ExtrusionMove.cpp index 04eeb01fad..234e1d8296 100644 --- a/src/path_planning/ExtrusionMove.cpp +++ b/src/path_planning/ExtrusionMove.cpp @@ -24,20 +24,22 @@ void ExtrusionMove::write(PathExporter& exporter, const std::vector(parents); const auto* feature_extrusion = findParent(parents); const auto* layer_plan = findParent(parents); + const auto* extruder_plan = findParent(parents); - if (! feature_extrusion || ! layer_plan || ! extruder_move_sequence) + if (! feature_extrusion || ! layer_plan || ! extruder_move_sequence || ! extruder_plan) { return; } const Point3LL position = layer_plan->getAbsolutePosition(*extruder_move_sequence, getPosition()); const Velocity velocity = feature_extrusion->getSpeed() * extruder_move_sequence->getSpeedFactor() * extruder_move_sequence->getSpeedBackPressureFactor(); + const size_t extruder_nr = extruder_plan->extruder_nr_; const double extrusion_mm3_per_mm = feature_extrusion->getExtrusionMM3perMM(); const coord_t line_width = std::llrint(feature_extrusion->getLineWidth() * static_cast(line_width_ratio_)); const coord_t line_thickness = feature_extrusion->getLayerThickness() + extruder_move_sequence->getZOffset() + getPosition().z_; const PrintFeatureType print_feature_type = feature_extrusion->getPrintFeatureType(); - exporter.writeExtrusion(position, velocity, extrusion_mm3_per_mm, line_width, line_thickness, print_feature_type, false); + exporter.writeExtrusion(position, velocity, extruder_nr, extrusion_mm3_per_mm, line_width, line_thickness, print_feature_type, false); } } // namespace cura diff --git a/src/path_processing/FeatureExtrusionsOrderOptimizer.cpp b/src/path_processing/FeatureExtrusionsOrderOptimizer.cpp index 6a1c14671e..4703809a8f 100644 --- a/src/path_processing/FeatureExtrusionsOrderOptimizer.cpp +++ b/src/path_processing/FeatureExtrusionsOrderOptimizer.cpp @@ -41,7 +41,7 @@ void FeatureExtrusionsOrderOptimizer::process(ExtruderPlan* extruder_plan) feature_extrusions.erase(feature_extrusions.begin(), iterator_end); } - // For now, just add the others while just optimizing their sequences +#warning finish this for (const std::shared_ptr& operation : feature_extrusions) { optimizeExtruderSequencesOrder(operation, current_position);