This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Move.h

224 lines
4.8 KiB
C++

/****************************************************************************************************
RepRapFirmware - Move
This is all the code to deal with movement and kinematics.
-----------------------------------------------------------------------------------------------------
Version 0.1
18 November 2012
Adrian Bowyer
RepRap Professional Ltd
http://reprappro.com
Licence: GPL
****************************************************************************************************/
#ifndef MOVE_H
#define MOVE_H
#define BUFFER_LENGTH 10
class DDA
{
public:
DDA(Move* m, Platform* p);
boolean Init(float currentPosition[], float targetPosition[], float& u, float& v);
void Start(boolean noTest);
void Step(boolean noTest);
boolean Active();
boolean VelocitiesAltered();
private:
Move* move;
Platform* platform;
long counter[DRIVES+1];
long delta[DRIVES+1];
boolean directions[DRIVES+1];
long totalSteps;
long stepCount;
float timeStep;
float velocity;
long stopAStep;
long startDStep;
float distance;
float dCross;
float acceleration;
float jerk;
boolean velocitiesAltered;
volatile boolean active;
};
//*********************************************************************************************
/*
To call the RingBuffer functions the sequences are:
Get:
if(ringBuffer->getLock())
{
if(ringBuffer->Empty())
{
ringBuffer->releaseLock();
// Nothing there - go and do something else...
}
d = Get();
ringBuffer->releaseLock();
// Do something with d and don't do another Get until you have finished with d...
}
Add:
if(ringBuffer->getLock())
{
if(ringBuffer->Full())
{
ringBuffer->releaseLock();
// No room - come back later...
}
ringBuffer->Add(...);
ringBuffer->releaseLock();
}
*/
class DDARingBuffer
{
public:
DDARingBuffer(Move* m, Platform* p);
void Add(float currentPosition[], float targetPosition[], float& u, float& v);
DDA* Get();
boolean Empty();
boolean Full();
boolean getLock();
void releaseLock();
private:
Platform* platform;
DDA* ring[RING_LENGTH];
volatile char addPointer;
volatile char getPointer;
volatile boolean locked;
};
//**************************************************************************************************
class Move
{
public:
Move(Platform* p, GCodes* g);
void Init();
void Spin();
void Exit();
void Qmove();
void GetCurrentState(float m[]);
void Interrupt();
friend class DDA;
private:
Platform* platform;
GCodes* gCodes;
DDA* dda;
unsigned long lastTime;
boolean active;
float currentFeedrate;
float currentPosition[AXES]; // Note - drives above AXES are always relative moves
float nextMove[DRIVES + 1]; // Extra is for feedrate
float stepDistances[(1<<AXES)]; // Index bits: lsb -> dx, dy, dz <- msb
float extruderStepDistances[(1<<(DRIVES-AXES))]; // NB - limits us to 5 extruders
};
//********************************************************************************************************
inline boolean DDA::Active()
{
return active;
}
inline boolean DDA::VelocitiesAltered()
{
return velocitiesAltered;
}
//*****************************************************************************************************
inline boolean DDARingBuffer::getLock()
{
if(locked)
return false;
locked = true;
return true;
}
inline void DDARingBuffer::releaseLock()
{
if(!locked)
platform->Message(HOST_MESSAGE, "Attempt to unlock already unlocked ring buffer.\n");
locked = false;
return;
}
inline void DDARingBuffer::Add(float currentPosition[], float targetPosition[], float& u, float& v)
{
if(Full())
{
platform->Message(HOST_MESSAGE, "Attempt to overfill ring buffer.\n");
return;
}
ring[addPointer]->Init(currentPosition, targetPosition, u, v);
addPointer++;
if(addPointer >= RING_LENGTH)
addPointer = 0;
}
inline DDA* DDARingBuffer::Get()
{
if(Empty())
{
platform->Message(HOST_MESSAGE, "Attempt to use empty ring buffer.\n");
return ring[getPointer]; // Safer than NULL
}
DDA* d = ring[getPointer];
getPointer++;
if(getPointer >= RING_LENGTH)
getPointer = 0;
return d;
}
inline boolean DDARingBuffer::Empty()
{
return getPointer == addPointer;
}
// Leave a gap of 2 as the last Get result may still be being processed
inline boolean DDARingBuffer::Full()
{
if(getPointer == 0)
return addPointer == RING_LENGTH - 2;
if(getPointer == 1)
return addPointer == RING_LENGTH - 1;
return addPointer == getPointer - 2;
}
//**********************************************************************************************
inline void Move::Interrupt()
{
dda->Step(true);
}
#endif