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)