// © RiceMotion ( Robert Carl Rice ) 2012-2016 - All rights reserved


// This software makes use of tools and libraries obtained from open source projects or released for

// use by relevant hardware manufactures. However, this software is NOT a part of any open source project.

// It is released only on a "need to know" basis for beta testers of the "RiceCNC Interpolation Engine".

// Recipents of this source code must respect the confidential nature of this software and prevent any

// distribution that could result in counterfeit copies of the "RiceCNC Interpolation Engine".


// © RiceMotion ( Robert Carl Rice ) 2012-2016 - All rights reserved

#include <MachineSplineCommand.h>

#include <Machine.h>

#include <MachineCommands.h>

#include <SysTick.h>

#include <MainCommands.h>

#include "InterpolationTimer.h"


const char MachineSpline::myName[] =

     "MachineSpline";


const char*

     MachineSpline::name() {


     return

          myName; };


MachineSpline::MachineSpline(

     char*               data,

     Axis*               firstMachineAxis,

     String*               msgPtr ) {


     stepControl.number     = 0;

     uint32_t length          = 0;

     sscanf( data,

          "%lu%ln",

          &stepControl.number,

          &length );

     data                    += length;


     firstMachineSplineAxis     = NULL;

     char   coordinate[20];


     while( sscanf( data,

               " %s%ln",

               &coordinate,

               &length ) > 0 ) { // returns -1 at eof


          MachineSplineAxis* splineAxisPtr     = new MachineSplineAxis(

               coordinate,

               firstMachineAxis,

               msgPtr );

    

          if ( splineAxisPtr->valid() ) {

               splineAxisPtr->nextSplineAxis   = firstMachineSplineAxis;

               firstMachineSplineAxis          = splineAxisPtr; }


          else

               delete splineAxisPtr;


          data                    += length; };


     aborting                    = false;


     stepControl.t                         = 0.0;

     stepControl.status                    = ' ';

     stepControl.progress.minimum     = 0;

     stepControl.progress.maximum     = 0;


     nextCommand                    = NULL; };


MachineSpline::~MachineSpline() {

     while ( firstMachineSplineAxis ) {

        MachineSplineAxis* splineAxisPtr     = firstMachineSplineAxis;

        firstMachineSplineAxis                    = splineAxisPtr->nextSplineAxis;

        delete splineAxisPtr; }; };


void

     MachineSpline::trackPadJogAbort(

          Machine* machine ) {


     aborting     = true; };



bool // This method performs machine position linear interpolation

     MachineSpline::execute(

          Machine* machine ) {


     if ( aborting )

          return

               true;


     // The target changes only for the axes included in the interpolation

     machine->adjustStepSize( &stepControl );

     calculateTarget();     // Calucalte the target machine position for interpolated axes


     return

          stepControl.t == 1.0; };


void

     MachineSpline::report(

          Machine*     machine,

          String*          msgPtr ) {


     machine->reportSplineCompleted( &stepControl, msgPtr );

     *msgPtr

          += "\n"; };



void

     MachineSpline::reportInterpolationStatus(

          Machine*     machine,

          String*          msgPtr ) {


     machine->reportInterpolationStatus( &stepControl, msgPtr ); };


void

     MachineSpline::calculateTarget() { // return interpolation speed acceleration


     if ( stepControl.t > 1.0 )

          stepControl.t = 1.0;

     // Calculate a target position for each axis

     MachineSplineAxis* splineAxisPtr  = firstMachineSplineAxis;

     while ( splineAxisPtr ) {

          splineAxisPtr->calculateTarget( stepControl.t );

          splineAxisPtr   = splineAxisPtr->nextSplineAxis; }; };