I was so annoyed that the estimates for my 3d printing jobs were so far off
(estimated 2 hours, took 8) that I modified the axis code.  It looks at the
Velocity and acceleration of each axis and tries to calculate a more
accurate time.  It only looks at moves - no G64 or probing.  It isn't
perfect, but much closer.

The attached file is the changes - a new gcode_properties function and some
additional routines.

My version of linuxcnc is pretty old, so a diff or patch wouldn't be useful.

Frank 





> -----Original Message-----
> From: Sebastian Kuzminsky [mailto:s...@highlab.com]
> Sent: Thursday, 9 October 2014 1:45 AM
> To: Enhanced Machine Controller (EMC)
> Subject: Re: [Emc-users] Thoughts on a Python script to calculate
estimated
> run time, for G code and my first hacked sub routine
> 
> On 10/8/14 9:01 AM, Schooner wrote:
> > First Q
> >
> >   From Axis
> >
> > File > Properties
> >
> > Brings up the properties of the currently loaded gcode including
> > estimated run time
> >
> > Always underestimates as it takes no account of time used in
> > acceleration and deceleration to/from the required Feed speed
> 
> Yep, the estimate is off.  It's based on the gcode only, and does not take
into
> account important things like machine acceleration and spindle
acceleration
> as you say, as well as things like tolerance (G64 P) and probing.
> 
> The only way I can think of to improve the estimate would be to run the
> motion controller, disconnected from actual motion, and see how long the
> motion actually takes.  That's probably possible, but it's not a small
change to
> design & implement.
> 
> 
> --
> Sebastian Kuzminsky
> 
>
----------------------------------------------------------------------------
--
> Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer Achieve
> PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports Are you
> Audit-Ready for PCI DSS 3.0 Compliance? Download White paper Comply to
> PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
> http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.cl
> ktrk
> _______________________________________________
> Emc-users mailing list
> Emc-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/emc-users
class AxisParam:
    def __init__(self, vel, acc):
        self.vel = vel
        self.acc = acc

    def StraightExecutionTime( self, distance, feedrate ):

        t = 0.0
        if feedrate is None:
            v = self.vel
        elif feedrate > self.vel:
            v = self.vel
        else:
            v = feedrate

        distance = abs(distance)
        a = self.acc

        if distance > 0:
            # calc time and distance to accelerate to v
            # v = at
            # s = 1/2 a t^2 + v0 t,  assume v0 = 0
            t = v / a
            s =  1.0 / 2.0 * a * t *t

            # check if accelerating to v then decelerating to v fits in the 
distance
            if 2.0*s < distance:
                t = 2.0 * t + (distance - 2.0*s) / v
            else:
                t = 2.0*math.sqrt( 2.0 * (distance/2.0) / a )

        #print "distance=",distance, "a=", a, "v=", v, "t=", t
        return t

def CalcExecutionTime( axis_params, start_point, end_point, feedrate=None ):
    distance = sum( (s-e)**2 for s, e in zip(start_point, end_point))
    distance = math.sqrt(distance)

    longest_time = 0
    for ap,start,end in zip(axis_params, start_point, end_point ):
        if not ap is None:
            f = feedrate
            if not feedrate is None:
                f = feedrate * abs(end-start)/distance
            time = ap.StraightExecutionTime( end - start, f )
            if time > longest_time:
                longest_time = time
    return longest_time

def CalcArcExecutionTime( ap, arcfeed ):
    # Arcs have already been converted into line segments.
    # We calculate absolute distance travelled in dx, dy, dz, etc
    # and estimate the time in each axis.  This wont take into
    # account an axis with low acceleration, but should be close enough.
    time = 0
    last_line = 0
    last_feed = 0
    arclen = [0,]*9
    segcount = 0
    for arcseg in arcfeed:
        # Each record contains, line number, start, end, feedrate.
        # We determine the end of an arc when the line # changes or the feed 
changes
        line = arcseg[0]
        start = arcseg[1]
        end = arcseg[2]
        feed = arcseg[3]
    
        if line != last_line or feed != last_feed:
            if segcount > 0:
                t = CalcExecutionTime( ap, [0,]*9, arclen, last_feed )
                time += t

            arclen = [0,]*9
            segcount = 0

        # sum the distance travelled in each axis
        for i in range(0,9):
            arclen[i] += abs(end[i]-start[i])
        segcount += 1

        last_feed = feed
        last_line = line

    if segcount > 0:
        t = CalcExecutionTime( ap, (0,)*9, arclen, last_feed )
        time += t

    return time

#Replace in class TclCommands(nf.TclCommands):

    def gcode_properties(event=None):
        props = {}
        if not loaded_file:
            props['name'] = _("No file loaded")
        else:
            ext = os.path.splitext(loaded_file)[1]
            program_filter = None
            if ext:
                program_filter = inifile.find("FILTER", ext[1:])
            name = os.path.basename(loaded_file)
            if program_filter:
                props['name'] = _("generated from %s") % name
            else:
                props['name'] = name

            size = os.stat(loaded_file).st_size
            lines = int(widgets.text.index("end").split(".")[0])-2
            props['size'] = _("%(size)s bytes\n%(lines)s gcode lines") % 
{'size': size, 'lines': lines}

            if vars.metric.get():
                conv = 1
                units = _("mm")
                fmt = "%.3f"
            else:
                conv = 1/25.4
                units = _("in")
                fmt = "%.4f"

            # read max_vel and max_acc for each axis
            ap = []
            lscale = 1.0
            for a in range(0,8):
                vel = inifile.find("AXIS_%d"%a, "MAX_VELOCITY")
                acc = inifile.find("AXIS_%d"%a, "MAX_ACCELERATION")

                #print "vel=", vel, " acc=", acc
                if not vel is None and not acc is None:
                    ap.append( AxisParam( float(vel) * lscale,
                                               float(acc) * lscale ) )
                else:
                    ap.append( None )

            g0 = sum(dist(l[1][:3], l[2][:3]) for l in o.canon.traverse)
            g1 = (sum(dist(l[1][:3], l[2][:3]) for l in o.canon.feed) +
                sum(dist(l[1][:3], l[2][:3]) for l in o.canon.arcfeed))
            gt =  sum( CalcExecutionTime( ap, l[1], l[2] ) for l in 
o.canon.traverse)
            gt += sum( CalcExecutionTime( ap, l[1], l[2], l[3] ) for l in 
o.canon.feed)
            gt += CalcArcExecutionTime( ap, o.canon.arcfeed )
            gt += o.canon.dwell_time
 
            props['g0'] = "%f %s".replace("%f", fmt) % 
(from_internal_linear_unit(g0, conv), units)
            props['g1'] = "%f %s".replace("%f", fmt) % 
(from_internal_linear_unit(g1, conv), units)

            h = gt/(60*60)
            m = (gt/60) % 60
            s = gt%60
            props['run'] = "%d:%02d:%02d" % (int(h),int(m),int(s))

            min_extents = from_internal_units(o.canon.min_extents, conv)
            max_extents = from_internal_units(o.canon.max_extents, conv)
            for (i, c) in enumerate("xyz"):
                a = min_extents[i]
                b = max_extents[i]
                if a != b:
                    props[c] = _("%(a)f to %(b)f = %(diff)f 
%(units)s").replace("%f", fmt) % {'a': a, 'b': b, 'diff': b-a, 'units': units}
        properties(root_window, _("G-Code Properties"), property_names, props)
------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
Emc-users mailing list
Emc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to