Slic3r/xs/src/libslic3r/GCodeTimeEstimator.cpp
Joseph Lenox 89018b6e02
Backwards-compatible Boost 1.73 (#4996)
* Make boost::Placeholders::_1 visible

Fixes https://github.com/slic3r/Slic3r/issues/4967

* Use boost/nowide/cstdlib.hpp instead of boost/nowide/cenv.hpp

* Do not undefine __STRICT_ANSI__

The `__STRICT_ANSI__` macro is defined by the compiler and it's undefined to undefine or redefine it.

Using `-U__STRICT_ANSI__ -std=c++11` is just silly. If you don't want strict mode, don't ask for strict mode. Certainly don't ask for strict mode and then undefined the macro that is defined by strict mode.

The correct solution is `-std=gnu++11` which doesn't define the macro in the first place.

* Help Slic3r::_Log out by adding methods to cover const char* and const wchar_t* (so our tests pass and things don't break when passed string literals).

* calculation of COG in Slic3r (#4970)

Implement center of gravity (COG) calculation and gcode output in Slic3r.

* Comment out cpp travis osx until it's sorted

* Fix misc. typos (#4857)

* Fix misc. typos

Found via `codespell -q 3 -S *.po,./t,./xs/t,./xs/xsp -L ot,uin`

* Follow-up typo fixes

* set progress on deploy script to avoid timeouts

* cpp porting: TransformationMatrix class tests (#4906)

* cpp porting: transformation class testing

* reword some tests

* remove obsolete include

* change equality threshold implementation

* semicolons help in C++

* Stop defining _GLIBCXX_USE_C99 (#4981)

This is an internal macro defined by libstdc++ to record the result of
configure checks done when GCC was built.  Defining (or undefining or
redefining) the macro yourself results in undefined behaviour.

If the system's C library doesn't expose support for C99 or 'long long'
then telling libstdc++ that it does isn't going to work. It will just
mean libstdc++ tries to use features that don't actually exist in the C
library.

In any case, systems that don't support C99 are probably not relevant to
anybody nowadays.

Fixes #4975

* fix-cmake-boost-1-70+ (#4980)

* Use boost/nowide/cstdlib.hpp instead of boost/nowide/cenv.hpp

* Patch build to work on Boost 1.73 and older versions as well.

* Add missing usage of boost::placeholders.

* Add a using for boost versions > 1.73

Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
Co-authored-by: Jonathan Wakely <jwakely@fedoraproject.org>
Co-authored-by: Roman Dvořák <romandvorak@mlab.cz>
Co-authored-by: luzpaz <luzpaz@users.noreply.github.com>
Co-authored-by: Michael Kirsch <mkirsch.git@gmail.com>
2021-03-14 18:45:53 -05:00

83 lines
2.9 KiB
C++

#include "GCodeTimeEstimator.hpp"
#include <cmath>
#include <boost/version.hpp>
#if BOOST_VERSION >= 107300
#include <boost/bind/bind.hpp>
#endif
namespace Slic3r {
#if BOOST_VERSION >= 107300
using boost::placeholders::_1;
using boost::placeholders::_2;
#endif
void
GCodeTimeEstimator::parse(const std::string &gcode)
{
GCodeReader::parse(gcode, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2));
}
void
GCodeTimeEstimator::parse_file(const std::string &file)
{
GCodeReader::parse_file(file, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2));
}
void
GCodeTimeEstimator::_parser(GCodeReader&, const GCodeReader::GCodeLine &line)
{
// std::cout << "[" << this->time << "] " << line.raw << std::endl;
if (line.cmd == "G1") {
const float dist_XY = line.dist_XY();
const float new_F = line.new_F();
if (dist_XY > 0) {
//this->time += dist_XY / new_F * 60;
this->time += _accelerated_move(dist_XY, new_F/60, this->acceleration);
} else {
//this->time += std::abs(line.dist_E()) / new_F * 60;
this->time += _accelerated_move(std::abs(line.dist_E()), new_F/60, this->acceleration);
}
//this->time += std::abs(line.dist_Z()) / new_F * 60;
this->time += _accelerated_move(std::abs(line.dist_Z()), new_F/60, this->acceleration);
} else if (line.cmd == "M204" && line.has('S')) {
this->acceleration = line.get_float('S');
} else if (line.cmd == "G4") { // swell
if (line.has('S')) {
this->time += line.get_float('S');
} else if (line.has('P')) {
this->time += line.get_float('P')/1000;
}
}
}
// Wildly optimistic acceleration "bell" curve modeling.
// Returns an estimate of how long the move with a given accel
// takes in seconds.
// It is assumed that the movement is smooth and uniform.
float
GCodeTimeEstimator::_accelerated_move(double length, double v, double acceleration)
{
// for half of the move, there are 2 zones, where the speed is increasing/decreasing and
// where the speed is constant.
// Since the slowdown is assumed to be uniform, calculate the average velocity for half of the
// expected displacement.
// final velocity v = a*t => a * (dx / 0.5v) => v^2 = 2*a*dx
// v_avg = 0.5v => 2*v_avg = v
// d_x = v_avg*t => t = d_x / v_avg
acceleration = (acceleration == 0.0 ? 4000.0 : acceleration); // Set a default accel to use for print time in case it's 0 somehow.
auto half_length = length / 2.0;
auto t_init = v / acceleration; // time to final velocity
auto dx_init = (0.5*v*t_init); // Initial displacement for the time to get to final velocity
auto t = 0.0;
if (half_length >= dx_init) {
half_length -= (0.5*v*t_init);
t += t_init;
}
t += (half_length / v); // constant speed for rest of the time and too short displacements
return 2.0*t; // cut in half before, so double to get full time spent.
}
}