programm works

This commit is contained in:
DashyFox 2024-09-22 21:38:17 +03:00
parent b98846eac1
commit 5b4db505c2
6 changed files with 263 additions and 117 deletions

View File

@ -106,8 +106,8 @@ typedef struct __attribute__((packed)) {
} HardwareInit_t; } HardwareInit_t;
typedef struct __attribute__((packed)) { typedef struct __attribute__((packed)) {
uint32_t totalShots; uint32_t shotsInShot;
uint32_t totalPrograms; uint32_t shotsInProgram;
uint32_t totalMacros; uint32_t totalMacros;
} Statistics; } Statistics;

View File

@ -36,14 +36,16 @@ typedef enum State{
typedef struct CurrentShot { typedef struct CurrentShot {
uint8_t index; uint8_t index;
uint16_t currentRepeatCount; uint16_t currentBallCount;
Shot shot; Shot shot;
} CurrentShot; } CurrentShot;
typedef struct CurrentProgram { typedef struct CurrentProgram {
uint8_t index; uint8_t index;
Program program; Program program;
uint8_t shot_index; CurrentShot currentShot;
uint8_t programShotId;
uint16_t currentBallCount;
} CurrentProgram; } CurrentProgram;
typedef struct CurrentMacro { typedef struct CurrentMacro {
@ -75,7 +77,7 @@ void BallEXT();
void RobotTick(); void RobotTick();
uint8_t prepareShot(uint8_t number); uint8_t prepareShot(uint8_t number);
//uint8_t prepareProgramm(uint8_t number); uint8_t prepareProgramm(uint8_t number);
//uint8_t prepareMacro(uint8_t number); //uint8_t prepareMacro(uint8_t number);

View File

@ -46,8 +46,8 @@ MemoryStatus EEPROM_INIT() {
infoBlock.hwInfo.servos[SERVO_VERTICAL].def = 90; infoBlock.hwInfo.servos[SERVO_VERTICAL].def = 90;
infoBlock.hwInfo.servos[SERVO_VERTICAL].max = 180; infoBlock.hwInfo.servos[SERVO_VERTICAL].max = 180;
infoBlock.statInfo.totalShots = 0; infoBlock.statInfo.shotsInShot = 0;
infoBlock.statInfo.totalPrograms = 0; infoBlock.statInfo.shotsInProgram = 0;
infoBlock.statInfo.totalMacros = 0; infoBlock.statInfo.totalMacros = 0;
status = saveInfoBlock(&infoBlock); status = saveInfoBlock(&infoBlock);
@ -112,11 +112,11 @@ MemoryStatus EEPROM_INIT() {
CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer));
snprintf(buffer, sizeof(buffer), "Total Shots: %lu\n", snprintf(buffer, sizeof(buffer), "Total Shots: %lu\n",
infoBlock.statInfo.totalShots); infoBlock.statInfo.shotsInShot);
CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer));
snprintf(buffer, sizeof(buffer), "Total Programs: %lu\n", snprintf(buffer, sizeof(buffer), "Total Programs: %lu\n",
infoBlock.statInfo.totalPrograms); infoBlock.statInfo.shotsInProgram);
CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer)); CDC_Transmit_FS((uint8_t*) buffer, strlen(buffer));
snprintf(buffer, sizeof(buffer), "Total Macros: %lu\n\n", snprintf(buffer, sizeof(buffer), "Total Macros: %lu\n\n",
@ -263,7 +263,7 @@ MemoryStatus EEPROM_EARSE() {
uint16_t old_addr = 0; uint16_t old_addr = 0;
do { do {
uint8_t Buf[255]; uint8_t Buf[255];
memset(Buf, 0xFF, sizeof(Buf)); memset(Buf, 0x00, sizeof(Buf));
FLASH_WriteBlock(addr, 0, Buf, sizeof(Buf), sizeof(Buf)); FLASH_WriteBlock(addr, 0, Buf, sizeof(Buf), sizeof(Buf));
old_addr = addr; old_addr = addr;
addr += sizeof(Buf); addr += sizeof(Buf);

View File

@ -31,6 +31,16 @@ uint32_t noBallTimer = 0;
uint32_t noBallTimeout = 0xFFFFFFFF; uint32_t noBallTimeout = 0xFFFFFFFF;
void BallEXT_Handler(); void BallEXT_Handler();
Shot* getShotFromProgram(CurrentProgram *currentProg);
void robotStateStart(uint32_t delayTime);
void robotStatePause();
void robotStateStop();
float calculatePeriod(int pwm_value);
uint8_t nextBallinShot(CurrentShot *shot);
void shotApply(Shot *shot);
uint8_t loadNextShotInProgram(CurrentProgram *currentProg);
uint8_t loadShotFromProgram(CurrentProgram *currentProg);
Shot* getShotFromProgram(CurrentProgram *currentProg);
void robotStateStart(uint32_t delayTime) { void robotStateStart(uint32_t delayTime) {
currentInfo.state = PRERUN_WAIT; currentInfo.state = PRERUN_WAIT;
@ -51,7 +61,6 @@ void BallEXT() {
ballReact_timer = millis(); ballReact_timer = millis();
} }
// Функция для расчета периода вылета мяча на основе ШИМ // Функция для расчета периода вылета мяча на основе ШИМ
float calculatePeriod(int pwm_value) { float calculatePeriod(int pwm_value) {
// Коэффициенты из аппроксимации // Коэффициенты из аппроксимации
@ -102,6 +111,27 @@ void RobotTick() {
} }
} }
uint8_t nextBallinShot(CurrentShot *shot) {
print("shot->shot.countRepeatShot ");
printNumber(shot->shot.countRepeatShot);
print("\n");
if (shot->currentBallCount + 1 < shot->shot.countRepeatShot
|| !shot->shot.countRepeatShot) {
// nextBall
print("Shot ");
printNumber(shot->currentBallCount);
print("\n\n");
shot->currentBallCount++;
return 0;
} else {
print("Shot DONE\n");
return 1;
}
}
void BallEXT_Handler() { void BallEXT_Handler() {
if (ballDetected && millis() - ballReact_timer > ballReact_value) { if (ballDetected && millis() - ballReact_timer > ballReact_value) {
ballDetected = 0; ballDetected = 0;
@ -122,24 +152,30 @@ void BallEXT_Handler() {
break; break;
case ShotMode: case ShotMode:
if (currentInfo.shot.currentRepeatCount + 1 if (nextBallinShot(&currentInfo.shot)) {
< currentInfo.shot.shot.countRepeatShot
|| !currentInfo.shot.shot.countRepeatShot) {
// nextRepeatCount
print("Shot ");
printNumber(currentInfo.shot.currentRepeatCount);
print("\n\n");
saveInfoBlock();
currentInfo.shot.currentRepeatCount++;
} else {
// shotDone
stopShooting(); stopShooting();
print("Shot DONE\n");
} }
infoBlock.statInfo.totalShots++; infoBlock.statInfo.shotsInShot++;
saveInfoBlock();
break; break;
case ProgramMode: case ProgramMode:
if (nextBallinShot(&currentInfo.program.currentShot)) {
if (!loadNextShotInProgram(&currentInfo.program)) {
stopShooting();
print("loadNextShotInProgram ERR\n");
}
shotApply(getShotFromProgram(&currentInfo.program));
}
if (currentInfo.program.currentBallCount + 1
< currentInfo.program.program.header.countRepeat) {
currentInfo.program.currentBallCount++;
} else {
stopShooting();
print("Program DONE\n");
}
infoBlock.statInfo.shotsInProgram++;
saveInfoBlock();
break; break;
case MacroMode: case MacroMode:
@ -230,38 +266,93 @@ void shotApply(Shot *shot) {
shot->rotationVertical); shot->rotationVertical);
setRollersSpeed(shot->speedRollerTop, shot->speedRollerBottom); setRollersSpeed(shot->speedRollerTop, shot->speedRollerBottom);
setScrewkSpeed(shot->speedScrew); setScrewkSpeed(shot->speedScrew);
noBallTimeout = calculatePeriod(
shot->speedScrew) * NOBALL_TIMEOUT_MULTIPLIER;
noBallTimer = millis(); noBallTimer = millis();
print("Fire!\n");
print("isExist ");
printNumber(shot->isExist);
print("\ncountRepeatShot; ");
printNumber(shot->countRepeatShot);
print("\nspeedRollerTop; ");
printNumber(shot->speedRollerTop);
print("\nspeedRollerBottom; ");
printNumber(shot->speedRollerBottom);
print("\nspeedScrew; ");
printNumber(shot->speedScrew);
print("\nrotationAxial; ");
printNumber(shot->rotationAxial);
print("\nrotationHorizontal; ");
printNumber(shot->rotationHorizontal);
print("\nrotationVertical; ");
printNumber(shot->rotationVertical);
print("\nnoBallTimeout: ");
printNumber(noBallTimeout);
print("\n");
print("\n\n");
}
uint8_t loadShotFromProgram(CurrentProgram *currentProg) {
Shot shot_;
uint8_t currentProgramShotId = currentProg->programShotId;
if (currentProgramShotId >= currentProg->program.header.shotCount) {
print("Shot index out of range\n");
// TODO: sound_ERR(); ledFX_ERR();
return 0;
}
uint8_t shotId = currentProg->program.shots[currentProgramShotId].id;
currentProg->currentShot.index = shotId;
getShot(shotId, &shot_);
if (!shot_.isExist) {
print("Shot in program is NULL\n");
// TODO: sound_ERR(); ledFX_ERR();
return 0;
}
shot_.speedScrew =
currentProg->program.shots[currentProgramShotId].speedScrew;
uint8_t repeatCountFromShot = currentProg->program.header.options & 2U;
if (!repeatCountFromShot) {
print("Repeat Count Override\n");
shot_.countRepeatShot = 1;
}
currentProg->currentShot.shot = shot_;
print("REPEAT ");
printNumber(shot_.countRepeatShot);
print("\n");
currentProg->currentShot.currentBallCount = 0;
return 1;
}
uint8_t loadNextShotInProgram(CurrentProgram *currentProg) {
uint8_t random = currentProg->program.header.options & 1U;
uint8_t *currentProgramShotId = &currentProg->programShotId;
if (random) {
*currentProgramShotId = rand() % currentProg->program.header.shotCount;
} else {
if ((*currentProgramShotId) + 1
< currentProg->program.header.shotCount) {
++(*currentProgramShotId);
} else {
*currentProgramShotId = 0;
}
}
return loadShotFromProgram(currentProg);
}
Shot* getShotFromProgram(CurrentProgram *currentProg) {
return &currentProg->currentShot.shot;
} }
void startShooting(uint32_t delayTime) { void startShooting(uint32_t delayTime) {
print("StartShooting\n");
switch (currentInfo.mode) { switch (currentInfo.mode) {
case ShotMode: case ShotMode:
print("StartShooting\n");
if (currentInfo.shot.shot.isExist) { if (currentInfo.shot.shot.isExist) {
print("Fire!\n");
print("isExist ");
printNumber(currentInfo.shot.shot.isExist);
print("\ncountRepeatShot; ");
printNumber(currentInfo.shot.shot.countRepeatShot);
print("\nspeedRollerTop; ");
printNumber(currentInfo.shot.shot.speedRollerTop);
print("\nspeedRollerBottom; ");
printNumber(currentInfo.shot.shot.speedRollerBottom);
print("\nspeedScrew; ");
printNumber(currentInfo.shot.shot.speedScrew);
print("\nrotationAxial; ");
printNumber(currentInfo.shot.shot.rotationAxial);
print("\nrotationHorizontal; ");
printNumber(currentInfo.shot.shot.rotationHorizontal);
print("\nrotationVertical; ");
printNumber(currentInfo.shot.shot.rotationVertical);
print("\n\n");
postDelayShot = &currentInfo.shot.shot; postDelayShot = &currentInfo.shot.shot;
#if PRE_RUN_DELAY_MODE == 0 if (PRE_RUN_DELAY_MODE) {
#elif PRE_RUN_DELAY_MODE == 1
setPosFromShot(postDelayShot); setPosFromShot(postDelayShot);
#endif }
robotStateStart(delayTime); robotStateStart(delayTime);
} else { } else {
print("Current Shot is NULL\n"); print("Current Shot is NULL\n");
@ -269,10 +360,29 @@ void startShooting(uint32_t delayTime) {
} }
break; break;
case ProgramMode: case ProgramMode:
if (currentInfo.program.program.header.shotCount) {
if (!loadShotFromProgram(&currentInfo.program)) {
print("loadShotFromProgram ERR\n");
break;
}
postDelayShot = getShotFromProgram(&currentInfo.program);
if (PRE_RUN_DELAY_MODE) {
setPosFromShot(postDelayShot);
}
robotStateStart(delayTime);
} else {
print("Current Program is NULL\n");
// TODO: sound_ERR(); ledFX_ERR();
}
break; break;
case MacroMode: case MacroMode:
if (currentInfo.macro.macro.header.programmCount) {
} else {
print("Current Macro is NULL\n");
// TODO: sound_ERR(); ledFX_ERR();
}
break; break;
default: default:
break; break;
@ -292,11 +402,7 @@ uint8_t prepareShot(uint8_t number) {
if (shot.isExist) { if (shot.isExist) {
currentInfo.mode = ShotMode; currentInfo.mode = ShotMode;
currentInfo.shot.shot = shot; currentInfo.shot.shot = shot;
currentInfo.shot.currentRepeatCount = 0; currentInfo.shot.currentBallCount = 0;
noBallTimeout = calculatePeriod(shot.speedScrew)*NOBALL_TIMEOUT_MULTIPLIER;
print("noBallTimeout: ");
printNumber(noBallTimeout);
print("\n");
return 1; return 1;
} else { } else {
// TODO: sound_ERR(); ledFX_ERR(); // TODO: sound_ERR(); ledFX_ERR();
@ -305,6 +411,23 @@ uint8_t prepareShot(uint8_t number) {
} }
} }
uint8_t prepareProgramm(uint8_t number) {
Program program;
getProg(number, &program);
if (program.header.shotCount) { // isExist
currentInfo.mode = ProgramMode;
currentInfo.program.program = program;
currentInfo.program.index = number;
currentInfo.program.programShotId = 0;
currentInfo.program.currentBallCount = 0;
return 1;
} else {
// TODO: sound_ERR(); ledFX_ERR();
print("program not exist\n\n");
return 0;
}
}
void setPosSingle(ServoMap servo, uint8_t value) { void setPosSingle(ServoMap servo, uint8_t value) {
ServoSetting *currentServo = &infoBlock.hwInfo.servos[servo]; ServoSetting *currentServo = &infoBlock.hwInfo.servos[servo];
uint8_t inv = currentServo->invert; uint8_t inv = currentServo->invert;
@ -332,7 +455,8 @@ void setPos(uint8_t axial, uint8_t horizontal, uint8_t vertical) {
} }
void setPosFromShot(Shot *shot) { void setPosFromShot(Shot *shot) {
setPos(shot->rotationAxial, shot->rotationHorizontal, shot->rotationVertical); setPos(shot->rotationAxial, shot->rotationHorizontal,
shot->rotationVertical);
} }
void setPosDefault() { void setPosDefault() {

View File

@ -49,8 +49,6 @@ void UART3_SaveShot(uint8_t *dataPtr, uint8_t len) {
shot.rotationHorizontal = map((int8_t) dataPtr[7], -99, 99, 0, 180); shot.rotationHorizontal = map((int8_t) dataPtr[7], -99, 99, 0, 180);
shot.rotationVertical = 180 - (int8_t) dataPtr[8] - 90; shot.rotationVertical = 180 - (int8_t) dataPtr[8] - 90;
saveShot(shotIndx, &shot); saveShot(shotIndx, &shot);
SendResponse(dataPtr[0], 0, NULL, 0); SendResponse(dataPtr[0], 0, NULL, 0);
@ -109,7 +107,6 @@ void UART3_SaveMacro(uint8_t *dataPtr, uint8_t len) {
SendResponse(dataPtr[0], 0, NULL, 0); SendResponse(dataPtr[0], 0, NULL, 0);
} }
void UART3_StartMacro(uint8_t *dataPtr, uint8_t len) { void UART3_StartMacro(uint8_t *dataPtr, uint8_t len) {
const uint8_t MIN_PARAM_LENGTH = 0; const uint8_t MIN_PARAM_LENGTH = 0;
if (!checkLen(dataPtr[0], len, MIN_PARAM_LENGTH)) if (!checkLen(dataPtr[0], len, MIN_PARAM_LENGTH))
@ -123,6 +120,10 @@ void UART3_StartProgram(uint8_t *dataPtr, uint8_t len) {
if (!checkLen(dataPtr[0], len, MIN_PARAM_LENGTH)) if (!checkLen(dataPtr[0], len, MIN_PARAM_LENGTH))
return; return;
uint8_t progIndx = dataPtr[1];
prepareProgramm(progIndx);
startShooting(infoBlock.hwInfo.timings.preRun);
SendResponse(dataPtr[0], 0, NULL, 0); SendResponse(dataPtr[0], 0, NULL, 0);
} }
@ -196,7 +197,6 @@ void UART3_DeleteAllData(uint8_t *dataPtr, uint8_t len) {
EEPROM_EARSE(); EEPROM_EARSE();
saveInfoBlock(); saveInfoBlock();
SendResponse(dataPtr[0], 0, NULL, 0); SendResponse(dataPtr[0], 0, NULL, 0);
} }
@ -452,26 +452,41 @@ void UART3_ReadStatistics(uint8_t *dataPtr, uint8_t len) {
uint8_t macro_number; uint8_t macro_number;
uint8_t program_number; uint8_t program_number;
uint8_t shot_number; uint8_t shot_number;
uint8_t total_macro_done_HIGH;
uint8_t total_macro_done_LOW; uint8_t total_macro_done_LOW;
uint8_t total_program_done_HIGH; uint8_t total_macro_done_HIGH;
uint8_t total_program_done_LOW; uint8_t total_program_done_LOW;
uint8_t total_shot_done_HIGH; uint8_t total_program_done_HIGH;
uint8_t total_shot_done_LOW; uint8_t total_shot_done_LOW;
uint8_t total_shot_done_HIGH;
} StatusStruct; } StatusStruct;
StatusStruct res; StatusStruct res;
uint8_t isRun = currentInfo.state == RUN;
res.status = isRun;
res.status = currentInfo.state == RUN; res.shot_number = 0xFF;
res.shot_number = currentInfo.shot.index; res.program_number = 0xFF;
res.program_number = currentInfo.program.index; res.macro_number = 0xFF;
res.macro_number = currentInfo.macro.index;
res.total_shot_done_HIGH = HIGHBIT(infoBlock.statInfo.totalShots); switch (currentInfo.mode) {
res.total_shot_done_LOW = LOWBIT(infoBlock.statInfo.totalShots); case ShotMode:
res.shot_number = isRun ? currentInfo.shot.index : 0xFF;
break;
case ProgramMode:
res.program_number = isRun ? currentInfo.program.index : 0xFF;
break;
case MacroMode:
res.macro_number = isRun ? currentInfo.macro.index : 0xFF;
break;
default:
break;
}
res.total_program_done_HIGH = HIGHBIT(infoBlock.statInfo.totalPrograms); res.total_shot_done_HIGH = HIGHBIT(infoBlock.statInfo.shotsInShot);
res.total_program_done_LOW = LOWBIT(infoBlock.statInfo.totalPrograms); res.total_shot_done_LOW = LOWBIT(infoBlock.statInfo.shotsInShot);
res.total_program_done_HIGH = HIGHBIT(infoBlock.statInfo.shotsInProgram);
res.total_program_done_LOW = LOWBIT(infoBlock.statInfo.shotsInProgram);
res.total_macro_done_HIGH = HIGHBIT(infoBlock.statInfo.totalMacros); res.total_macro_done_HIGH = HIGHBIT(infoBlock.statInfo.totalMacros);
res.total_macro_done_LOW = LOWBIT(infoBlock.statInfo.totalMacros); res.total_macro_done_LOW = LOWBIT(infoBlock.statInfo.totalMacros);

View File

@ -47,5 +47,10 @@ IR:
Ошибки: Ошибки:
V В некоторый момент PID регулятор выдаёт 0 и двигатель не запускается не зависимо от входного значенияPWM V+- В некоторый момент PID регулятор выдаёт 0 и двигатель не запускается не зависимо от входного значенияPWM
Оранж:
При сбоях UART вешает его и иногда не переинициализирует даже после рестарта контроллера
Программы:
Есл стоит "Настроить темп ударов", во все удары приходят нули.