#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <sys/types.h>
#include <list>
#include <stdint.h>
#include "rcs.hh"
#include "posemath.h"
#include "emc.hh"
#include "emc_nml.hh"
#include "canon.hh"
#include "emcglb.h"
#include "emccfg.h"
#include "inifile.hh"
#include "nml_oi.hh"
#include "rcs_print.hh"
#include "timer.hh"
#include "shcom.hh"
#include "emcsched.hh"
#define MAX_PRIORITY 0x80000000
#define POLYNOMIAL 0xD8
#define WIDTH (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
typedef uint32_t crc;
crc crcTable[256];
crc crcResult;
int autoTagId = 0;
queueStatusType queueStatus = qsStop;
class SchedEntry {
int priority;
int tagId;
float xpos, ypos, zpos;
int zone;
string programName;
string fileName;
float feedOverride;
float spindleOverride;
int tool;
public:
SchedEntry();
~SchedEntry();
int getPriority() const;
void setPriority(int pri);
int getTagId() const;
void setTagId(int tag);
void getOffsets(float &x, float &y, float &z);
void setOffsets(float x, float y, float z);
int getZone() const;
void setZone(int z);
string getFileName() const;
void setFileName(string s);
string getProgramName() const;
void setProgramName(string s);
float getFeedOverride() const;
void setFeedOverride(float f);
float getSpindleOverride() const;
void setSpindleOverride(float s);
int getTool() const;
void setTool(int t);
};
SchedEntry::SchedEntry() {
priority = 0;
tagId = 0;
xpos = 0.0;
ypos = 0.0;
zpos = 0.0;
zone = 0;
fileName = "";
feedOverride = 100.0;
spindleOverride = 100.0;
tool = 1;
}
list<SchedEntry> q;
bool operator<(const SchedEntry &a, const SchedEntry &b) {
return a.getPriority() < b.getPriority();
}
bool operator==(const SchedEntry &a, const SchedEntry &b) {
return a.getPriority() == b.getPriority();
}
SchedEntry::~SchedEntry() {
}
int SchedEntry::getPriority() const {
return priority;
}
void SchedEntry::setPriority(int pri) {
priority = pri;
}
int SchedEntry::getTagId() const {
return tagId;
}
void SchedEntry::setTagId(int tag) {
tagId = tag;
}
void SchedEntry::getOffsets(float &x, float &y, float &z) {
x = xpos;
y = ypos;
z = zpos;
}
void SchedEntry::setOffsets(float x, float y, float z) {
xpos = x;
ypos = y;
zpos = z;
}
int SchedEntry::getZone() const {
return zone;
}
void SchedEntry::setZone(int z) {
zone = z;
}
string SchedEntry::getFileName() const {
return fileName;
}
void SchedEntry::setFileName(string s) {
fileName = s;
}
string SchedEntry::getProgramName() const {
return programName;
}
void SchedEntry::setProgramName(string s) {
programName = s;
}
float SchedEntry::getFeedOverride() const {
return feedOverride;
}
void SchedEntry::setFeedOverride(float f) {
feedOverride = f;
}
float SchedEntry::getSpindleOverride() const {
return spindleOverride;
}
void SchedEntry::setSpindleOverride(float s) {
spindleOverride = s;
}
int SchedEntry::getTool() const {
return tool;
}
void SchedEntry::setTool(int t) {
tool = t;
}
static void crcInit() {
crc rmdr;
int i;
uint32_t bit;
for (i = 0; i < 256; ++i)
{
rmdr = i << (WIDTH - 8);
for (bit = 8; bit > 0; --bit)
{
if (rmdr & TOPBIT)
{
rmdr = (rmdr << 1) ^ POLYNOMIAL;
}
else
{
rmdr = (rmdr << 1);
}
}
crcTable[i] = rmdr;
}
}
static void crcFast(uint32_t value) {
uint32_t data;
data = value ^ (crcResult >> (WIDTH - 8));
crcResult = crcTable[data] ^ (crcResult << 8);
}
static queueStatusType getQueueStatus() {
return queueStatus;
}
static void setQueueStatus(queueStatusType qs) {
if ((qs == qsResume) && (queueStatus == qsPause)) queueStatus = qsRun;
else queueStatus = qs;
}
bool isIdle()
{
return ((emcStatus->task.interpState != EMC_TASK_INTERP_READING) &&
(emcStatus->task.interpState != EMC_TASK_INTERP_WAITING) &&
(emcStatus->task.interpState != EMC_TASK_INTERP_PAUSED));
}
bool interlocksOk() {
if (emcStatus->task.state == EMC_TASK_STATE_ESTOP) {
return false;
}
if (emcStatus->task.state != EMC_TASK_STATE_ON) {
return false;
}
return true;
}
void updateQueue() {
char fileStr[255];
float x, y, z;
char cmd[80];
if (queueStatus == qsRun) {
if (isIdle() && q.empty()) {
queueStatus = qsStop;
return;
}
if (!q.empty()) {
if (isIdle()) {
q.front().setPriority(MAX_PRIORITY); if (interlocksOk()) {
sendFeedOverride(((double) q.front().getFeedOverride()) / 100.0);
sendSpindleOverride(0, ((double) q.front().getSpindleOverride()) / 100.0);
sendMdi();
sendMdiCmd("G92.1\n");
if (emcCommandWaitDone() != 0) {
queueStatus = qsError;
return;
}
if (q.front().getZone() != 0) {
switch (q.front().getZone()) {
case 1: sendMdiCmd("G54\n"); break;
case 2: sendMdiCmd("G55\n"); break;
case 3: sendMdiCmd("G56\n"); break;
case 4: sendMdiCmd("G57\n"); break;
case 5: sendMdiCmd("G58\n"); break;
case 6: sendMdiCmd("G59\n"); break;
case 7: sendMdiCmd("G59.1\n"); break;
case 8: sendMdiCmd("G59.2\n"); break;
case 9: sendMdiCmd("G59.3\n");
}
if (emcCommandWaitDone() != 0) {
queueStatus = qsError;
return;
}
}
else {
q.front().getOffsets(x, y, z);
sprintf(cmd, "G0 X%f Y%f Z%f\n", x, y, z);
sendMdiCmd(cmd);
if (emcCommandWaitDone() != 0) {
queueStatus = qsError;
return;
}
sendMdiCmd("G92 X0 Y0 Z0\n");
if (emcCommandWaitDone() != 0) {
queueStatus = qsError;
return;
}
}
if (sendTaskPlanInit() != 0) {
queueStatus = qsError;
}
sendAuto();
strcpy(fileStr, defaultPath);
strcat(fileStr, q.front().getFileName().c_str());
if (sendProgramOpen(fileStr) != 0) {
queueStatus = qsError;
return;
}
if (sendProgramRun(0) != 0) {
queueStatus = qsError;
}
q.remove(q.front());
}
else queueStatus = qsError;
}
}
}
}
int addProgram(int pri, int tag, float x, float y, float z, int azone, string progName, float feedOvr, float spindleOvr, int toolNum) {
SchedEntry p;
p.setPriority(pri);
p.setTagId(tag);
if (azone == 0)
p.setOffsets(x, y, z);
else p.setZone(azone);
p.setFileName(progName);
p.setFeedOverride(feedOvr);
p.setSpindleOverride(spindleOvr);
p.setTool(toolNum);
q.push_back(p);
q.sort();
return q.size();
}
int getQueueSize() {
return q.size();
}
void clearQueue() {
while (!q.empty()) {
q.remove(q.front());
}
}
int getStatus() {
return (int) getQueueStatus();
}
void queueStart() {
setQueueStatus(qsRun);
}
void queueStop() {
setQueueStatus(qsStop);
clearQueue();
}
void queuePause() {
setQueueStatus(qsPause);
}
int getProgramById(int id, qRecType *qRec) {
list<SchedEntry>::iterator i;
if (q.size() == 0) return -1;
for (i=q.begin(); i!=q.end(); ++i) {
if (i->getTagId() == id) break;
}
if (i->getTagId() != id) return -1;
qRec->priority = i->getPriority();
qRec->tagId = i->getTagId();
i->getOffsets(qRec->xpos, qRec->ypos, qRec->zpos);
qRec->zone = i->getZone();
strcpy(qRec->fileName, i->getFileName().c_str());
qRec->feedOverride = i->getFeedOverride();
qRec->spindleOverride = i->getSpindleOverride();
qRec->tool = i->getTool();
return 0;
}
int getProgramByIndex(int idx, qRecType *qRec) {
list<SchedEntry>::iterator i;
int index;
if ((unsigned int) idx >= q.size()) return -1;
index = 0;
for (i=q.begin(); i!=q.end(); ++i) {
if (index == idx) break;
index++;
}
qRec->priority = i->getPriority();
qRec->tagId = i->getTagId();
i->getOffsets(qRec->xpos, qRec->ypos, qRec->zpos);
qRec->zone = i->getZone();
strcpy(qRec->fileName, i->getFileName().c_str());
qRec->feedOverride = i->getFeedOverride();
qRec->spindleOverride = i->getSpindleOverride();
qRec->tool = i->getTool();
return 0;
}
int getQueueCRC() {
list<SchedEntry>::iterator i;
crcResult = 0;
for (i=q.begin(); i!=q.end(); ++i) {
crcFast(i->getTagId());
}
return crcResult;
}
int getFirstTagId() {
if (q.empty()) return 0;
return q.front().getTagId();
}
int getLastTagId() {
if (q.empty()) return 0;
return q.back().getTagId();
}
int deleteProgramById(int id) {
list<SchedEntry>::iterator i;
for (i=q.begin(); i!=q.end(); ++i) {
if (i->getTagId() == id) {
if (i->getPriority() == (int)MAX_PRIORITY) return -1;
i = q.erase(i);
return 0;
}
}
return -1;
}
int deleteProgramByIndex(int idx) {
list<SchedEntry>::iterator i;
int index = 0;
for (i=q.begin(); i!=q.end(); ++i) {
if (index == idx) {
if (i->getPriority() == (int)MAX_PRIORITY) return -1;
i = q.erase(i);
return 0;
}
index++;
}
return -1;
}
int changePriorityById(int id, int newPriority) {
list<SchedEntry>::iterator i;
for (i=q.begin(); i!=q.end(); ++i) {
if (i->getTagId() == id) {
if (i->getPriority() == (int)MAX_PRIORITY) return -1;
i->setPriority(newPriority);
q.sort();
return 0;
}
}
return -1;
}
int changePriorityByIndex(int idx, int newPriority) {
list<SchedEntry>::iterator i;
int index = 0;
for (i=q.begin(); i!=q.end(); ++i) {
if (index == idx) {
if (i->getPriority() == (int)MAX_PRIORITY) return -1;
i->setPriority(newPriority);
q.sort();
return 0;
}
index++;
}
return -1;
}
int getPriorityById(int id, int &pri) {
list<SchedEntry>::iterator i;
for (i=q.begin(); i!=q.end(); ++i) {
if (i->getTagId() == id) {
pri = i->getPriority();
return 0;
}
}
return -1;
}
int getPriorityByIndex(int idx, int &pri) {
list<SchedEntry>::iterator i;
int index = 0;
for (i=q.begin(); i!=q.end(); ++i) {
if (index == idx) {
pri = i->getPriority();
return 0;
}
index++;
}
return -1;
}
int getNextTagId() {
return autoTagId++;
}
void resetTagIds(int startId) {
autoTagId = startId;
}
void schedInit() {
crcInit();
}