diff --git a/src/Mod/Path/App/Path.cpp b/src/Mod/Path/App/Path.cpp index c802a61768..e0451ff0a5 100644 --- a/src/Mod/Path/App/Path.cpp +++ b/src/Mod/Path/App/Path.cpp @@ -31,6 +31,7 @@ #include #include #include +#include // KDL stuff - at the moment, not used //#include "Mod/Robot/App/kdl_cp/path_line.hpp" @@ -146,6 +147,67 @@ double Toolpath::getLength() return l; } +double Toolpath::getCycleTime(double hFeed, double vFeed, double hRapid, double vRapid) +{ + // check the feedrates are set + if ((hFeed == 0) || (vFeed == 0)){ + Base::Console().Warning("Feed Rate Error: Check Tool Controllers have Feed Rates"); + return 0; + } + + if (hRapid == 0){ + hRapid = hFeed; + } + + if (vRapid == 0){ + vRapid = vFeed; + } + + if(vpcCommands.size()==0) + return 0; + double l = 0; + double time = 0; + bool verticalMove = false; + Vector3d last(0,0,0); + Vector3d next; + for(std::vector::const_iterator it = vpcCommands.begin();it!=vpcCommands.end();++it) { + std::string name = (*it)->Name; + float feedrate = (*it)->getParam("F"); + + l = 0; + verticalMove = false; + feedrate = hFeed; + next = (*it)->getPlacement(last).getPosition(); + + if (last.z != next.z){ + verticalMove = true; + feedrate = vFeed; + } + + if ((name == "G0") || (name == "G00")){ + // Rapid Move + l += (next - last).Length(); + feedrate = hRapid; + if(verticalMove){ + feedrate = vRapid; + } + }else if ((name == "G1") || (name == "G01")) { + // Feed Move + l += (next - last).Length(); + }else if ((name == "G2") || (name == "G02") || (name == "G3") || (name == "G03") ) { + // Arc Move + Vector3d center = (*it)->getCenter(); + double radius = (last - center).Length(); + double angle = (next - center).GetAngle(last - center); + l += angle * radius; + } + + time += l / feedrate; + last = next; + } + return time; +} + class BoundBoxSegmentVisitor : public PathSegmentVisitor { public: diff --git a/src/Mod/Path/App/Path.h b/src/Mod/Path/App/Path.h index 24e1023312..9ad4381f7b 100644 --- a/src/Mod/Path/App/Path.h +++ b/src/Mod/Path/App/Path.h @@ -60,6 +60,7 @@ namespace Path void insertCommand(const Command &Cmd, int); // inserts a command void deleteCommand(int); // deletes a command double getLength(void); // return the Length (mm) of the Path + double getCycleTime(double, double, double, double); // return the Cycle Time (s) of the Path void recalculate(void); // recalculates the points void setFromGCode(const std::string); // sets the path from the contents of the given GCode string std::string toGCode(void) const; // gets a gcode string representation from the Path diff --git a/src/Mod/Path/App/PathPy.xml b/src/Mod/Path/App/PathPy.xml index 4440ea2379..94a56ec172 100644 --- a/src/Mod/Path/App/PathPy.xml +++ b/src/Mod/Path/App/PathPy.xml @@ -78,6 +78,11 @@ deletes the command found at the given position or from the end of the pathreturns a copy of this path + + + return the cycle time estimation for this path in s + + diff --git a/src/Mod/Path/App/PathPyImp.cpp b/src/Mod/Path/App/PathPyImp.cpp index 20bac63a8f..f61c5568e6 100644 --- a/src/Mod/Path/App/PathPyImp.cpp +++ b/src/Mod/Path/App/PathPyImp.cpp @@ -189,6 +189,14 @@ PyObject* PathPy::deleteCommand(PyObject * args) Py_Error(Base::BaseExceptionFreeCADError, "Wrong parameters - expected an integer (optional)"); } +PyObject* PathPy::getCycleTime(PyObject * args) +{ + double hFeed, vFeed, hRapid, vRapid; + if (PyArg_ParseTuple(args, "dddd", &hFeed, &vFeed, &hRapid, &vRapid)){ + return PyFloat_FromDouble(getToolpathPtr()->getCycleTime(hFeed, vFeed, hRapid, vRapid)); + } +} + // GCode methods PyObject* PathPy::toGCode(PyObject * args)