diff options
| author | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2019-04-07 16:15:05 +0300 |
|---|---|---|
| committer | Victoria Plitt <Victoria.Plitt@twine-s.com> | 2019-04-07 16:15:05 +0300 |
| commit | b4a71931ea52636c6b36376aa9d71697ccf73524 (patch) | |
| tree | d4b6db4671e4e7bf1f91d008798ae909462ed784 | |
| parent | 4a9fb8a89a7fc48d9d3ecc9f24770c472834453d (diff) | |
| parent | df349ae963176cb53ef7b924cfb53ba09d32bfaf (diff) | |
| download | Tango-b4a71931ea52636c6b36376aa9d71697ccf73524.tar.gz Tango-b4a71931ea52636c6b36376aa9d71697ccf73524.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
78 files changed, 3496 insertions, 654 deletions
diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c index d57d3b14b..3357cfc06 100644 --- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c +++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c @@ -55,6 +55,7 @@ int32_t FileSentLength = 0; static char g_cCwdBuf[50] = "/"; uint32_t WrittenBytes = 0; uint32_t ReadBytes = 0; +Task_Handle CommRxTaskHandle; ErrorCode getErrorCode(FRESULT Fresult) @@ -81,27 +82,34 @@ uint32_t FileUploadRequestFunc(MessageContainer* requestContainer) FileUploadResponse response = FILE_UPLOAD_RESPONSE__INIT; WrittenBytes=0; - UploadFileHandle = my_malloc(sizeof(FIL)); - if (UploadFileHandle == 0) + if (JobIsActive()) Fresult = FR_DENIED; else { - Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE |FA_OPEN_ALWAYS| FA_CREATE_ALWAYS); - if (Fresult == FR_OK) - { - FileLength = request->length; - response.has_maxchunklength = true; - response.maxchunklength = MAX_CHUNK_LENGTH; - strcpy(FileHandleChar, "1234"); - response.uploadid = FileHandleChar; //supporting only single file at each time. - } + UploadFileHandle = my_malloc(sizeof(FIL)); + if (UploadFileHandle == 0) + Fresult = FR_DENIED; else { - free (UploadFileHandle); - UploadFileHandle = 0; - } + Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS); + if (Fresult == FR_OK) + { + FileLength = request->length; + response.has_maxchunklength = true; + response.maxchunklength = MAX_CHUNK_LENGTH; + strcpy(FileHandleChar, "1234"); + response.uploadid = FileHandleChar; //supporting only single file at each time. + } + else + { + free (UploadFileHandle); + UploadFileHandle = 0; + } + } } + CommRxTaskHandle = Task_self(); + Task_setPri(CommRxTaskHandle, 4); responseContainer = createContainer(MESSAGE_TYPE__FileUploadResponse, requestContainer->token, false, &response, &file_upload_response__pack, &file_upload_response__get_packed_size); @@ -123,6 +131,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; + bool FileDone = false; MessageContainer responseContainer; @@ -142,6 +151,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) if(Fresult != FR_OK) { LOG_ERROR (Fresult,"f_write error"); + FileDone = true; } else { @@ -152,6 +162,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) f_close(ReceivedFileHandle); free (UploadFileHandle); FileReceivedLength = 0; + FileDone = true; } else { @@ -161,6 +172,7 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) f_close(ReceivedFileHandle); free (UploadFileHandle); FileReceivedLength = 0; + FileDone = true; } } } @@ -185,6 +197,8 @@ uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) file_chunk_upload_request__free_unpacked(request,NULL); my_free(responseContainer.data.data); SendChars(container_buffer, container_size); + if (FileDone == true) + Task_setPri(CommRxTaskHandle, 9); return OK; } @@ -504,7 +518,7 @@ uint32_t GetFilesRequestFunc(MessageContainer* requestContainer) #define MAX_NUM_OF_FILES 10 DIR dir; FILINFO* fno[MAX_NUM_OF_FILES]; - char FullPath[MAX_NUM_OF_FILES][50]; + char FullPath[MAX_NUM_OF_FILES][100]; int i,NumOfFiles = 0; FRESULT Fresult = FR_OK; @@ -580,11 +594,14 @@ uint32_t GetFilesRequestFunc(MessageContainer* requestContainer) } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); - size_t container_size = message_container__pack(&responseContainer, container_buffer); + if (container_buffer) + { + size_t container_size = message_container__pack(&responseContainer, container_buffer); + SendChars(container_buffer, container_size); + } my_free(responseContainer.data.data); my_free(FilesInfo); get_files_request__free_unpacked(request,NULL); - SendChars(container_buffer, container_size); for (i = 0;i < NumOfFiles;i++) { if (fno[i]) diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c index 456c30290..d54280fee 100644 --- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c +++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.c @@ -21,6 +21,7 @@ #include <Communication/PMR/FirmwareUpgrade/VersionFileDescriptor.pb-c.h> #include <Communication/PMR/FirmwareUpgrade/VersionPackageDescriptor.pb-c.h> +#include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h" #include "drivers/FPGA/Full_Vme/FPGA_Programming_Up.h" #include "drivers/FPGA/Full_Vme/ispvme/vmopcode.h" #include "Common/Utilities/Utils.h" @@ -35,10 +36,20 @@ char activateString[100]; char ActivateToken[36+1]={0}; bool Reboot = false; + +bool SwUpgradeActive(void) +{ + if (ActivateVersionControlId != 0xFF) + { + Reboot = false; + return true; + } + return false; +} uint32_t ActivateVersionCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) { - ActivateVersionResponse response = ACTIVATE_VERSION_RESPONSE__INIT; - MessageContainer responseContainer; + //ActivateVersionResponse response = ACTIVATE_VERSION_RESPONSE__INIT; + //MessageContainer responseContainer; usnprintf(activateString, 1000, "file %d of %d bytes %d of %d",CurrentRunningFile,NumberOfFiles,vme_index,CurrentFileSize); diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.h b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.h index 9af76f96f..6f817fe90 100644 --- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.h +++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FirmwareUpgrade.h @@ -11,6 +11,7 @@ uint32_t ActivateVersionRequestFunc(MessageContainer* requestContainer); uint32_t ValidateVersionRequestFunc(MessageContainer* requestContainer); +bool SwUpgradeActive(void); diff --git a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c index e037f2bad..030c4229e 100644 --- a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c +++ b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c @@ -20,7 +20,7 @@ typedef struct } TangoVersion_t; -TangoVersion_t _gTangoVersion = {1,3,8,12}; +TangoVersion_t _gTangoVersion = {1,3,8,3}; #define BUILD_DATE __DATE__ char Dat[50] = BUILD_DATE; char _gTangoName [MAX_STRING_LEN] = "Tango01 ";//d diff --git a/Software/Embedded_SW/Embedded/Common/report/distributor.c b/Software/Embedded_SW/Embedded/Common/report/distributor.c index c026ad4d2..f011653ec 100644 --- a/Software/Embedded_SW/Embedded/Common/report/distributor.c +++ b/Software/Embedded_SW/Embedded/Common/report/distributor.c @@ -242,7 +242,7 @@ Void reportService(UArg arg0, UArg arg1) ReportInitParams InitParams; InitParams.DistributorQueueMaxMsgs = 30; InitParams.DistributorTaskPriority = 6; - InitParams.MaxNumOfFilterNames = 1;//30 + InitParams.MaxNumOfFilterNames = 30; InitParams.MaxNumberOfPrivateDistributors = 2; ReportInit (InitParams); diff --git a/Software/Embedded_SW/Embedded/Communication/Container.c b/Software/Embedded_SW/Embedded/Communication/Container.c index ad57c36ab..b0c063a5e 100644 --- a/Software/Embedded_SW/Embedded/Communication/Container.c +++ b/Software/Embedded_SW/Embedded/Communication/Container.c @@ -43,6 +43,7 @@ #include "Communication/CommunicationTask.h" #include "StateMachines/Printing/PrintingSTM.h" +#include "StateMachines/Initialization/PowerIdle.h" #include "Common/report/report.h" #include "Connection.h" @@ -130,6 +131,8 @@ void receive_callback(char* buffer, size_t length) if (requestContainer == NULL) return; // HeatingTestSendResonse(0, false,true,true, /*OriginalMotorSpd_2PPS[index]*/length,requestContainer->type,0,0, "Container"); + if (requestContainer->type != MESSAGE_TYPE__KeepAliveRequest) //user action resets the idle counter + resetIdleCounter(); msgId[index] = requestContainer->type; Length[index] = length; diff --git a/Software/Embedded_SW/Embedded/DataDef.h b/Software/Embedded_SW/Embedded/DataDef.h index 424eff1d8..1b5f000f2 100644 --- a/Software/Embedded_SW/Embedded/DataDef.h +++ b/Software/Embedded_SW/Embedded/DataDef.h @@ -400,7 +400,7 @@ Supports diagnostic <id> (--diag_suppress, - pds) #define HEAD6_PT100 TEMP_SENSE_AN_ENCLOSURETEMP3 #define MIXER_PT100 TEMP_SENSE_ANALOG_MIXCHIP_TEMP -/* + extern PackageHandle ControlFilter; extern PackageHandle HeatersFilter; extern PackageHandle JobFilter ; @@ -415,6 +415,6 @@ extern PackageHandle FPGAFilter; extern PackageHandle LoadFilter; extern PackageHandle InitFilter; extern PackageHandle MaintFilter; -*/ + #endif /* DATADEF_H */ diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c index 342a9d759..a268ad0d5 100644 --- a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c +++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c @@ -842,13 +842,13 @@ uint8_t Pannel_Leds(PANEL_BUTTON_OR_CRAT_ID Pannel_Led_Id, OPERATION_MODE LED_Mo Machine_Idle_Mode = false; break; case THREAD_JOGGING: - F3_low_var_LED2 = Low_Reg; - F3_high_var_LED2 = High_Reg; - break; - case THREAD_LOAD: F3_low_var_LED3 = Low_Reg; F3_high_var_LED3 = High_Reg; break; + case THREAD_LOAD: + F3_low_var_LED2 = Low_Reg; + F3_high_var_LED2 = High_Reg; + break; case CART_1: F3_LOw_Cart_Led1 = Low_Reg; F3_High_Cart_Led1 = High_Reg; diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c index ea5161b15..26f6d5c56 100644 --- a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c +++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c @@ -796,7 +796,7 @@ void FPGA_SetMotMicroStep(TimerMotors_t _motorId)// for (i = 0; i < 8; i++) { - if (MotorsCfg[_motorId].microstep == MultiStep[i]) + if (MotorDriverRequest[_motorId].microstep == MultiStep[i]) { good = i; break; @@ -931,8 +931,73 @@ void FPGA_SetMotStop(TimerMotors_t _motorId) // FPGA_SPI_Transnit(_motorId); } +void FPGA_SetMotKvalHold(TimerMotors_t _motorId) +{ + uint32_t temp; + + temp = x_SET_PARAM | x_KVAL_HOLD; + temp = temp << 24; + + if((MotorDriverResponse[_motorId].DriverType == CurrentMotDriver) && (MotorDriverRequest[_motorId].KvalHold > 0x7F)) + MotorDriverRequest[_motorId].KvalHold = 0x7F; + + temp |= MotorDriverRequest[_motorId].KvalHold<<16; + Fpga_Spi[_motorId].TX_MOSI = temp; + Fpga_Spi[_motorId].AMT_OF_Words = 4; + FPGA_SPI_Transnit(_motorId); +} +void FPGA_SetMotKvalRun(TimerMotors_t _motorId) +{ + uint32_t temp; + + temp = x_SET_PARAM | x_KVAL_RUN; + temp = temp << 24; + + if((MotorDriverResponse[_motorId].DriverType == CurrentMotDriver) && (MotorDriverRequest[_motorId].KvalRun > 0x7F)) + MotorDriverRequest[_motorId].KvalRun = 0x7F; + + temp |= MotorDriverRequest[_motorId].KvalRun<<16; + + Fpga_Spi[_motorId].TX_MOSI = temp; + Fpga_Spi[_motorId].AMT_OF_Words = 4; + FPGA_SPI_Transnit(_motorId); +} + +void FPGA_SetMotKvalAcc(TimerMotors_t _motorId) +{ + uint32_t temp; + + temp = x_SET_PARAM | x_KVAL_ACC; + temp = temp << 24; + + if((MotorDriverResponse[_motorId].DriverType == CurrentMotDriver) && (MotorDriverRequest[_motorId].KvalAcc > 0x7F)) + MotorDriverRequest[_motorId].KvalAcc = 0x7F; + + temp |= MotorDriverRequest[_motorId].KvalAcc<<16; + + Fpga_Spi[_motorId].TX_MOSI = temp; + Fpga_Spi[_motorId].AMT_OF_Words = 4; + FPGA_SPI_Transnit(_motorId); +} + +void FPGA_SetMotKvalDec(TimerMotors_t _motorId) +{ + uint32_t temp; + + temp = x_SET_PARAM | x_KVAL_DEC; + temp = temp << 24; + + if((MotorDriverResponse[_motorId].DriverType == CurrentMotDriver) && (MotorDriverRequest[_motorId].KvalDec > 0x7F)) + MotorDriverRequest[_motorId].KvalDec = 0x7F; + + temp |= MotorDriverRequest[_motorId].KvalDec<<16; + + Fpga_Spi[_motorId].TX_MOSI = temp; + Fpga_Spi[_motorId].AMT_OF_Words = 4; + FPGA_SPI_Transnit(_motorId); +} /////////////////////////////////////////////////////////////////////////////// /* diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.h b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.h index cc9d85cca..e2937e597 100644 --- a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.h +++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.h @@ -27,6 +27,11 @@ void FPGA_SetMotPosition(TimerMotors_t _motorId); void FPGA_SetMotSpeed(TimerMotors_t _motorId); void FPGA_SetMotSpeedDirect(TimerMotors_t _motorId); +void FPGA_SetMotKvalHold(TimerMotors_t _motorId); +void FPGA_SetMotKvalRun(TimerMotors_t _motorId); +void FPGA_SetMotKvalAcc(TimerMotors_t _motorId); +void FPGA_SetMotKvalDec(TimerMotors_t _motorId); + void FPGA_SetMotorsInit(); uint32_t FPGA_MotorConfig(TimerMotors_t _motorId, MotorDriverConfigStruc *MotorConfig); diff --git a/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.c b/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.c index b921a883c..106e60316 100644 --- a/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.c +++ b/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.c @@ -344,13 +344,42 @@ uint32_t MotorSetMaxSpeed(TimerMotors_t _motorId, uint32_t MaxSpeed) uint32_t MotorSetMicroStep(TimerMotors_t _motorId, uint32_t microstep) { - MotorsCfg[_motorId].microstep = microstep; + MotorDriverRequest[_motorId].microstep = microstep; FPGA_SetMotMicroStep(_motorId); return OK; } +uint32_t MotorSetKvalHold(TimerMotors_t _motorId, uint8_t Value) +{ + MotorDriverRequest[_motorId].KvalHold = Value; + FPGA_SetMotKvalHold(_motorId); + + return OK; +} +uint32_t MotorSetKvalRun(TimerMotors_t _motorId, uint8_t Value) +{ + MotorDriverRequest[_motorId].KvalRun = Value; + FPGA_SetMotKvalRun(_motorId); + return OK; +} + +uint32_t MotorSetKvalAcc(TimerMotors_t _motorId, uint8_t Value) +{ + MotorDriverRequest[_motorId].KvalAcc = Value; + FPGA_SetMotKvalAcc(_motorId); + + return OK; +} + +uint32_t MotorSetKvalDec(TimerMotors_t _motorId, uint8_t Value) +{ + MotorDriverRequest[_motorId].KvalDec = Value; + FPGA_SetMotKvalDec(_motorId); + + return OK; +} uint32_t MotorMove(TimerMotors_t _motorId,bool direction, uint32_t Steps) { diff --git a/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.h b/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.h index ecc70765b..3b9eba3d8 100644 --- a/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.h +++ b/Software/Embedded_SW/Embedded/Drivers/Motors/Motor.h @@ -86,6 +86,11 @@ typedef struct uint32_t Speed; uint32_t Position; uint8_t Stop; + uint8_t KvalHold; + uint8_t KvalRun; + uint8_t KvalAcc; + uint8_t KvalDec; + int32_t microstep; }MotorDriverRequestStruct; typedef struct @@ -182,6 +187,11 @@ uint32_t MotorSetSpeedWithCallback (TimerMotors_t _motorId, uint32_t _freq, call uint32_t SetMotHome(TimerMotors_t _motorId); +uint32_t MotorSetKvalHold(TimerMotors_t _motorId, uint8_t Value); +uint32_t MotorSetKvalRun(TimerMotors_t _motorId, uint8_t Value); +uint32_t MotorSetKvalAcc(TimerMotors_t _motorId, uint8_t Value); +uint32_t MotorSetKvalDec(TimerMotors_t _motorId, uint8_t Value); + void MotorActionsInit(void); uint32_t MotorGetStatus(TimerMotors_t _motorId); diff --git a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c index 637c91e7d..ac1cff75e 100644 --- a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c +++ b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c @@ -33,7 +33,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b uint32_t ui32ProgAddr; uint32_t ui32BufferAddr; volatile uint32_t ui32Idx; - uint32_t ui32FlashEnd; + //uint32_t ui32FlashEnd; // @@ -41,7 +41,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b // If reserved space is configured, then the ending address is reduced // by the amount of the reserved block. // - ui32FlashEnd = ui32FlashStart + ui32FileSize; + //ui32FlashEnd = ui32FlashStart + ui32FileSize; // @@ -68,7 +68,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b // stick updater). // ui32ProgAddr = ui32FlashStart; - ui32BufferAddr = buffer; + ui32BufferAddr = (uint32_t)buffer; ui32Remaining = ui32FileSize; while(ui32Remaining) { diff --git a/Software/Embedded_SW/Embedded/Main.c b/Software/Embedded_SW/Embedded/Main.c index 2147652e2..046f8291e 100644 --- a/Software/Embedded_SW/Embedded/Main.c +++ b/Software/Embedded_SW/Embedded/Main.c @@ -46,7 +46,7 @@ #include "StateMachines/Printing/PrintingSTM.h" #include "StateMachines/Initialization/InitSequence.h" - +#include "StateMachines/Initialization/PowerIdle.h" #include <Drivers/SSI_Comm/SSI_Comm.h> #include "drivers/SPI/SPI_Comm.h" #include "drivers/Uart_Comm/Uart.h" @@ -245,7 +245,7 @@ int main(void) // HWControlId = AddControlCallback( MainHWInitCallBackFunction, 2* eOneSecond/*eHundredMillisecond*/, MainDummyFunction,0,0, 0 ); Start_InitSequence(); - + PowerIdleInit(); BIOS_start(); diff --git a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c index 7c0f9a6c1..81c4a230b 100644 --- a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c +++ b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c @@ -337,7 +337,7 @@ const AlarmHandlingItemStruc HardCodedAlarmItem[MAX_SYSTEM_ALARMS]={ char AlarmStorePath[25] ="0://SysInfo//AlarmPrm.cfg"; -bool DispenserInUse[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; +//bool DispenserInUse[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; bool EventsNotificationRequestAccepted = false; //read dispensers limit switches. 25 - send warning. up - stop job and send alarm //Cone missing @@ -471,7 +471,7 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever MotorStop(HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1+Disp_i,Hard_Hiz); if (JobIsActive()) { - if (DispenserInUse[Disp_i] == false) + if (DispenserUsedInJob[Disp_i] == false) AlarmItem[AlarmId].Severity = DEBUG_LOG_CATEGORY__Info; } } @@ -481,7 +481,7 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever MotorStop(HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1+Disp_i,Hard_Hiz); if (JobIsActive()) { - if (DispenserInUse[Disp_i] == false) + if (DispenserUsedInJob[Disp_i] == false) AlarmItem[AlarmId].Severity = DEBUG_LOG_CATEGORY__Info; } break; @@ -505,24 +505,26 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever } JobEndReasonEnum AlarmHandlingPrepareJob(void *CurrentJob) { - JobTicket* JobTicket = CurrentJob; + //JobTicket* JobTicket = CurrentJob; EventType HeaterEventType[MAX_HEATERS_NUM*2] = {EVENT_TYPE__DRYER_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DRYER_ZONE_2_OVERTEMPERATURE,EVENT_TYPE__DRYER_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_1_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_2_OVERTEMPERATURE, EVENT_TYPE__DYEING_HEAD_ZONE_3_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_4_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_5_OVERTEMPERATURE,EVENT_TYPE__DYEING_HEAD_ZONE_6_OVERTEMPERATURE, EVENT_TYPE__MIXER_OVERTEMPERATURE}; EventType HeaterEventTypeUnder[MAX_HEATERS_NUM*2] = {EVENT_TYPE__DRYER_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DRYER_ZONE_2_UNDERTEMPERATURE_B,EVENT_TYPE__DRYER_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_1_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_2_UNDERTEMPERATURE_B, EVENT_TYPE__DYEING_HEAD_ZONE_3_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_4_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_5_UNDERTEMPERATURE_B,EVENT_TYPE__DYEING_HEAD_ZONE_6_UNDERTEMPERATURE_B, EVENT_TYPE__MIXER_UNDERTEMPERATURE_B}; - int Segment_i,Brush_i,Dispenser_i,DispenserId,Alarm_i,Heater_i,AlarmId=0; + int Dispenser_i,Alarm_i,Heater_i,AlarmId=0; HeaterState HeaterState; - for (Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) - { - DispenserInUse[Dispenser_i] = false; - } + //for (Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) + //{ + // DispenserInUse[Dispenser_i] = false; + //} JobEndReasonEnum status = JOB_OK; - if (JobTicket->n_segments == 0) + IDS_MapDispenserUsedinJob(CurrentJob); + if (n_segments == 0) return OK; - for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) + + /*for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) { for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) { @@ -540,11 +542,12 @@ JobEndReasonEnum AlarmHandlingPrepareJob(void *CurrentJob) }//if dispensers }//for brush }//for segments + */ if (Configured[Module_IDS]) { for (Dispenser_i=0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) { - if (DispenserInUse[Dispenser_i] == true) + if (DispenserUsedInJob[Dispenser_i] == true) { for (Alarm_i = 0;Alarm_i<MAX_SYSTEM_ALARMS;Alarm_i++) { @@ -664,7 +667,6 @@ void AlarmHandlingInternalSetAlarm(uint32_t AlarmId, bool value) { if (AlarmState[Alarm_i].Status != value) { - AlarmState[Alarm_i].Status = value; if (value == true) { // no need to call consequent actionsAlarmHandlingConsequentActions(Alarm_i, AlarmItem[Alarm_i].Severity); @@ -676,12 +678,14 @@ void AlarmHandlingInternalSetAlarm(uint32_t AlarmId, bool value) AlarmState[Alarm_i].EventPtr->has_type = true; AlarmState[Alarm_i].EventPtr->type = AlarmItem[Alarm_i].EventType; AlarmState[Alarm_i].EventPtr->message = AlarmItem[Alarm_i].EventName; + AlarmState[Alarm_i].Status = value; Report("Alarm ON ", __FILE__,__LINE__,AlarmItem[Alarm_i].EventType, RpMessage, value, Alarm_i); } } else { Report("Alarm OFF ", __FILE__,__LINE__,AlarmItem[Alarm_i].EventType, RpMessage, value, Alarm_i); + AlarmState[Alarm_i].Status = value; if (AlarmState[Alarm_i].EventPtr) my_free(AlarmState[Alarm_i].EventPtr); } @@ -1017,20 +1021,33 @@ void SendEventNotifications(void) response.n_events++; } } - response.events = (Event **)my_malloc(sizeof(Event*)*response.n_events); - if(response.events) + + if (response.n_events) { - for (i = 0;i<MAX_SYSTEM_ALARMS;i++) + response.events = (Event **)my_malloc(sizeof(Event*)*response.n_events); + if(response.events) { - if (AlarmState[i].Status == true) + for (i = 0;i<MAX_SYSTEM_ALARMS;i++) { - if (AlarmState[i].EventPtr) + if (AlarmState[i].Status == true) { - response.events[e]=AlarmState[i].EventPtr; - e++; + if (AlarmState[i].EventPtr) + { + response.events[e]=AlarmState[i].EventPtr; + e++; + } } } } + else + { + LOG_ERROR(response.n_events,"events malloc error"); + return; + } + } + else + { + response.events = NULL; } responseContainer = createAllocatedContainer(MESSAGE_TYPE__StartEventsNotificationResponse, AlarmHandlingToken, false, &response, &start_events_notification_response__pack, &start_events_notification_response__get_packed_size,&alarm_response_buffer); responseContainer.continuous = true; diff --git a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c index 738f59686..d34ac9ff9 100644 --- a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c +++ b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c @@ -484,6 +484,7 @@ uint32_t MillisecLowLoop(uint32_t tick) if (watchdogCriticalAlarm == false) { Control_WD(ENABLE,5); //activate heaters/dispenser watchdog, 0.5 seconds + //LOG_ERROR (1111, "Control_WD"); } } } diff --git a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c index 74f8c8746..f5aec59f6 100644 --- a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c +++ b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c @@ -175,7 +175,7 @@ uint32_t EmbeddedParametersInit(void) LoadConfigurationParameters(Params); DataUpdated=true; free (buffer); - configuration_parameters__free_unpacked(NULL,Params); + configuration_parameters__free_unpacked(Params,NULL); } else { diff --git a/Software/Embedded_SW/Embedded/Modules/General/buttons.c b/Software/Embedded_SW/Embedded/Modules/General/buttons.c index 4befb83ea..21d425221 100644 --- a/Software/Embedded_SW/Embedded/Modules/General/buttons.c +++ b/Software/Embedded_SW/Embedded/Modules/General/buttons.c @@ -13,6 +13,7 @@ #include "Modules/General/buttons.h" #include "StateMachines/Printing/PrintingSTM.h" #include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h" +//#include "StateMachines/Initialization/PowerOffSequence.h" #include <stdlib.h> #include <stdint.h> @@ -22,6 +23,7 @@ #include "Modules/Thread/Thread_ex.h" #include "Modules/General/buttons.h" +#include "StateMachines/Initialization/PowerOffSequence.h" //int MachineOnOff(); int PowerDown(); @@ -67,7 +69,7 @@ uint32_t ButtonJogCallBackFunction(uint32_t IfIndex, uint32_t ReadValue); uint32_t ButtonJogCBFunction(uint32_t IfIndex, uint32_t ReadValue); uint8_t thraedJogging(uint8_t off); uint32_t setJoggingEnableCondition( button *pBtn); -uint32_t joggingMachine(uint8_t OnOffPB, button *pBtn); +uint32_t joggingMachine( button *pBtn); //uint8_t OnOffPB, uint32_t ButtonLoadCallBackFunction(uint32_t IfIndex, uint32_t ReadValue); @@ -86,6 +88,7 @@ bool Read_PWR_Button();//TODO move to GPIO folder int PowerDown() { bool ret = OK; + PowerOffInit(); return ret; } @@ -98,6 +101,51 @@ int PowerUp() } +bool SetPowerMachineState(PBmachineState state) +{ + bool ret = OK; + switch ( state ) + { + case sttOFF: + power.state = state; + break; + case sttON: + power.state = state; + break; + case sttDISABLE: + jog.state = state; + break; + case sttENABLE: + jog.state = state; + break; + case sttIDLE: + power.state = state; + break; + case sttJOGGING: + jog.state = state; + break; + case sttRDY: + load.state = state; + break; + case sttPRELOAD: + load.state = state; + break; + case sttLOADING: + load.state = state; + break; + case sttLOADSUCSESS: + load.state = state; + break; + case sttLOADFAIL: + load.state = state; + break; + default: + break; + } + + + return ret; +} /* * read GPIO status * port: GPIO_PORTN_BASE @@ -145,17 +193,17 @@ uint32_t Buttons_Init(void) // power.bttn_status = 0 ; // power.bttn_name = "power"; //option - power.bttn_status = 0; // 0=release 1=press + power.bttn_status = release; // 0=release 1=press power.Action = OFFPB ; //off,short,long,count,replong - power.color = colorOFF; //off, blue, blink, bithing - power.state = sttOFF; //sttOFF, sttON, sttDISABLE, sttENABLE, sttIDLE, sttJOGGING + power.color = BLUE; //off, blue, blink, bithing + power.state = sttON; //sttOFF, sttON, sttDISABLE, sttENABLE, sttIDLE, sttJOGGING power.count = 0; AddControlCallback( ButtonPowerCBFunction, BUTTOMS_SAMPLE_TIME, ButtonPowerCallBackFunction, 0,0,0 ); // eFiftyMillisecond // jog.bttn_status = 0 ; // jog.bttn_name = "jog"; //option - jog.bttn_status = 0; // 0=release 1=press + jog.bttn_status = release; // 0=release 1=press jog.Action = OFFPB ; //OFFPB,short,long,count,replong jog.color = colorOFF; //colorOFF, BLUE, BLINK, jog.state = sttOFF; // sttDISABLE, sttENABLE, sttJOGGING @@ -164,7 +212,7 @@ uint32_t Buttons_Init(void) // load.bttn_status = 0 ; // load.bttn_name = "load"; //option - load.bttn_status = 0; // 0=release 1=press + load.bttn_status = release; // 0=release 1=press load.Action = OFFPB ; //OFFPB,short,long,count,replong load.color = colorOFF; //colorOFF, BLUE, BLINK, load.state = sttOFF; // sttDISABLE, sttENABLE, sttJOGGING @@ -184,8 +232,15 @@ uint32_t ButtonPowerCBFunction(uint32_t IfIndex, uint32_t ReadValue) uint32_t ButtonJogCBFunction(uint32_t IfIndex, uint32_t ReadValue) { - setJoggingEnableCondition(&jog); - joggingMachine(ReadValue, &jog); + + jog.bttn_status = ReadValue; + //if (ReadValue == press) + { + setJoggingEnableCondition(&jog); + joggingMachine(&jog); + } + + return 0; } @@ -193,8 +248,16 @@ uint32_t ButtonJogCBFunction(uint32_t IfIndex, uint32_t ReadValue) uint32_t ButtonLoadCBFunction(uint32_t IfIndex, uint32_t ReadValue) { uint8_t parameter = 2; - REPORT_MSG(parameter," ------------ Start thread loading empty function ----------------- "); - LoadStatMachine(&load); + + if ((load.bttn_status == release) && (ReadValue == press)) + { + REPORT_MSG(parameter," ------------ Start thread loading empty function ----------------- "); + load.bttn_status = press; + LoadStatMachine(&load); + + } + else load.bttn_status = ReadValue; + return 0; } @@ -306,6 +369,7 @@ uint32_t ShortLongOffPB(uint8_t OnOffPB, button *pBtn) uint32_t StateMachine( button *pBtn) //short press(=0)/long press(=1) { uint8_t parameter = 1; + Report(" ------------ StateMachine state action ----------------- ",__FILE__,__LINE__,pBtn->state,RpWarning,pBtn->Action,0); switch (pBtn->state)// sttON/sttOFF/sttIDLE { @@ -314,6 +378,8 @@ uint32_t StateMachine( button *pBtn) //short press(=0)/long press(=1) { case LONGPB: //Power Down pBtn->state = sttOFF; + pBtn->color = colorOFF; + Pannel_Leds(POWER_ON_OFF,MODE_OFF);//AVI+ PowerDown();// todo REPORT_MSG(parameter," ------------ Power state is OFF ----------------- "); break; @@ -333,6 +399,8 @@ uint32_t StateMachine( button *pBtn) //short press(=0)/long press(=1) case SHORTPB: //powerup? // to do ? pBtn->state = sttON; + pBtn->color = BLUE ; + Pannel_Leds(POWER_ON_OFF,MODE_ON);//AVI+ PowerUp(); //todo REPORT_MSG(parameter," ------------ Power state is ON ----------------- "); break; @@ -345,6 +413,8 @@ uint32_t StateMachine( button *pBtn) //short press(=0)/long press(=1) { case LONGPB: //Power off from idle pBtn->state = sttOFF; + pBtn->color = colorOFF; + Pannel_Leds(POWER_ON_OFF,MODE_OFF);//AVI+ PowerDown(); // todo Pannel_Leds(POWER_ON_OFF,MODE_OFF); //AVI+ - TODO option MODE_ON to stop Breathing and the led will turn off in power down REPORT_MSG(parameter," ------------ Power state is OFF ----------------- "); @@ -395,14 +465,18 @@ uint32_t setJoggingEnableCondition( button *pBtn) ) { pBtn->state = sttDISABLE; - REPORT_MSG(parameter," ------------ Jogging : sttDISABLE ----------------- "); + REPORT_MSG(parameter," ------------ Jogging : setJoggingEnableCondition sttDISABLE ----------------- "); + pBtn->color = colorOFF; + Pannel_Leds(THREAD_JOGGING, MODE_OFF); //AVI+ // ThreadAbortJoggingFunc(); } else { pBtn->state = sttENABLE; - REPORT_MSG(parameter," ------------ Jogging : sttENABLE ----------------- "); +// REPORT_MSG(parameter," ------------ Jogging : setJoggingEnableCondition sttENABLE ----------------- "); + pBtn->color = BLUE; + Pannel_Leds(THREAD_JOGGING, MODE_ON); //AVI+ //ThreadJoggingFunc(40); } @@ -422,7 +496,7 @@ return 0; */ -uint32_t joggingMachine(uint8_t OnOffPB, button *pBtn) +uint32_t joggingMachine( button *pBtn) //uint8_t OnOffPB, { uint8_t parameter = 4; @@ -430,26 +504,66 @@ uint32_t joggingMachine(uint8_t OnOffPB, button *pBtn) if (sttDISABLE == pBtn->state) { // jogging is disable - REPORT_MSG(parameter," ------------ Jogging is Disable ----------------- "); + REPORT_MSG(parameter," ------------joggingMachine: Jogging is Disable ----------------- "); + pBtn->Action = OFFPB; pBtn->color = colorOFF; Pannel_Leds(THREAD_JOGGING,MODE_OFF);//AVI+ } else { - if (!OnOffPB) + if ( (pBtn->Action != OFFPB) && (pBtn->bttn_status == release)) { - REPORT_MSG(parameter," ------------ stop Jogging ----------------- "); + REPORT_MSG(parameter," ------------joggingMachine: Jogging OnOffPB == 00----------------- "); + REPORT_MSG(parameter," ------------joggingMachine: stop Jogging ----------------- "); + pBtn->Action = OFFPB; ThreadAbortJoggingFunc(); // to do!!!! pBtn->color = BLUE; - Pannel_Leds(THREAD_JOGGING,MODE_ON);//AVI+ + Pannel_Leds(THREAD_JOGGING, MODE_ON);//AVI+ } - else + else if ((pBtn->Action == OFFPB) && (pBtn->bttn_status == press)) { - REPORT_MSG(parameter," ------------ start Jogging ----------------- "); + pBtn->Action = LONGPB; + REPORT_MSG(parameter," ------------joggingMachine: Jogging OnOffPB == 1 ----------------- "); + REPORT_MSG(parameter," ------------joggingMachine: start Jogging ----------------- "); pBtn->color = BLINK; ThreadJoggingFunc(40); } +// if (pBtn->bttn_status == press)ThreadJoggingFunc(40); +// else +// { +// pBtn->Action = OFFPB; +// REPORT_MSG(parameter," ??????????????????? joggingMachine: start Jogging ???????????????????"); +// } } + + + +// if (OnOffPB == release) +// { +// REPORT_MSG(parameter," ------------joggingMachine: Jogging OnOffPB == 00----------------- "); +// REPORT_MSG(parameter," ------------joggingMachine: stop Jogging ----------------- "); +// pBtn->Action = OFFPB; +// ThreadAbortJoggingFunc(); // to do!!!! +// pBtn->color = BLUE; +// Pannel_Leds(THREAD_JOGGING, MODE_ON);//AVI+ +// } +// else +// { +// if (pBtn->Action == OFFPB) +// { +// pBtn->Action = LONGPB; +// REPORT_MSG(parameter," ------------joggingMachine: Jogging OnOffPB == 1 ----------------- "); +// REPORT_MSG(parameter," ------------joggingMachine: start Jogging ----------------- "); +// pBtn->color = BLINK; +// ThreadJoggingFunc(40); +// } +// else +// { +// REPORT_MSG(parameter," ??????????????????? joggingMachine: start Jogging ???????????????????"); +// } +// +// } +// } return 0; } @@ -461,9 +575,10 @@ return 0; uint32_t LoadStatMachine( button *pBtn) { - uint8_t parameter = 5; + //uint8_t parameter = 5; - REPORT_MSG(parameter," ------------ start loadong ----------------- "); + //REPORT_MSG(parameter," ------------ start loading ----------------- "); + Report(" ------------ start loading ----------------- ",__FILE__,__LINE__,pBtn->state,RpWarning,pBtn->color,0); switch (pBtn->state) { case sttRDY : @@ -474,12 +589,18 @@ uint32_t LoadStatMachine( button *pBtn) case (REPLONGPB): pBtn->state = sttPRELOAD; pBtn->color = BLINK; + Pannel_Leds(THREAD_LOAD, MODE_ON);//AVI+ if (ThreadLoadStateMachine( THREAD_LOAD_INIT)) - { - pBtn->state = sttPRELOAD ; // to do - pBtn->color = BLUE; - } - else pBtn->state = sttDISABLE ; + { + pBtn->state = sttPRELOAD ; // to do + pBtn->color = BLUE; + Pannel_Leds(THREAD_LOAD, MODE_ON);//AVI+ + } + else + { + pBtn->state = sttDISABLE ; + Pannel_Leds(THREAD_LOAD, MODE_OFF);//AVI+ + } break; default : break; @@ -491,15 +612,19 @@ uint32_t LoadStatMachine( button *pBtn) case (SHORTPB): case (LONGPB): case (REPLONGPB): - if (ThreadLoadStateMachine( THREAD_LOAD_INITIAL_TENSION)) + pBtn->color = BLUE; + Pannel_Leds(THREAD_LOAD, MODE_ON);//AVI+ + if (ThreadLoadStateMachine( THREAD_LOAD_INITIAL_TENSION)) { pBtn->state = sttLOADSUCSESS ; // to do pBtn->color = BLUE; + Pannel_Leds(THREAD_LOAD, MODE_ON);//AVI+ } else { pBtn->state = sttLOADFAIL ; pBtn->color = fastBILNK ; // to do + Pannel_Leds(THREAD_LOAD, MODE_ON);//AVI+ } break; default : @@ -515,6 +640,7 @@ uint32_t LoadStatMachine( button *pBtn) default: //sttDISABLE pBtn->color = colorOFF; + Pannel_Leds(THREAD_LOAD, MODE_OFF);//AVI+ break; } return OK; diff --git a/Software/Embedded_SW/Embedded/Modules/General/buttons.h b/Software/Embedded_SW/Embedded/Modules/General/buttons.h index adf975979..8b064bbcc 100644 --- a/Software/Embedded_SW/Embedded/Modules/General/buttons.h +++ b/Software/Embedded_SW/Embedded/Modules/General/buttons.h @@ -3,6 +3,12 @@ typedef enum { + release = 0, + press +} PB_Status; + +typedef enum +{ colorOFF = 0, BLUE, BLINK, @@ -32,7 +38,7 @@ typedef enum sttLOADING, sttLOADSUCSESS, sttLOADFAIL -} PBmachinState; +} PBmachineState; typedef struct Button { @@ -40,7 +46,7 @@ typedef struct Button int bttn_status; // 0=release 1=press PBstat Action; // enum : offPB,shortPB,longPB,countPB,replongPB PBcolor color; // enum : off, blue, blink, bithing - PBmachinState state; // enum : sttOFF, sttON, sttDISABLE, sttENABLE, sttIDLE, sttJOGGING + PBmachineState state; // enum : sttOFF, sttON, sttDISABLE, sttENABLE, sttIDLE, sttJOGGING uint32_t count; }button; @@ -49,5 +55,9 @@ extern button power , jog, load; uint32_t Buttons_Init(void); uint32_t Button_load_Init(void); uint32_t Button_JOG_Init(void); +bool SetPowerMachineState(PBmachineState state); + + + #endif diff --git a/Software/Embedded_SW/Embedded/Modules/General/process.c b/Software/Embedded_SW/Embedded/Modules/General/process.c index 458bb35f2..277891861 100644 --- a/Software/Embedded_SW/Embedded/Modules/General/process.c +++ b/Software/Embedded_SW/Embedded/Modules/General/process.c @@ -20,6 +20,7 @@ #include "modules/ids/ids_ex.h" #include "third_party/fatfs/src/ffconf.h" #include "Common/SWUpdate/FileSystem.h" +#include "StateMachines/Initialization/PowerIdle.h" @@ -210,6 +211,7 @@ void ProcessRequestFunc(MessageContainer* requestContainer) //REPORT_MSG (ProcessParams->dryerzone1temp,"Process Params Dryer"); + PowerIdleOutOfIdleState(); if (status == 0) status = HandleProcessParameters(ProcessParams); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h index ba08101f8..80a55d63e 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h @@ -5,6 +5,7 @@ #include "drivers/motors/motor.h" #include "ids_ex.h" +extern uint32_t CurrentDispenserSpeed[MAX_SYSTEM_DISPENSERS]; extern uint32_t DispenserIdToMotorId[MAX_SYSTEM_DISPENSERS]; extern float DispenserPressure[MAX_SYSTEM_DISPENSERS]; uint32_t DispenserConfigMessage(HardwareDispenser * request); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c index 0fcd73b59..b33b531a3 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c @@ -238,13 +238,31 @@ void IDS_Dispenser_Content_Init (void) IDS_Dispenser_Data[i].has_nanolitterperpulse = true; } free (buffer); - dispenser_data__free_unpacked(NULL,StoredDispenserData); + dispenser_data__free_unpacked(StoredDispenserData,NULL); } return; //================================== } uint16_t seconds_counter = 0; +uint32_t IDS_Dispenser_Store_Data (void) +{ + FRESULT Status = FR_OK; + IDSDispenserData.n_dispenserinfo = MAX_SYSTEM_DISPENSERS; + IDSDispenserData.dispenserinfo = dispenserdata; + uint8_t* response_buffer = my_malloc(dispenser_data__get_packed_size(&IDSDispenserData)); + size_t response_size = 0; + if (response_buffer) + { + response_size = dispenser_data__pack(&IDSDispenserData, response_buffer); + Status = FileWrite(response_buffer,response_size,DispenserStorePath); + my_free(response_buffer); + } + else + return ERROR; + + return Status; +} void IDS_Dispenser_Content_Calculation (char DispenserId) { assert (DispenserId<MAX_SYSTEM_DISPENSERS); @@ -258,24 +276,12 @@ void IDS_Dispenser_Content_Calculation (char DispenserId) { if (seconds_counter++>=600)//3600) { + seconds_counter = 0; if (IDS_Dispenser_Data[DispenserId].consumedinnanolitter) { REPORT_MSG(IDS_Dispenser_Data[DispenserId].consumedinnanolitter,"Saving Dispenser Data" ); } - seconds_counter = 0; - IDSDispenserData.n_dispenserinfo = MAX_SYSTEM_DISPENSERS; - IDSDispenserData.dispenserinfo = dispenserdata; - uint8_t* response_buffer = my_malloc(dispenser_data__get_packed_size(&IDSDispenserData)); - size_t response_size = 0; - if (response_buffer) - { - response_size = dispenser_data__pack(&IDSDispenserData, response_buffer); - } - - FileWrite(response_buffer,response_size,DispenserStorePath); - my_free(response_buffer); - //dispenser_data__free_unpacked(response_size,NULL); - + IDS_Dispenser_Store_Data(); } } } @@ -285,7 +291,7 @@ void IDS_Dispenser_Set_Flow_Params (char DispenserId,double nanolitterperpulse,c IDS_Dispenser_Data[DispenserId].nanolitterperpulse = nanolitterperpulse; IDS_Dispenser_Data[DispenserId].microsteps = microsteps; IDS_Dispenser_Data[DispenserId].direction = 1; - Report("IDS_Dispenser_Set_Flow_Params",__FILE__,DispenserId,(int)nanolitterperpulse,RpWarning,microsteps,0); + //Report("IDS_Dispenser_Set_Flow_Params",__FILE__,DispenserId,(int)nanolitterperpulse,RpWarning,microsteps,0); } void IDS_Dispenser_RefillStarted (char DispenserId) { @@ -294,7 +300,7 @@ void IDS_Dispenser_RefillStarted (char DispenserId) IDS_Dispenser_Data[DispenserId].nanolitterperpulse = assumedFlow; IDS_Dispenser_Data[DispenserId].microsteps = 1; IDS_Dispenser_Data[DispenserId].direction = 0; - Report("IDS_Dispenser_RefillStarted",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)(assumedFlow*100),0); + //Report("IDS_Dispenser_RefillStarted",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)(assumedFlow*100),0); } void IDS_Dispenser_RefillEnded (char DispenserId) { @@ -302,7 +308,7 @@ void IDS_Dispenser_RefillEnded (char DispenserId) IDS_Dispenser_Data[DispenserId].numberofrefills++; IDS_Dispenser_Data[DispenserId].direction = 1; IDS_Dispenser_Data[DispenserId].consumedinnanolitter = 0; - Report("IDS_Dispenser_RefillEnded",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)IDS_Dispenser_Data[DispenserId].numberofrefills,0); + //Report("IDS_Dispenser_RefillEnded",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)IDS_Dispenser_Data[DispenserId].numberofrefills,0); } void IDS_Dispenser_MovingDirection (char DispenserId, bool direction) { @@ -314,6 +320,6 @@ void IDS_Dispenser_MovingDirection (char DispenserId, bool direction) { IDS_Dispenser_Data[DispenserId].direction = 0; } - Report("IDS_Dispenser_MovingDirection",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)direction,0); + //Report("IDS_Dispenser_MovingDirection",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)direction,0); } diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h index ded3642a0..9b2442698 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h @@ -33,6 +33,8 @@ extern bool EnableLubrication; extern bool EnableIntersegment; extern double IntersegmentLength; +extern bool DispenserUsedInJob[MAX_SYSTEM_DISPENSERS]; +bool IDS_MapDispenserUsedinJob(void *JobDetails); void IDS_ModuleInit (void); void Calculateinit(void); @@ -67,7 +69,9 @@ uint32_t IDS_Dispenser_Close_Valve_And_Stop_Motor(int DispenserId, callback_fptr uint32_t IDS_Dispenser_Start_Motor_and_Open_Valve(int DispenserId, int MotorSpeed, callback_fptr callback); void IDS_Dispenser_Content_Calculation (char DispenserId); +uint32_t IDS_Dispenser_Store_Data (void); +uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails); float CalculateDispenserPressure (int DispenserId); float GetDispenserPressure(int DispenserId); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c index 80db2a4e6..1bdf15b29 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c @@ -147,7 +147,7 @@ uint32_t IDS_HomeDispenser (uint32_t deviceID, uint32_t speed , callback_fptr ca //open dispenser valve dispenser to midtank direction Control3WayValvesWithCallback ((Valves_t)deviceID, MidTank_Dispenser, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer //Valve_Set((Valves_t) request->index, MidTank_Dispenser); - MotorSetMicroStep(deviceID, 1); + MotorSetMicroStep(MotorId, 1); SysCtlDelay(180000); //open dry air valve in the dispenser Valve_Set(IDS_Id_to_AirValve[deviceID], Atm_MidTank_ON); @@ -168,6 +168,7 @@ uint32_t IDS_Dispenser_Alarm_On (uint8_t deviceID) Enable_MidTank_Pressure_Reading(deviceID); status |= MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep); status |= MotorStop(deviceID, Hard_Hiz); + JobEndReason = JOB_OUT_OF_DYE; return status; } uint32_t IDS_Dispenser_Alarm_Off (uint8_t deviceID) @@ -192,7 +193,8 @@ uint32_t IDS_StopHomeDispenser (uint32_t deviceID) Disable_MidTank_Pressure_Reading(deviceID); Valve_Set(IDS_Id_to_AirValve[deviceID], Atm_MidTank_OFF); Control3WayValvesWithCallback ((Valves_t)deviceID, MidTank_Dispenser, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer - MotorSetMicroStep(deviceID, MotorsCfg[deviceID].microstep); + + MotorSetMicroStep(MotorId, MotorsCfg[MotorId].microstep); return OK; } @@ -232,7 +234,7 @@ uint32_t IDS_EmptyDispenser (uint32_t deviceID, uint32_t speed , callback_fptr c //open dispenser valve dispenser to midtank direction Control3WayValvesWithCallback ((Valves_t)deviceID, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer //Valve_Set((Valves_t) request->index, Dispenser_Mixer); - MotorSetMicroStep(deviceID, 1); + MotorSetMicroStep(MotorId, 1); SysCtlDelay(180000); //open dry air valve in the dispenser //Valve_Set(IDS_Id_to_AirValve[deviceID], Atm_MidTank_ON); diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c index 38c139141..2a8cac415 100644 --- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c +++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c @@ -12,10 +12,18 @@ #include "../thread/thread.h" #include "PMR/Hardware/Hardwaremotor.pb-c.h" #include "PMR/Hardware/HardwareDispenser.pb-c.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "PMR/Printing/JobUploadStrategy.pb-c.h" +#include "PMR/Printing/JobSegment.pb-c.h" +#include "PMR/Printing/JobTicket.pb-c.h" #include "StateMachines/Printing/printingSTM.h" #include "drivers/motors/motor.h" #include "drivers/valves/valve.h" +#include "Common/SWUpdate/FileSystem.h" +#include "drivers/Flash_Memory/fatfs/ff.h" + #include "modules/heaters/heaters.h" #include "drivers/Flash_ram/FlashProgram.h" @@ -33,7 +41,8 @@ typedef struct }DispenserControlConfig_t; HardwarePidControl *DispensersControl;// = (HardwarePidControl *)GENHWCFG_MAP_IN_FLASH + 0x4000; #define LUBRICANT_DISPENSER 7 -#define MAX_DYE_DISPENSERS 7 +#define CLEANER_DISPENSER 6 +#define MAX_DYE_DISPENSERS 6 int32_t DispenserSamples[MAX_SYSTEM_DISPENSERS][MAX_CONTROL_SAMPLES] = {0}; int DispenserSamplePointer[MAX_SYSTEM_DISPENSERS] = {0}; double DispenserNormalizedErrorCoEfficient[MAX_SYSTEM_DISPENSERS] = {0}; @@ -45,7 +54,8 @@ bool IDS_Active = false; /******************** STRUCTURES AND ENUMs ********************************************/ uint32_t IDS_Valve_DistanceToSpoolReady(uint32_t deviceID, uint32_t ReadValue); uint32_t IDS_Valve_PresegmentReady(uint32_t deviceID, uint32_t ReadValue); -bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId); +uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue); +//bool IDS_isDispenserUsedNextSegment(void *JobDetails,int DispenserId, int SegmentId); /******************** GLOBAL PARAMETERS ********************************************/ DispenserControlConfig_t DispenserControlConfig[MAX_SYSTEM_DISPENSERS]; uint32_t ControlIdtoDispenserId [MAX_SYSTEM_DISPENSERS] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; @@ -56,6 +66,18 @@ bool DispenserDistanceToSpoolReady[MAX_SYSTEM_DISPENSERS] = {true,true,t bool DispenserUsedInJob[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; bool DispensersAlarmState[ MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false}; int JobBrushStopId = 0; +int lInterSegmentLength = 0; + int InterSegmentStepsLimit = 0,InterSegmentStepsCount = 0; + uint32_t InterSegmentStartSprayCleaner; + uint32_t InterSegmentStartRocking; + uint32_t InterSegmentCenterRockers; + uint32_t InterSegmentStartWFCFDispensers; + bool EnableCleaning = true; + + + uint32_t DispenserPreSegmentControlId = 0xFF; + uint32_t BrushStopControlId = 0xFF; + uint32_t PreSegmentControlId = 0xFF; uint32_t IDS_DispenserControlInit() { @@ -122,7 +144,7 @@ void DispenserPrepareReady(void) return; //not all configured Dispensers are ready } } - REPORT_MSG(Module_IDS,"DispenserPrepareReady"); + REPORT_MSG(Module_IDS,"All Dispensers Prepare Ready"); PrepareReady(Module_IDS,ModuleDone); } //******************************************************************************************************************** @@ -137,45 +159,306 @@ void DispenserPrepareReady(void) return OK; // all configured heaters are ready } - bool IDS_MapDispenserUsedinJob(void *JobDetails) +/* + void OpenJobFile(); +void CloseJobFile(); +JobDescriptionFileSegment *GetNextSegmentFromJobFile(); +void FreeSegmentFileData(JobDescriptionFileSegment *Segment); +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile(); +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop); + + */ + /************************************************************************************************************************************/ + uint32_t IDS_MapDispenserUsedinFileJobshort(void *JobDetails) { JobTicket* JobTicket = JobDetails; - int Dispenser_i, Segment_i,Brush_i,DispenserId; + JobDescriptionFileBrushStop *BrushStop; + JobDescriptionFileSegment *Segment; + int Dispenser_i, Brush_i,DispenserId; + FRESULT Fresult = FR_OK; + uint32_t status = OK; for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) { DispenserUsedInJob[Dispenser_i] = false; } - if (JobTicket->n_segments == 0) - return false; + if (EnableCleaning == true) + DispenserUsedInJob[CLEANER_DISPENSER] = true; + if (JobTicket->enablelubrication == true) + DispenserUsedInJob[LUBRICANT_DISPENSER] = true; - for (Segment_i=0;Segment_i<JobTicket->n_segments;Segment_i++) + Fresult = OpenJobFile(); + if (Fresult == FR_OK) + { + Segment = GetNextSegmentFromJobFile(); + while(Segment) { - for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) + if ((Segment->has_brushstopscount)&&(Segment->brushstopscount)) { - if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers) + for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++) { - for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++) + BrushStop = GetNextBrushStopFromJobFile(); + if (BrushStop) { - //prepare the SW structures - DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index; - if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + if (BrushStop->n_dispensers) { - DispenserUsedInJob[DispenserId] = true; - if(DispenserId == LUBRICANT_DISPENSER) + for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++) { - lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ - JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; - REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + //prepare the SW structures + DispenserId = BrushStop->dispensers[Dispenser_i]->index; + if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + /*if(DispenserId == LUBRICANT_DISPENSER) + { + lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ + JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; + REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + }*/ + } + }//for dispenser + }//if dispensers + else + { + LOG_ERROR (BrushStop->index, "no dispensers in brushstop"); + } + FreeBrushStopFileData(BrushStop); + BrushStop = NULL; + } + else + { + LOG_ERROR (BrushStop, "malloc error"); + status = ERROR; + } + }//for brushstops + }// if brush stop count + FreeSegmentFileData(Segment); + Segment = GetNextSegmentFromJobFile(); + } + FreeSegmentFileData(Segment); + CloseJobFile(); + } + return status; + + } + /************************************************************************************************************************************/ + uint32_t IDS_MapDispenserUsedinFileJob(void *JobDetails) + { + JobTicket* JobTicket = JobDetails; + uint8_t *SegmentPtr = 0, *BrushStopPtr = 0; + JobDescriptionFileBrushStop *BrushStop; + JobDescriptionFileSegment *Segment; + int Dispenser_i, Brush_i,DispenserId; + uint32_t Bytes = 0,readBytes = 0,ImmediateRead = 0,SegmentSize = 0,BrushStopSize = 0; + uint32_t status = OK; + FRESULT Fresult = FR_OK; + FIL *FileHandle = 0; //the system supports a single active file + +/* + Parsing the job description file. +The job description file simply contains an array of segments and their brush stops. +The job description file is meant to be read brush stop by brush stop while the job is in progress. +The following diagram represents a single job description file segment structure. +The process of reading the whole file is simply repeating that reading order. + +Each JobDescriptionFileSegment contains a “BrushStopsCount” field that should be used to determine how many brush stops are associated +with the current segment and how many times the process of reading brush stops should be repeated. +1. 32bit integer containing the next JobFileDescriptionSegment message byte count +2. JobDescriptionFileSegment message +3. 32bit integer containing the next JobDescriptionFileBrushStop message byte count +4. JobDescriptionFileBrushStop message + +1. Read segment message length. +2. Read segment message. +a. Read brush stop message length. +b. Read brush stop message. +c. Go to step 2.a x Segment.BrushStopsCount. +3. Go to step 1 until end of file. + */ + for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) + { + DispenserUsedInJob[Dispenser_i] = false; + } + n_segments = 0; + if (EnableCleaning == true) + DispenserUsedInJob[CLEANER_DISPENSER] = true; + if (JobTicket->enablelubrication == true) + DispenserUsedInJob[LUBRICANT_DISPENSER] = true; + if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + FileHandle = my_malloc(sizeof(FIL)); + + Fresult = FileOpen(JobTicket->jobdescriptionfile, &Bytes, FileHandle); + if (Fresult == FR_OK) + { + while((readBytes < Bytes)&&(status == OK)) + { + Fresult = f_read(FileHandle,&SegmentSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + SegmentPtr = my_malloc (SegmentSize); + if (SegmentPtr) + { + Fresult = f_read(FileHandle,SegmentPtr,SegmentSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + n_segments++; + Segment = job_description_file_segment__unpack(NULL, SegmentSize, SegmentPtr); + if ((Segment->has_brushstopscount)&&(Segment->brushstopscount)) + { + REPORT_MSG (Segment->brushstopscount, "Segment->brushstopscount"); + for (Brush_i=0;Brush_i<Segment->brushstopscount;Brush_i++) + { + if (status == ERROR) + break; + Fresult = f_read(FileHandle,&BrushStopSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + BrushStopPtr = my_malloc (BrushStopSize); + if (BrushStopPtr) + { + Fresult = f_read(FileHandle,BrushStopPtr,BrushStopSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readBytes += ImmediateRead; + BrushStop = job_description_file_brush_stop__unpack(NULL, BrushStopSize, BrushStopPtr); + REPORT_MSG (BrushStopSize, "BrushStop"); + if (BrushStop->n_dispensers) + { + for (Dispenser_i = 0;Dispenser_i < BrushStop->n_dispensers;Dispenser_i++) + { + //prepare the SW structures + DispenserId = BrushStop->dispensers[Dispenser_i]->index; + if (BrushStop->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + } + }//for dispenser + }//if dispensers + else + { + LOG_ERROR (BrushStop->index, "no dispensers in brushstop"); + } + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + BrushStop = NULL; + } //read brush stop data + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + my_free(BrushStopPtr); + BrushStopPtr = NULL; + }//brushstop malloc ok + else + { + LOG_ERROR (BrushStopPtr, "malloc error"); + status = ERROR; + } + }//brushstop size read ok + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + }//for brushstops + }// if brush stop count + else + { + LOG_ERROR (0, "no brushstops error"); + status = ERROR; } + job_description_file_segment__free_unpacked(Segment,NULL); + Segment = NULL; + }// read segment data + my_free(SegmentPtr); + SegmentPtr = NULL; + Task_sleep(10); + }//segment malloc + else + { + LOG_ERROR (SegmentPtr, "malloc error"); + status = ERROR; + } + }//segment read size + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + }//while(readBytes < Bytes) + } + else + { + LOG_ERROR (Fresult, "FileOpen error"); + status = ERROR; + } + }//file job - } - }//for dispenser - }//if dispensers - }//for brush - }//for segments + if (SegmentPtr) + my_free(SegmentPtr); + if (BrushStopPtr) + my_free(BrushStopPtr); + if (Segment != NULL) + job_description_file_segment__free_unpacked(Segment,NULL); + if (BrushStop != NULL) + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + Fresult = f_close(FileHandle); + REPORT_MSG (n_segments, "Finished checking the file"); + return status; + + } +/************************************************************************************************************************************/ + bool IDS_MapDispenserUsedinJob(void *JobDetails) + { + JobTicket* JobTicket = JobDetails; + int Dispenser_i, Segment_i,Brush_i,DispenserId; + + if (JobTicket->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + return (IDS_MapDispenserUsedinFileJob(JobDetails)); + //return (IDS_MapDispenserUsedinFileJobshort(JobDetails)); + } + else + { + for (Dispenser_i = 0;Dispenser_i<MAX_SYSTEM_DISPENSERS;Dispenser_i++) + { + DispenserUsedInJob[Dispenser_i] = false; + } + if (n_segments == 0) + return false; + + for (Segment_i=0;Segment_i<n_segments;Segment_i++) + { + for (Brush_i=0;Brush_i<JobTicket->segments[Segment_i]->n_brushstops;Brush_i++) + { + if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers) + { + for (Dispenser_i = 0;Dispenser_i < JobTicket->segments[Segment_i]->brushstops[Brush_i]->n_dispensers;Dispenser_i++) + { + //prepare the SW structures + DispenserId = JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->index; + if (JobTicket->segments[Segment_i]->brushstops[Brush_i]->dispensers[Dispenser_i]->nanolitterpersecond>0.0) + { + DispenserUsedInJob[DispenserId] = true; + if(DispenserId == LUBRICANT_DISPENSER) + { + lubricant_speed = JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond/ + JobTicket->segments[0]->brushstops[0]->dispensers[Dispenser_i]->nanoliterperpulse; + REPORT_MSG (lubricant_speed*100, "LUBRICANT_SPEED*100"); + } - return false; + } + }//for dispenser + }//if dispensers + }//for brush + }//for segments + } + + return true; } @@ -214,47 +497,26 @@ void DispenserPrepareReady(void) //ValveCommand (Enable,MixerDirection); } //set 3 dancers to the profile positions - IDS_MapDispenserUsedinJob(JobDetails); + //IDS_MapDispenserUsedinJob(JobDetails); for (i = 0; i < MAX_SYSTEM_DISPENSERS; i++) { if (DispenserUsedInJob[i] == true) //we actually should check for all dispensers { + IDS_StopHomeDispenser(i); DispenserReady[i] = false; IDS_Dispenser_Build_Pressure(i, IDS_PrepareReady); REPORT_MSG(i,"Dispenser prepare called"); } else + { DispenserReady[i] = true; + IDS_HomeDispenser (i, 1000 , NULL); + } + } DispenserPrepareReady(); return OK; } -bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int SegmentId) -{ - JobSegment* Segment = SegmentDetails; - int Dispenser_i,n_dispensers; - if (Segment->brushstops[0]->n_dispensers) - { - n_dispensers = Segment->brushstops[0]->n_dispensers; - for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) - { - if (DispenserId == Segment->brushstops[0]->dispensers[Dispenser_i]->index) //dispenser is in use next segment - { - if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond>0) - { - return true; - } - else - { - return false; - } - } - } - } - - return false; - -} //******************************************************************************************************************** uint32_t IDS_Valve_PresegmentValveReady(uint32_t deviceID, uint32_t ReadValue) { @@ -280,20 +542,24 @@ bool IDS_isDispenserUsedNextSegment(void *SegmentDetails,int DispenserId, int Se return OK; //not all configured heaters are ready } } - REPORT_MSG(deviceID,"IDS_Valve_Presegment all Ready!!"); + REPORT_MSG(deviceID,"IDS Presegment Ready!!"); PreSegmentReady(Module_IDS,ModuleDone); return OK; // all configured heaters are ready } - int lInterSegmentLength = 0; - int InterSegmentStepsLimit = 0,InterSegmentStepsCount = 0; - int InterSegmentWFCFTime; - uint32_t DispenserPreSegmentControlId = 0xFF; + //******************************************************************************************************************** + JobDescriptionFileBrushStop * FileBrushStop; + char IdsMessage[100]; uint32_t IDSPreSegmentStateCallbackRunner(uint32_t IfIndex, uint32_t ReadValue) { - /* + JobDispenser **Dispensers; + //set the speed only before the first segment, speed is constant accros job + int Dispenser_i,n_dispensers,DispenserId; + TimerMotors_t HW_Motor_Id; + double segmentfirst_speed; +/* IDS Pre-Segment (Inter-Segment) activity 1. Cleaning 2. Build pressure toward the waste valve @@ -313,19 +579,110 @@ This means that for each Pre-segment we must calculate: TW,TU,Tending, This means that for each segment we must calculate: Tx,Ty. */ +/*uint32_t InterSegmentStartSprayCleaner = 500; +uint32_t InterSegmentStartRocking = 1000; +uint32_t InterSegmentCenterRockers = 3000; +uint32_t InterSegmentStartWFCFDispensers = lInterSegmentLength-1500; +uint32_t IDS_Cleaning_Move_Rockers (int LeftRockerSpeed,int RightRockerSpeed); +uint32_t IDS_Cleaning_Center_And_Stop_Rockers (int timeout,callback_fptr callback); +uint32_t IDS_Cleaning_Spray_Cleaning_Solution (int dispenserSpeed,callback_fptr callback); +uint32_t IDS_Cleaning_Stop_Cleaning_Solution (callback_fptr callback); +*/ //InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps - InterSegmentStepsCount++; - if (InterSegmentStepsCount == InterSegmentStepsLimit) + InterSegmentStepsCount+=100; + if (InterSegmentStepsCount == lInterSegmentLength) { - IDS_Valve_PresegmentReady(1,0); + //IDS_Valve_PresegmentReady(1,0); + Report("End of Pre-segment Handling",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); SafeRemoveControlCallback(DispenserPreSegmentControlId,IDSPreSegmentStateCallbackRunner); } + if (EnableCleaning == true) + { + if (InterSegmentStartSprayCleaner == InterSegmentStepsCount) + { + Report("Start Spray Cleaner",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //IDS_Cleaning_Spray_Cleaning_Solution (int dispenserSpeed,callback_fptr callback); + } + if (InterSegmentStartRocking == InterSegmentStepsCount) + { + Report("Start cleaning rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //IDS_Cleaning_Move_Rockers (int LeftRockerSpeed,int RightRockerSpeed); + } + if (InterSegmentCenterRockers == InterSegmentStepsCount) + { + Report("Stop spray and center rockers",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + //IDS_Cleaning_Stop_Cleaning_Solution (callback_fptr callback); + //IDS_Cleaning_Center_And_Stop_Rockers (int timeout,callback_fptr callback); + } + } + if (InterSegmentStartWFCFDispensers == InterSegmentStepsCount) + { + Report("start dispensers at rate * WFCF",__FILE__,__LINE__,InterSegmentStepsCount,RpWarning,(int)lInterSegmentLength,0); + if (FileBrushStop) + { + REPORT_MSG(FileBrushStop->index,"WFCFBrushStopRead Index"); + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + if (n_dispensers) + { + for (Dispenser_i = 0; Dispenser_i < n_dispensers; Dispenser_i++) + { + DispenserId = Dispensers[Dispenser_i]->index; + HW_Motor_Id = DispenserIdToMotorId[DispenserId]; + if (MotorsCfg[HW_Motor_Id].hardwaremotortype + != DispenserIdToMotorId[DispenserId]) + continue; + + //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius) + segmentfirst_speed = Dispensers[Dispenser_i]->nanolitterpersecond + / Dispensers[Dispenser_i]->nanoliterperpulse; + if (Dispensers[Dispenser_i]->dispenserstepdivision + != DISPENSER_STEP_DIVISION__Auto) + { + //MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision); + segmentfirst_speed /= + Dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + Dispensers[Dispenser_i]->dispenserstepdivision); + } + else + { + //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + MotorsCfg[HW_Motor_Id].microstep); + } + if ((int) segmentfirst_speed > 0) + { +#define WFCF 80 + segmentfirst_speed *= (100+WFCF); + segmentfirst_speed /= 100; + DispenserSegmentReady[DispenserId] = false; + //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer + IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId, + segmentfirst_speed, + NULL); usnprintf(IdsMessage, 80, + "WFCF Dispenser %d nl/sec %d nl/pulse %d speed %d", + DispenserId, + (int) Dispensers[Dispenser_i]->nanolitterpersecond, + (int) Dispensers[Dispenser_i]->nanoliterperpulse, + (int) segmentfirst_speed); + //REPORT_MSG(segmentfirst_speed,IdsMessage); + Report(IdsMessage, __FILE__, __LINE__, Dispenser_i, RpWarning, segmentfirst_speed, 0); + SendJobProgress(0.0, 0, false, IdsMessage); + } + } + } + } + //startDispensersAtSegmentSpeed*1=WFCFClenerSpray(speed); + } return OK; } - uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) { JobSegment* Segment = SegmentDetails; + JobDispenser **Dispensers; //set the speed only before the first segment, speed is constant accros job int Dispenser_i,n_dispensers,DispenserId; TimerMotors_t HW_Motor_Id; @@ -339,7 +696,9 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) REPORT_MSG(SegmentId,"IDSPreSegmentState"); if (JobBrushStopId>=Segment->n_brushstops) { - LOG_ERROR(JobBrushStopId,"Error JobBrushStopId"); + LOG_ERROR(Segment->n_brushstops,"Error JobBrushStopId"); + JobEndReason = JOB_OUT_OF_DYE; + PreSegmentReady(Module_IDS,ModuleFail); return ERROR; } @@ -347,148 +706,258 @@ uint32_t IDSPreSegmentState(void *SegmentDetails, int SegmentId) if ((EnableIntersegment == true)&&(IntersegmentLength>0)) { Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste); //if intersegment is defined throw the ink away - lInterSegmentLength = ((IntersegmentLength*100)/dyeingspeed); - InterSegmentStepsLimit = lInterSegmentLength*10;//100 millisec steps - InterSegmentStepsCount = 0; - /*DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 ); - if (DispenserPreSegmentControlId == 0xFF) + if (SegmentId>0) { - Report("Add control callback failed",__FILE__,__LINE__,(int)InterSegmentLength,RpWarning,(int)0,0); - return ERROR; - }*/ + lInterSegmentLength = ((IntersegmentLength*100)*1000/dyeingspeed); + lInterSegmentLength-=(lInterSegmentLength%100); //round to a 100 multiplication + InterSegmentStepsCount = 0; + DispenserPreSegmentControlId = AddControlCallback( IDSPreSegmentStateCallbackRunner, 100,TemplateDataReadCBFunction ,0, 0, 0 ); + if (DispenserPreSegmentControlId == 0xFF) + { + Report("Add control callback failed",__FILE__,__LINE__,(int)100,RpWarning,(int)0,0); + return ERROR; + } + Report("Add control callback ",__FILE__,__LINE__,(int)100,RpWarning,(int)IntersegmentLength,0); + if (EnableCleaning == true) + { + InterSegmentStartSprayCleaner = 500; + InterSegmentStartRocking = 1000; + InterSegmentCenterRockers = 3000; + } + InterSegmentStartWFCFDispensers = lInterSegmentLength-5000; + } } - if (Segment->brushstops[JobBrushStopId]->n_dispensers) + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; + } + else + { + if (BrushStopControlId != 0xFF) + { + RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0xFF; + } + FileBrushStop = GetNextBrushStopFromJobFile(); + if (FileBrushStop) + { + REPORT_MSG(FileBrushStop->index,"BrushStopRead Index"); + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); + JobEndReason = JOB_OUT_OF_DYE; + SegmentReady(Module_IDS,ModuleFail); + } + } + if (n_dispensers) + { for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; - HW_Motor_Id = DispenserIdToMotorId[DispenserId]; - if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser - { - REPORT_MSG(DispenserId,"Dispenser PreSegment not configured"); - continue; - } + DispenserId = Dispensers[Dispenser_i]->index; DispenserPreSegmentReady[DispenserId] = false; } for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; + DispenserId = Dispensers[Dispenser_i]->index; HW_Motor_Id = DispenserIdToMotorId[DispenserId]; if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser { REPORT_MSG(DispenserId,"Dispenser PreSegment not configured"); + DispenserPreSegmentReady[DispenserId] = true; //27/03/19 check if job should be stopped continue; } - REPORT_MSG(DispenserId,"IDS_Valve_Presegment start"); + //REPORT_MSG(DispenserId,"IDS_Valve_Presegment start"); IDS_Dispenser_Set_Flow_Params(DispenserId,0,0); - if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) + if (Dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) { - MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); + MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision); } else { MotorSetMicroStep(HW_Motor_Id, MotorsCfg[HW_Motor_Id].microstep); } + MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves + CurrentDispenserSpeed[DispenserId] = 0; + IDS_Valve_PresegmentReady(DispenserId,0); //27/03/19 to be removed when the presegment handler will be added + //REPORT_MSG(DispenserId,"Dispenser stopped pre Segment"); + } + } + + return OK; +} +//******************************************************************************************************************** + +uint32_t SegmentNumOfBrushStops = 0; +double BrushStopTime = 0; + +void IDS_StartBrushStop(int n_dispensers, JobDispenser** Dispensers) +{ + int Dispenser_i,DispenserId; + TimerMotors_t HW_Motor_Id; + double segmentfirst_speed; + Report("IDS_StartBrushStop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)0,0); + + if (n_dispensers) + { + for (Dispenser_i = 0; Dispenser_i < n_dispensers; Dispenser_i++) + { + DispenserId = Dispensers[Dispenser_i]->index; + HW_Motor_Id = DispenserIdToMotorId[DispenserId]; + if (MotorsCfg[HW_Motor_Id].hardwaremotortype + != DispenserIdToMotorId[DispenserId]) + continue; - if (Segment->brushstops[0]->dispensers[Dispenser_i]->nanolitterpersecond==0) + //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius) + segmentfirst_speed = Dispensers[Dispenser_i]->nanolitterpersecond + / Dispensers[Dispenser_i]->nanoliterperpulse; + if (Dispensers[Dispenser_i]->dispenserstepdivision + != DISPENSER_STEP_DIVISION__Auto) { - MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves - IDS_Valve_PresegmentReady(DispenserId,0); - //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer - //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady); - REPORT_MSG(DispenserId,"Dispenser Not Used Next Segment"); + //MotorSetMicroStep(HW_Motor_Id, Dispensers[Dispenser_i]->dispenserstepdivision); + segmentfirst_speed /= + Dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + Dispensers[Dispenser_i]->dispenserstepdivision); } else { - if (IntersegmentLength&&(SegmentId>0)) //there is an intersegment, stop all the dispensers. otherwise stop only dispensers that are not in use in the next segment. - { - //Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, IDS_Valve_PresegmentValveReady); //direction: MidTank_Dispenser or Dispenser_Mixer - MotorStop(HW_Motor_Id,Hard_Hiz); //26/03/19 test without valves - IDS_Valve_PresegmentReady(DispenserId,0); - //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,IDS_Valve_PresegmentValveReady); - REPORT_MSG(DispenserId,"Dispenser Used Next Segment with intersegment"); - } - else - { - IDS_Valve_PresegmentReady(DispenserId,0); - } - REPORT_MSG(DispenserId,"Dispenser is Used Next Segment"); + //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep + IDS_Dispenser_Set_Flow_Params( + DispenserId, Dispensers[Dispenser_i]->nanoliterperpulse, + MotorsCfg[HW_Motor_Id].microstep); + } + if ((int) segmentfirst_speed > 0) + { + DispenserSegmentReady[DispenserId] = false; + //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer + /*IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId, + segmentfirst_speed, + NULL);*/ + Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer + MotorSetSpeed(HW_Motor_Id, segmentfirst_speed); + CurrentDispenserSpeed[DispenserId] = segmentfirst_speed; + usnprintf(IdsMessage, 80, + "Dispenser %d nl/sec %d nl/pulse %d speed %d", + DispenserId, + (int) Dispensers[Dispenser_i]->nanolitterpersecond, + (int) Dispensers[Dispenser_i]->nanoliterperpulse, + (int) segmentfirst_speed); + //REPORT_MSG(segmentfirst_speed,IdsMessage); + Report(IdsMessage, __FILE__, __LINE__, Dispenser_i, RpWarning, segmentfirst_speed, 0); + SendJobProgress(0.0, 0, false, IdsMessage); + } + else + { + DispenserSegmentReady[DispenserId] = true; + //IDS_Dispenser_Close_Valve_And_Stop_Motor(DispenserId,NULL);*/ + MotorStop(HW_Motor_Id, Hard_Hiz); + CurrentDispenserSpeed[DispenserId] = 0; + Report("inActive dispenser stopped", __FILE__, __LINE__, DispenserId, RpWarning, segmentfirst_speed, 0); } } } +} +uint32_t IDSBrushStopRestartCallback(uint32_t IfIndex, uint32_t readValue) +{ + JobDispenser **Dispensers = NULL; + int n_dispensers = 0; + JobSegment* Segment = (void *)IfIndex; + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) + { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; + n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; + } + else + { + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = GetNextBrushStopFromJobFile(); + if (FileBrushStop) + { + REPORT_MSG(FileBrushStop->index,"BrushStopRead Index"); + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); + JobEndReason = JOB_OUT_OF_DYE; + SegmentReady(Module_IDS,ModuleFail); + } + } + if (n_dispensers) + { + IDS_StartBrushStop(n_dispensers, Dispensers); + } + JobBrushStopId++; + Report("brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0); + if (JobBrushStopId >= SegmentNumOfBrushStops) + { + Report("last brushstop",__FILE__,__LINE__,(int)JobBrushStopId,RpWarning,(int)SegmentNumOfBrushStops,0); + SafeRemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0Xff; + } return OK; } //******************************************************************************************************************** - - uint32_t IDS_Valve_SegmentReady(uint32_t deviceID, uint32_t ReadValue) - { - int i; - DispenserSegmentReady[deviceID] = true; - for (i=0;i<MAX_SYSTEM_DISPENSERS;i++) - { - if (DispenserSegmentReady[i] == false) - { - return OK; //not all configured heaters are ready - } - } - SegmentReady(Module_IDS,ModuleDone); - return OK; // all configured heaters are ready - } - - char IdsMessage[100]; -//******************************************************************************************************************** uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) { JobSegment* Segment = SegmentDetails; - int Dispenser_i,n_dispensers,DispenserId; - TimerMotors_t HW_Motor_Id; - double segmentfirst_speed; + JobDispenser **Dispensers; + int n_dispensers; Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Head); - if (Segment->brushstops[JobBrushStopId]->n_dispensers) + + SegmentNumOfBrushStops = Segment->n_brushstops; + BrushStopTime = Segment->length/SegmentNumOfBrushStops; //brushstop in meters + BrushStopTime = ((BrushStopTime*100)/dyeingspeed);//brushstop in seconds + BrushStopTime *= 1000; //brushstop in millisecond + Report("IDSSegmentState",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)SegmentNumOfBrushStops,0); + if (uploadstrategy == JOB_UPLOAD_STRATEGY__Default) { + Dispensers = Segment->brushstops[JobBrushStopId]->dispensers; n_dispensers = Segment->brushstops[JobBrushStopId]->n_dispensers; - for (Dispenser_i = 0;Dispenser_i < n_dispensers;Dispenser_i++) + } + else + { + if (FileBrushStop) { - DispenserId = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->index; - HW_Motor_Id = DispenserIdToMotorId[DispenserId]; - if (MotorsCfg[HW_Motor_Id].hardwaremotortype != DispenserIdToMotorId[DispenserId])//unconfigured dispenser - continue; - //(Speed*uStep*PPR)/((2*PI*Dispenser_Radius) - segmentfirst_speed = Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond/ - Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse; - if (Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision != DISPENSER_STEP_DIVISION__Auto) - { - //MotorSetMicroStep(HW_Motor_Id, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); - segmentfirst_speed/=Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision; //the dye supply is calculated based on a 1/8 microstep - IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse - , Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->dispenserstepdivision); - } - else - { - //segmentfirst_speed/=MotorsCfg[HW_Motor_Id].microstep; //the dye supply is calculated based on a 1/8 microstep - IDS_Dispenser_Set_Flow_Params ( DispenserId, Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse - ,MotorsCfg[HW_Motor_Id].microstep); - } - if ((int)segmentfirst_speed > 0) - { - DispenserSegmentReady[DispenserId] = false; - //Control3WayValvesWithCallback (DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer - IDS_Dispenser_Start_Motor_and_Open_Valve(DispenserId,segmentfirst_speed,NULL); - usnprintf(IdsMessage, 80, "Dispenser %d nl/sec %d nl/pulse %d speed %d",Dispenser_i,(int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanolitterpersecond, - (int)Segment->brushstops[JobBrushStopId]->dispensers[Dispenser_i]->nanoliterperpulse,(int)segmentfirst_speed); - //REPORT_MSG(segmentfirst_speed,IdsMessage); - Report(IdsMessage,__FILE__,__LINE__,Dispenser_i,RpWarning,segmentfirst_speed,0); - SendJobProgress(0.0,0,false, IdsMessage); - - - } + Dispensers = FileBrushStop->dispensers; + n_dispensers = FileBrushStop->n_dispensers; + } + else + { + LOG_ERROR(FileBrushStop,"BrushStopReadError"); } } + IDS_StartBrushStop(n_dispensers, Dispensers); + JobBrushStopId++; + if ((BrushStopTime)&&(SegmentNumOfBrushStops > 1)) + { + BrushStopControlId = AddControlCallback( IDSBrushStopRestartCallback, BrushStopTime,TemplateDataReadCBFunction ,SegmentDetails, 0, 0 ); + if (BrushStopControlId == 0xFF) + { + Report("Add control callback failed",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)0,0); + return ERROR; + } + Report("Add control callback ",__FILE__,__LINE__,(int)BrushStopTime,RpWarning,(int)n_dispensers,0); + + } + else + { + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = NULL; + } + return OK; } //******************************************************************************************************************** @@ -513,6 +982,7 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) return OK; //not all configured heaters are ready } } + REPORT_MSG(deviceID,"IDS_Valve_DistanceToSpoolReady End called"); DistanceToSpoolReady(Module_IDS,ModuleDone); return OK; // all configured heaters are ready } @@ -542,6 +1012,8 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) //TimerMotors_t HW_Motor_Id = DispenserIdToMotorId[deviceID]; //REPORT_MSG(deviceID,"Dispenser End called"); //MotorStop(HW_Motor_Id,Hard_Hiz); + IDS_HomeDispenser (deviceID, 1000 , NULL); + return OK; } //******************************************************************************************************************** @@ -551,6 +1023,14 @@ uint32_t IDSSegmentState(void *SegmentDetails, int SegmentId) IDS_Active = false; Valve_Set(VALVE_MIXCHIP_WASTECH, Mixer_Waste); REPORT_MSG(0,"Dispenser End Start"); + if (BrushStopControlId != 0xFF) + { + RemoveControlCallback(BrushStopControlId,IDSBrushStopRestartCallback); + BrushStopControlId = 0xFF; + } + if (FileBrushStop) + FreeBrushStopFileData(FileBrushStop); + FileBrushStop = NULL; for ( Dispenser_i = 0;Dispenser_i < MAX_SYSTEM_DISPENSERS;Dispenser_i++) { if (DispenserUsedInJob[Dispenser_i] == true) diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c index 919e84582..d041b648e 100644 --- a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c +++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c @@ -7,6 +7,7 @@ #include "driverlib/gpio.h" #include "Drivers/USB_Communication/USBCDCD.h" +#include "StateMachines/Initialization/PowerOffSequence.h" //#include "graphics_adapter.h" @@ -20,7 +21,7 @@ void Stub_ProgressRequest(MessageContainer* requestContainer) ProgressResponse response = PROGRESS_RESPONSE__INIT; response.has_progress = true; - + PowerOffInit(); int i = 0; for (i = 0; i < request->amount; i++) { diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/ThreadLoad.c b/Software/Embedded_SW/Embedded/Modules/Thread/ThreadLoad.c index 74a07e99c..ab5075ab9 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/ThreadLoad.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/ThreadLoad.c @@ -78,6 +78,13 @@ //RUN MOTOR A FULL CYCLE //RUN A MOTOR NUMBER OF STEPS //RUN CONTROL FOR A SINGLE DANCER + bool ThreadLoadingActive(void) + { + if ((LoadStages > THREAD_LOAD_INIT)&&(LoadStages < THREAD_LOAD_END)) + return true; + else + return false; + } uint32_t Thread_Load_Init(void) { void* buffer = NULL; @@ -200,6 +207,7 @@ } uint8_t CallbackCounter = 0; uint8_t TimeoutsCounter = 0; + uint32_t Thread_Load_HomingCallback(uint32_t MotorId, uint32_t ReadValue) { Report("Thread Load State Machine Callback.",__FILE__,__LINE__,LoadStages,RpMessage,NumberOfDrierLoaderCycles,0); @@ -222,6 +230,13 @@ else { LoadStages++; + if (LoadStages == THREAD_LOAD_LIFT_ROCKERS) + { + MotorSetMicroStep(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].microstep); + MotorSetMicroStep(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].microstep); + MotorSetKvalRun(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].microstep); + MotorSetKvalRun(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].microstep); + } if (LoadStages != THREAD_LOAD_INITIAL_TENSION) //on this stage we should wait for user call { //ThreadLoadStateMachine(LoadStages); @@ -237,9 +252,9 @@ { REPORT_MSG(LoadStages, "Thread Load State Machine step"); CallbackCounter++; - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD].directionthreadwize, 200, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD], Thread_Load_HomingCallback,10000); + MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD].directionthreadwize, 80, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD], Thread_Load_HomingCallback,10000); CallbackCounter++; - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH].directionthreadwize, 200, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH], Thread_Load_HomingCallback,10000); + MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH].directionthreadwize, 80, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH], Thread_Load_HomingCallback,10000); return OK; } uint32_t Thread_Load_Open_Covers(void) @@ -270,10 +285,15 @@ //Machine Is Ready. Send Message, Start Timer To Close Lids, Wait For Operator Response { REPORT_MSG(LoadStages, "Thread Load State Machine step"); + MotorSetMicroStep(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 1); + MotorSetMicroStep(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 1); + MotorSetKvalRun(HARDWARE_MOTOR_TYPE__MOTO_RLOADING, 35); + MotorSetKvalRun(HARDWARE_MOTOR_TYPE__MOTO_LLOADING, 35); + Task_sleep(10); CallbackCounter++; - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize, 300, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_RLOADING], Thread_Load_HomingCallback,12000); + MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_RLOADING,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].directionthreadwize, 50, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_RLOADING], Thread_Load_HomingCallback,25000); CallbackCounter++; - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_LLOADING,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize, 300, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_LLOADING], Thread_Load_HomingCallback,12000); + MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_LLOADING,1-MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_LLOADING].directionthreadwize, 50, Motor_Id_to_LS_IdUp[HARDWARE_MOTOR_TYPE__MOTO_LLOADING], Thread_Load_HomingCallback,25000); return OK; } diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c index d8564963c..1f7836ea5 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_Winder.c @@ -288,7 +288,7 @@ uint32_t Screw100msecDirectionChange(uint32_t deviceID, uint32_t BusyFlag) //Report(TempScrewStr,__FILE__,__LINE__,0,RpWarning,0, 0); //Report(ScrewStr,__FILE__,__LINE__,ScrewCurrentDirection,RpWarning,CalculationDirectionChangeCounter, 0); //REPORT_MSG(temp , "new winder speed"); - Report("new winder speed",__FILE__,ScrewNumberOfSteps,temp,RpWarning,ScrewSpeed,0); +// Report("new winder speed",__FILE__,ScrewNumberOfSteps,temp,RpWarning,ScrewSpeed,0); } /********************************************************************************/ @@ -382,8 +382,8 @@ uint32_t Winder_End(void) CurrentControlledSpeed[SCREW_MOTOR] = 0; ScrewsStopControlTimer(); //move the cart to the edge so the spool can be easily replaced - MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_SCREW,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_SCREW].directionthreadwize, 1000, GPI_LS_SCREW_RIGHT, NULL,0); - + //MotorMovetoLimitSwitch (HARDWARE_MOTOR_TYPE__MOTO_SCREW,MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_SCREW].directionthreadwize, 1000, GPI_LS_SCREW_RIGHT, NULL,0); + MotorStop(HARDWARE_MOTOR_TYPE__MOTO_SCREW,Hard_Hiz); return OK; } void Winder_ScrewHomeLimitSwitchInterrupt(void) diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h index 69ac4b6ad..d7ce917c0 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h @@ -67,9 +67,11 @@ typedef enum THREAD_LOAD_END }THREAD_LOAD_STAGES_ENUM; uint32_t ThreadLoadStateMachine( THREAD_LOAD_STAGES_ENUM ReadValue); +bool ThreadLoadingActive(void); void ThreadLoadPollRequest(MessageContainer* requestContainer); void ThreadLoadRequest(MessageContainer* requestContainer); + #endif diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c index 9f5ece15a..a4208ad25 100644 --- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -83,6 +83,11 @@ void ThreadInterSegmentEnded(void); void ThreadDistanceToSpoolEnded(void); uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue); +bool SegmentState = false; +bool PreSegmentState = false; +bool DTSState = false; +void SendSegmentFail(void); + double KeepNormalizedError = 0; bool ThreadControlActive = false; ////////////////////////Slow Motor State//////////////////////////////////// @@ -128,6 +133,7 @@ uint32_t Poolerinitialpos = 0xFFFF; void ThreadUpdateProcessLength (double length, void *Funcptr) { + REPORT_MSG(length,"ThreadUpdateProcessLength"); CurrentRequestedLength = length*100;//Centimetres CurrentProcessedLength = 0; ProcessedLengthFuncPtr = (ProcessedLengthFunc)Funcptr; @@ -436,7 +442,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) JobEndReason = JOB_THREAD_BREAK; ThreadControlActive = false; SendJobProgress(0.0,0,false, TMessage); - SegmentReady(Module_Thread,ModuleFail); + SendSegmentFail(); //AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true); //EndState(CurrentJob,"ReadBreakSensor Error" ); LOG_ERROR(index, "ReadBreakSensor Error"); @@ -466,7 +472,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue) JobEndReason = JOB_WINDER_DANCER_FAIL+DancerId; SendJobProgress(0.0,0,false, TMessage); //EndState(CurrentJob,TMessage ); - SegmentReady(Module_Thread,ModuleFail); + SendSegmentFail(); /*switch (index) { case POOLER_MOTOR: @@ -711,7 +717,7 @@ void SetOriginMotorSpeed(float process_speed) uint32_t ThreadPreSegmentState(void *SegmentDetails, uint32_t SegmentId) { //set the speed only before the first segment, speed is constant across all job segments and intersegments - JobSegment* Segment = SegmentDetails; + //JobSegment* Segment = SegmentDetails; float process_speed = dyeingspeed; if (dyeingspeed == 0) @@ -750,10 +756,13 @@ uint32_t ThreadPreSegmentState(void *SegmentDetails, uint32_t SegmentId) //set speed for both rocker motors //wait for all motors to get to the required speed (set the target speed for the control to check) //call the job state machine when the thread system is ready - if ((InitialProcess==false) && (EnableIntersegment == true) && (IntersegmentLength >= 1.0)) //fix - avoid intersegment length 0 + if ((InitialProcess==false) && (EnableIntersegment == true)) //&& (IntersegmentLength >= 1.0)) //fix - avoid intersegment length 0 {//add initial presegment and cleaning before first segment ThreadUpdateProcessLength (IntersegmentLength,(void *)ThreadInterSegmentEnded); REPORT_MSG (IntersegmentLength," ThreadPreSegmentState IntersegmentLength"); + SegmentState = false; + PreSegmentState = true; + DTSState = false; } else { @@ -766,6 +775,17 @@ uint32_t ThreadPreSegmentState(void *SegmentDetails, uint32_t SegmentId) return OK; } int REPSegmentId = 0; +void SendSegmentFail(void) +{ + if (SegmentState == true) + SegmentReady(Module_Thread,ModuleFail); + else if (PreSegmentState == true) + PreSegmentReady(Module_Thread,ModuleFail); + else if (DTSState == true) + DistanceToSpoolReady(Module_Thread,ModuleFail); + +} + void ThreadInterSegmentEnded(void) { REPORT_MSG (REPSegmentId,"ThreadInterSegmentEnded"); @@ -792,6 +812,9 @@ uint32_t ThreadSegmentState(void *SegmentDetails, int SegmentId) CurrentSegmentId = SegmentId; REPORT_MSG (seglength," ThreadSegmentState"); ThreadUpdateProcessLength (seglength,(void *)ThreadSegmentEnded); + SegmentState = true; + PreSegmentState = false; + DTSState = false; return OK; } @@ -801,6 +824,9 @@ uint32_t ThreadDistanceToSpoolState(void ) seglength = dryerbufferlength; REPORT_MSG (seglength,"ThreadDistanceToSpoolState"); ThreadUpdateProcessLength (seglength,(void *)ThreadDistanceToSpoolEnded); + SegmentState = false; + PreSegmentState = false; + DTSState = true; return OK; } @@ -816,6 +842,7 @@ char Endstr[150]; Report(Endstr,__FILE__,__LINE__,(int)TotalProcessedLength,RpWarning,(int)PoolerTotalProcessedLength,0); ThreadUpdateProcessLength (0.0,(void *)NULL); + TotalProcessedLength = 0.0; SetOriginMotorSpeed(0); #ifdef HUNDRED_MICROSECONDS_DANCER_READ MillisecLogClose(); diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h b/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h index 66428039f..bda01564f 100644 --- a/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h +++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h @@ -97,7 +97,7 @@ typedef enum U8 WHS_init(void); U8 WHS_HW_test(void); - +bool WHS_IsEmptying(); #endif diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c index 689a2bc95..9531b67d6 100644 --- a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c +++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c @@ -99,7 +99,15 @@ struct WHS_information struct WHS_information WHS_info; - +bool WHS_IsEmptying() +{ + bool ret = false; + if ( WHS_info.sttMachine == WHS_emptying ) + { + ret = true; + } + return ret; +} /* -------- cartridge function ----*/ diff --git a/Software/Embedded_SW/Embedded/Software Release Notes.txt b/Software/Embedded_SW/Embedded/Software Release Notes.txt index 356301dda..d62cee15e 100644 --- a/Software/Embedded_SW/Embedded/Software Release Notes.txt +++ b/Software/Embedded_SW/Embedded/Software Release Notes.txt @@ -1,3 +1,11 @@ +Embedded SW Release note - Version 1.3.8.2 +File upload: prevent on job, reduce priority (watchdog) +Report: packages filters introduced, please feel free to use them. +robustness in communication improved +large number of segments and gradient support - initial +at the end of job the screw does not return back +rockers - adjust values before and after loading the cart + Embedded SW Release note - Version 1.3.8.12 Prepare continous response on sw upgarde - test! Lubrication supported throughout the job - test! diff --git a/Software/Embedded_SW/Embedded/StateMachines/Initialization/InitSequence.c b/Software/Embedded_SW/Embedded/StateMachines/Initialization/InitSequence.c index 017eb2126..64cb99918 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Initialization/InitSequence.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Initialization/InitSequence.c @@ -23,6 +23,8 @@ #include "InitSequence.h" #include "drivers/I2C_Communication/DAC/Blower.h" +#include "drivers/I2C_Communication/ADC_MUX/ADC_MUX.h" +#include "drivers/Valves/Valve.h" #include "heaters/heaters_ex.h" @@ -38,7 +40,7 @@ INIT_SEQUENCE_MACHINE_READY_TO_DYE, INIT_SEQUENCE_END, }INIT_SEQUENCE_STAGES_ENUM; - INIT_SEQUENCE_STAGES_ENUM InitStages = INIT_SEQUENCE_INIT; + INIT_SEQUENCE_STAGES_ENUM InitStages = INIT_SEQUENCE_INIT, StoredInitStages = INIT_SEQUENCE_INIT; MACHINE_STATE_STAGES_ENUM MachineState = MACHINE_STATE_INIT; MACHINE_STATE_STAGES_ENUM GetMachineState(void) @@ -49,7 +51,9 @@ void SetMachineState(MACHINE_STATE_STAGES_ENUM NewState) { MachineState = NewState; } -uint32_t HWControlId; +uint32_t HWControlId,InitSchedulerControlId; +uint32_t MidTankControlId; + uint32_t RESET_Cause = 0; void InitSequenceResetReason(void); @@ -72,7 +76,7 @@ uint32_t InitSequenceCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) { ActivateHeadMagnet(); InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); } else { @@ -81,11 +85,23 @@ uint32_t InitSequenceCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) } return OK; } +/*******************************************************************************************************/ +uint32_t InitScheduler(uint32_t IfIndex, uint32_t BusyFlag) +{ + if (InitStages > StoredInitStages) + { + StoredInitStages = InitStages; + InitSequenceStateMachine(InitStages); + } + return OK; +} +/*******************************************************************************************************/ uint32_t Start_InitSequence(void) { MachineState = MACHINE_STATE_HW_CONFIG; HWControlId = AddControlCallback( InitSequenceCallBackFunction, 4* eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); + InitSchedulerControlId = AddControlCallback( InitScheduler, eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); return OK; } void InitSequenceResetReason(void) @@ -104,7 +120,7 @@ void InitSequenceResetReason(void) LOG_ERROR(RESET_Cause,"Reset Reason Register"); SysCtlResetCauseClear(RESET_Cause); InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); //return OK; } @@ -113,7 +129,7 @@ void InitSequenceBuiltInTestCallBack(uint32_t IfIndex, uint32_t BusyFlag) if (1)//BIT OK { InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); } else { @@ -127,6 +143,44 @@ uint32_t InitSequenceBuiltInTest(void) InitSequenceBuiltInTestCallBack(0,0); return OK; } +int MidTankOperationCounter = 0; +uint32_t InitSequenceMidTankCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) +{ + int MidTankOpenAir = 8; + int MidTankReadPressure = 16; + int MidTankCloseAir = 24; + int MidTankEnd = 32; + int portId; + + if (MidTankOperationCounter >= MidTankEnd) + { + SafeRemoveControlCallback(MidTankControlId, InitSequenceMidTankCallBackFunction); + } + else if (MidTankOperationCounter >= MidTankCloseAir) + { + //close air valve for midtank (MidTankOperationCounter-MidTankCloseAir) + portId = (MidTankOperationCounter - MidTankCloseAir) ; //0-7 + Disable_MidTank_Pressure_Reading(portId); + Valve_Set(IDS_Id_to_AirValve[portId], Atm_MidTank_OFF ); //Atm_MidTank_OFF/ON + } + else if (MidTankOperationCounter >= MidTankReadPressure) + { + //read pressure for midtank (MidTankOperationCounter-MidTankCloseAir) + for (portId = 0;portId < MAX_SYSTEM_DISPENSERS;portId++) + { + Read_MidTank_Pressure_Sensor(portId); + } + } + else if (MidTankOperationCounter >= MidTankOpenAir) + { + //open air valve for midtank (MidTankOperationCounter-MidTankOpenAir) + portId = (MidTankOperationCounter - MidTankOpenAir) ; //0-7 + Enable_MidTank_Pressure_Reading(portId); + Valve_Set(IDS_Id_to_AirValve[portId], Atm_MidTank_ON ); //Atm_MidTank_OFF/ON + } + MidTankOperationCounter++; + return OK; +} uint32_t InitSequenceBlowerCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) { if (SafeRemoveControlCallback(HWControlId, InitSequenceBlowerCallBackFunction )==OK) @@ -137,7 +191,7 @@ uint32_t InitSequenceBlowerCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) Control_Voltage_To_Blower(BlowerCfg.heatingvoltage); Safety_Init(); InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); return OK; } uint32_t InitSequenceInitialBlowerActivation(void) @@ -150,6 +204,8 @@ uint32_t InitSequenceInitialBlowerActivation(void) Control_Voltage_To_Blower(BlowerCfg.voltage); HWControlId = AddControlCallback( InitSequenceBlowerCallBackFunction, 10* eOneSecond/*eHundredMillisecond*/, TemplateDataReadCBFunction,0,0, 0 ); } + MidTankControlId = AddControlCallback( InitSequenceMidTankCallBackFunction, 300/*eHundredMillisecond*/, TemplateDataReadCBFunction,0,0, 0 ); + return OK; } int NumOfCheckedDispnsers = 0; @@ -159,7 +215,7 @@ uint32_t InitSequenceDispenserPressureBuildUpTestCallBackFunction(uint32_t IfInd if(NumOfCheckedDispnsers==0) { InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); MachineState = MACHINE_STATE_DISPENSER_PRESSURE_BUILDUP_TEST; } @@ -187,7 +243,7 @@ uint32_t InitSequenceThreadDetection(void) { InitStages++; MachineState = MACHINE_STATE_THREAD_DETECTION; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); return OK; } @@ -201,7 +257,7 @@ uint32_t InitSequenceStartHeatingCallBackFunction(uint32_t IfIndex, uint32_t Bus else Report("Remove control callback failed",__FILE__,__LINE__,(int)HWControlId,RpWarning,(int)InitSequenceStartHeatingCallBackFunction,0); InitStages++; - InitSequenceStateMachine(InitStages); + //InitSequenceStateMachine(InitStages); } return OK; } @@ -267,6 +323,7 @@ uint32_t InitSequenceStateMachine( INIT_SEQUENCE_STAGES_ENUM ReadValue) break; default: LOG_ERROR(ReadValue,"ERROR IN INIT STATE MACHINE"); + RemoveControlCallback( InitSchedulerControlId,InitScheduler); break; } return OK; diff --git a/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.c b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.c new file mode 100644 index 000000000..7d42ad8f5 --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.c @@ -0,0 +1,130 @@ +/* + * PowerIdle.c + * + * Created on: Apr 3, 2019 + * Author: shlomo + */ +#include "modules/General/GeneralHardware.h" +#include "modules/General/Safety.h" +#include "modules/thread/thread.h" +#include "modules/ids/ids.h" +#include "modules/control/control.h" +#include "modules/AlarmHandling/AlarmHandling.h" +#include "modules/heaters/heaters_ex.h" +#include "modules/Diagnostics/Diagnostics.h" +#include "Modules/General/process.h" + +#include "StateMachines/Printing/PrintingSTM.h" +#include "InitSequence.h" + +#include "drivers/I2C_Communication/DAC/Blower.h" +#include "drivers/I2C_Communication/ADC_MUX/ADC_MUX.h" +#include "drivers/Valves/Valve.h" + +#include "Modules/General/buttons.h" + +#include "heaters/heaters_ex.h" + +#define DEFAULT_IDLE_TIME_LIMIT 3600 +int powerIdleSecondsCounter = 0; +int powerIdleSecondsLimit = DEFAULT_IDLE_TIME_LIMIT; +bool powerIdleState = false; +bool machineActive = false; +uint32_t IdleControlId = 0xFF; +ProcessParameters ActiveProcessParameters; +void PowerIdleSetIdle(void) +{ + memcpy (&ActiveProcessParameters,&ProcessParametersKeep,sizeof(ProcessParameters)); + ProcessParameters ProcessParametersClear; + ProcessParametersClear.dryerzone1temp = 80; + ProcessParametersClear.dryerzone2temp = 80; + ProcessParametersClear.dryerzone3temp = 80; + ProcessParametersClear.mixertemp = 0; + ProcessParametersClear.headzone1temp = 80; + ProcessParametersClear.headzone2temp = 80; + ProcessParametersClear.headzone3temp = 80; + ProcessParametersClear.headzone4temp = 80; + ProcessParametersClear.headzone5temp = 80; + ProcessParametersClear.headzone6temp = 80; + ProcessParametersClear.dyeingspeed = 40; + if (HandleProcessParameters(&ProcessParametersClear)!= OK) + { + LOG_ERROR (1, "Turn Heaters idle failed"); + return; + } + if (BlowerCfg.enabled == true) + { + Turn_the_Blower_On();//Turn on with the Default_Voltage + if (BlowerCfg.heatingvoltage) + Control_Voltage_To_Blower(BlowerCfg.heatingvoltage); + else + Control_Voltage_To_Blower(BlowerCfg.voltage-500); + } +} + +uint32_t PowerIdleCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) +{ + if (machineActive == true) + return OK; + if (powerIdleSecondsCounter%10 == 0) + Report("PowerIdle Idle counter ",__FILE__,__LINE__,(int)powerIdleSecondsLimit,RpWarning,(int)powerIdleSecondsCounter,0); + + if (++powerIdleSecondsCounter>=powerIdleSecondsLimit) + { + if (powerIdleState == false) + { + Report("PowerIdle Idle activated ",__FILE__,__LINE__,(int)powerIdleSecondsLimit,RpWarning,(int)powerIdleSecondsCounter,0); + powerIdleState = true; + SetPowerMachineState(sttIDLE); + //move to idle state + PowerIdleSetIdle(); + } + } + return OK; +} +void PowerIdleInit(void) +{ + IdleControlId = AddControlCallback( PowerIdleCallBackFunction, eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); + if (IdleControlId == 0xFF) + Report("AddControlCallback failed",__FILE__,__LINE__,(int)IdleControlId,RpWarning,(int)0,0); + Report("PowerIdleInit ",__FILE__,__LINE__,(int)powerIdleSecondsLimit,RpWarning,(int)0,0); + +} +int getIdleCounter (void) {return powerIdleSecondsCounter;} +void setIdleLimit (int Limit) {powerIdleSecondsLimit = Limit;} +void setmachineActive(bool Active){machineActive = Active;} +void resetIdleCounter (void) {powerIdleSecondsCounter = 0;} +bool getIdleState (void) {return powerIdleState;} + +void PowerIdleOutOfIdleState(void) +{ + Report("PowerIdle Out of Idle ",__FILE__,__LINE__,(int)powerIdleSecondsLimit,RpWarning,(int)powerIdleSecondsCounter,0); + powerIdleSecondsCounter = 0; + if (powerIdleState == true) + { + powerIdleState = false; + SetPowerMachineState(sttON); + if (HandleProcessParameters(&ActiveProcessParameters)!= OK) + { + LOG_ERROR (1, "Turn Heaters active failed"); + return ; + } + } + +} +void PowerIdleActivateIdleState(void) +{ + Report("PowerIdle Activate Idle ",__FILE__,__LINE__,(int)machineActive,RpWarning,(int)powerIdleSecondsCounter,0); + if (machineActive == true) + { + LOG_ERROR(machineActive, "machine is active, cannot switch on idle state"); + return; + } + powerIdleSecondsCounter = 0; + if (powerIdleState == false) + { + powerIdleState = true; + PowerIdleSetIdle(); + } + +} diff --git a/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.h b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.h new file mode 100644 index 000000000..efe0e7cb4 --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerIdle.h @@ -0,0 +1,27 @@ +/* + * PowerIdle.h + * + * Created on: Apr 3, 2019 + * Author: shlomo + */ + +#ifndef STATEMACHINES_INITIALIZATION_POWERIDLE_H_ +#define STATEMACHINES_INITIALIZATION_POWERIDLE_H_ + +int getIdleCounter (void); + +void setIdleLimit (int Limit); + +void resetIdleCounter (void); +bool getIdleState (void); + +void PowerIdleOutOfIdleState(void); +void PowerIdleActivateIdleState(void); + +void setmachineActive(bool Active); +void PowerIdleInit(void); + + + + +#endif /* STATEMACHINES_INITIALIZATION_POWERIDLE_H_ */ diff --git a/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.c b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.c new file mode 100644 index 000000000..454204229 --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.c @@ -0,0 +1,347 @@ +/* + * PowerOffSequence.c + * + * Created on: Apr 2, 2019 + * Author: shlomo + */ + + +#include "modules/General/GeneralHardware.h" +#include "modules/General/Safety.h" +#include "modules/thread/thread.h" +#include "modules/waste/waste.h" +#include "modules/ids/ids.h" +#include "modules/control/control.h" +#include "modules/AlarmHandling/AlarmHandling.h" +#include "modules/heaters/heaters_ex.h" +#include "modules/Diagnostics/Diagnostics.h" +#include "Modules/General/process.h" + +#include "Modules/Thread/Thread_ex.h" +#include "Common/SWUpdate/FirmwareUpgrade.h" + +#include "StateMachines/Printing/PrintingSTM.h" +#include "PowerIdle.h" +#include "InitSequence.h" + +#include "drivers/I2C_Communication/DAC/Blower.h" +#include "drivers/I2C_Communication/ADC_MUX/ADC_MUX.h" +#include "drivers/Heater/TemperatureSensor.h" +#include "drivers/Valves/Valve.h" + +#include "heaters/heaters_ex.h" + +#include "PowerOffSequence.h" +/* + typedef enum + { + POWER_OFF_INIT, + POWER_OFF_HEAD_CLEAN, + POWER_OFF_MIXER_FLUSH, + POWER_OFF_HEATERS_OFF, + POWER_OFF_STORE_DATA, + POWER_OFF_WAIT_FOR_PROCESSES,//wait for waste emptying, ink filling, thread loading + POWER_OFF_STOP_RUNNING_JOB, + POWER_OFF_SET_VALVE_POSITION, + POWER_OFF_WAIT_FOR_TEMPERATURE, + POWER_OFF_TURN_OFF_DRYER_FAN, + POWER_OFF_TURN_OFF_COOLER, + POWER_OFF_TURN_OFF_BLOWER, + POWER_OFF_POWER_OFF, + POWER_OFF_MAX, + }POWER_OFF_STAGES_ENUM; +*/ +POWER_OFF_STAGES_ENUM PowerOffMachineState = POWER_OFF_INIT,StoredMachineState = POWER_OFF_INIT; +uint32_t PowerOffControlId = 0xFF; +uint32_t WaitForProcessControlId = 0xFF; +uint32_t PowerOffSequenceStateMachine( POWER_OFF_STAGES_ENUM ReadValue); + +/*******************************************************************************************************/ +uint32_t PowerOffScheduler(uint32_t IfIndex, uint32_t BusyFlag) +{ + if (PowerOffMachineState > StoredMachineState) + { + StoredMachineState = PowerOffMachineState; + PowerOffSequenceStateMachine (PowerOffMachineState); + } + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffInit(void) +{ + LOG_ERROR(0,"Power Off Init"); + PowerOffMachineState = POWER_OFF_HEAD_CLEAN; + PowerOffControlId = AddControlCallback( PowerOffScheduler, eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffCancel(void) +{ + if (PowerOffMachineState >= POWER_OFF_HEAD_CLEAN) + PowerOffMachineState = POWER_OFF_CANCELLED; + return OK; +} + +/*******************************************************************************************************/ +uint32_t PowerOffHeadClean(void) +{ + //TBD + PowerOffMachineState = POWER_OFF_MIXER_FLUSH; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffMixerFlush(void) +{ + //TBD + PowerOffMachineState = POWER_OFF_HEATERS_OFF; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffHeatersOff(void) +{ + ProcessParameters ProcessParametersClear; + ProcessParametersClear.dryerzone1temp = 0; + ProcessParametersClear.dryerzone2temp = 0; + ProcessParametersClear.dryerzone3temp = 0; + ProcessParametersClear.mixertemp = 0; + ProcessParametersClear.headzone1temp = 0; + ProcessParametersClear.headzone2temp = 0; + ProcessParametersClear.headzone3temp = 0; + ProcessParametersClear.headzone4temp = 0; + ProcessParametersClear.headzone5temp = 0; + ProcessParametersClear.headzone6temp = 0; + ProcessParametersClear.dyeingspeed = 40; + if (HandleProcessParameters(&ProcessParametersClear)!= OK) + { + LOG_ERROR (PowerOffMachineState, "Turn Off Heaters failed"); + return ERROR; + } + + PowerOffMachineState = POWER_OFF_STORE_DATA; + + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffStoreData(void) +{ + //TBD + REPORT_MSG (PowerOffMachineState, "Store Data"); + IDS_Dispenser_Store_Data(); + PowerOffMachineState = POWER_OFF_WAIT_FOR_PROCESSES; + return OK; +} +/*******************************************************************************************************/ +int WaitForProcessCounter = 0; +uint32_t PowerOffWaitForProcessesCallback(uint32_t IfIndex, uint32_t BusyFlag) +{ + if ((WHS_IsEmptying()|| + //MidTankFillingActive()|| + ThreadLoadingActive()|| + SwUpgradeActive())&& + (WaitForProcessCounter++<900)) + { + REPORT_MSG (PowerOffMachineState, "On going processes, wait for end of process"); + resetIdleCounter(); + } + else + { + PowerOffMachineState = POWER_OFF_SET_VALVE_POSITION; + SafeRemoveControlCallback(WaitForProcessControlId, PowerOffWaitForProcessesCallback); + WaitForProcessControlId = 0xFF; + } + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffWaitForProcesses(void) +{ + int i; + REPORT_MSG (PowerOffMachineState, "Stop dispensers homing"); + for (i=0;i<MAX_SYSTEM_DISPENSERS;i++) + IDS_StopHomeDispenser(i); + if (WHS_IsEmptying()|| + //MidTankFillingActive()|| + ThreadLoadingActive()|| + SwUpgradeActive()) + { + WaitForProcessCounter = 0; //15 minutes wait + REPORT_MSG (PowerOffMachineState, "On going processes, wait for end of process"); + WaitForProcessControlId = AddControlCallback( PowerOffWaitForProcessesCallback, eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); + } + else + { + PowerOffMachineState = POWER_OFF_STOP_RUNNING_JOB; + } + //TBD + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffStopRunningJob(void) +{ + if (JobIsActive()) + { + REPORT_MSG (PowerOffMachineState, "Stop running job"); + AbortJob("Power off pressed"); + } + PowerOffMachineState = POWER_OFF_SET_VALVE_POSITION; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffSetValvePosition(void) +{ + //TBD + PowerOffMachineState = POWER_OFF_WAIT_FOR_TEMPERATURE; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffWaitForTemperatureCallback(uint32_t IfIndex, uint32_t BusyFlag) +{ + uint32_t MaxTemp = 0,readTemp; + readTemp = TemperatureSensorRead( MIXER_PT100); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DYEINGH_TEMP1); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DYEINGH_TEMP2); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DYEINGH_TEMP3); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DYEINGH_TEMP4); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DYEINGH_TEMP5); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( HEAD6_PT100); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + readTemp = TemperatureSensorRead( TEMP_SENSE_ANALOG_DRYER_TEMP1); + if ((readTemp>= MaxTemp)&&(readTemp < 28000)) + MaxTemp = readTemp; + +#define POWER_OFF_TEMP_THRESHOLD 10000 + + if ((MaxTemp>POWER_OFF_TEMP_THRESHOLD)&&(WaitForProcessCounter++<1800)) + { + Report("On going cooling down, wait for end of cooling",__FILE__,__LINE__,(int)MaxTemp,RpWarning,(int)WaitForProcessCounter,0); + resetIdleCounter(); + } + else + { + Report("ended cooling down, wait for end of cooling",__FILE__,__LINE__,(int)MaxTemp,RpWarning,(int)WaitForProcessCounter,0); + PowerOffMachineState = POWER_OFF_TURN_OFF_DRYER_FAN; + SafeRemoveControlCallback(WaitForProcessControlId, PowerOffWaitForTemperatureCallback); + WaitForProcessControlId = 0xFF; + } + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffWaitForTemperature(void) +{ + if (WaitForProcessControlId == 0xFF) + { + WaitForProcessCounter = 0; + WaitForProcessControlId = AddControlCallback( PowerOffWaitForTemperatureCallback, eOneSecond, TemplateDataReadCBFunction,0,0, 0 ); + } + //TBD + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffTurnOffDryerFan(void) +{ + Control_Dryer_Fan(STOP,75);//use START or STOP, 0 - 100% + PowerOffMachineState = POWER_OFF_TURN_OFF_COOLER; + + //TBD + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffTurnOffCooler(void) +{ + uint32_t DeActivateChiller(); + PowerOffMachineState = POWER_OFF_TURN_OFF_BLOWER; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffTurnOffBlower(void) +{ + Turn_the_Blower_Off();//Turn off + PowerOffMachineState = POWER_OFF_POWER_OFF; + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffPowerOff(void) +{ + int i; + for (i = 0;i<10;i++) + { + REPORT_MSG (10-i, "Power off in x seconds"); + Task_sleep (1000); + } + Power_Off(); + return OK; +} +/*******************************************************************************************************/ +uint32_t PowerOffSequenceStateMachine( POWER_OFF_STAGES_ENUM ReadValue) +{ + uint32_t status = OK; + + REPORT_MSG(ReadValue,"PowerOffSequenceStateMachine"); + switch (ReadValue) + { + case POWER_OFF_INIT: + break; + case POWER_OFF_HEAD_CLEAN: + status = PowerOffHeadClean(); + break; + case POWER_OFF_MIXER_FLUSH: + status = PowerOffMixerFlush(); + break; + case POWER_OFF_HEATERS_OFF: + status = PowerOffHeatersOff(); + break; + case POWER_OFF_STORE_DATA: + status = PowerOffStoreData(); + break; + case POWER_OFF_WAIT_FOR_PROCESSES: //wait for waste emptying: ink filling: thread loading + status = PowerOffWaitForProcesses(); + break; + case POWER_OFF_STOP_RUNNING_JOB: + status = PowerOffStopRunningJob(); + break; + case POWER_OFF_SET_VALVE_POSITION: + status = PowerOffSetValvePosition(); + break; + case POWER_OFF_WAIT_FOR_TEMPERATURE: + status = PowerOffWaitForTemperature(); + break; + case POWER_OFF_TURN_OFF_DRYER_FAN: + status = PowerOffTurnOffDryerFan(); + break; + case POWER_OFF_TURN_OFF_COOLER: + status = PowerOffTurnOffCooler(); + break; + case POWER_OFF_TURN_OFF_BLOWER: + status = PowerOffTurnOffBlower(); + break; + case POWER_OFF_POWER_OFF: + status = PowerOffPowerOff(); + break; + case POWER_OFF_ERROR: + case POWER_OFF_CANCELLED: + RemoveControlCallback( PowerOffControlId,PowerOffScheduler); + PowerOffControlId = 0xFF; + RemoveControlCallback(WaitForProcessControlId, PowerOffWaitForProcessesCallback); + RemoveControlCallback(WaitForProcessControlId, PowerOffWaitForTemperatureCallback); + WaitForProcessControlId = 0xFF; + LOG_ERROR(ReadValue,"POWER OFF Cancelled"); + break; + default: + LOG_ERROR(ReadValue,"ERROR IN POWER OFF STATE MACHINE"); + break; + } +return OK; +} + diff --git a/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.h b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.h new file mode 100644 index 000000000..af4d4230d --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Initialization/PowerOffSequence.h @@ -0,0 +1,36 @@ +/* + * PowerOffSequence.h + * + * Created on: Apr 2, 2019 + * Author: shlomo + */ + +#ifndef STATEMACHINES_INITIALIZATION_POWEROFFSEQUENCE_H_ +#define STATEMACHINES_INITIALIZATION_POWEROFFSEQUENCE_H_ + + typedef enum + { + POWER_OFF_INIT, + POWER_OFF_HEAD_CLEAN, + POWER_OFF_MIXER_FLUSH, + POWER_OFF_HEATERS_OFF, + POWER_OFF_STORE_DATA, + POWER_OFF_WAIT_FOR_PROCESSES,//wait for waste emptying, ink filling, thread loading + POWER_OFF_STOP_RUNNING_JOB, + POWER_OFF_SET_VALVE_POSITION, + POWER_OFF_WAIT_FOR_TEMPERATURE, + POWER_OFF_TURN_OFF_DRYER_FAN, + POWER_OFF_TURN_OFF_COOLER, + POWER_OFF_TURN_OFF_BLOWER, + POWER_OFF_POWER_OFF, + POWER_OFF_ERROR, + POWER_OFF_CANCELLED, + POWER_OFF_MAX, + }POWER_OFF_STAGES_ENUM; + + +uint32_t PowerOffInit(void); +uint32_t PowerOffCancel(void);//POWER_OFF_CANCELLED + + +#endif /* STATEMACHINES_INITIALIZATION_POWEROFFSEQUENCE_H_ */ diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c index 69361bbae..b5034a11c 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c @@ -37,6 +37,7 @@ #include "PMR/Printing/CurrentJobResponse.pb-c.h" #include "PMR/Printing/ResumeCurrentJobRequest.pb-c.h" #include "PMR/Printing/ResumeCurrentJobResponse.pb-c.h" +#include "PMR/Printing/JobUploadStrategy.pb-c.h" #include "PMR/Printing/JobStatus.pb-c.h" #include "PMR/Printing/AbortJobRequest.pb-c.h" #include "PMR/Printing/AbortJobResponse.pb-c.h" @@ -58,6 +59,7 @@ #include "PMR/Diagnostics/ThreadAbortJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingResponse.pb-c.h" +#include "StateMachines/Initialization/PowerIdle.h" #include "./printingSTM.h" #include "modules/thread/thread_ex.h" @@ -88,7 +90,7 @@ JobSegment *TSegment; JobSpool *Tspool; bool CopyConfigured[MAX_SYSTEM_MODULES]; char ErrorMsg[100]; - +JobUploadStrategy uploadstrategy = JOB_UPLOAD_STRATEGY__Default; ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle}; @@ -377,6 +379,7 @@ uint32_t ThreadJoggingFunc(int speed) { //load essential job prameters to enable thread running Ticket.n_segments = 1; + n_segments = 1; Ticket.segments = my_malloc(sizeof(Ticket.segments)); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); @@ -587,7 +590,7 @@ void JobRequestFunc(MessageContainer* requestContainer) ErrorCode error = ERROR_CODE__NONE; JobEndReasonEnum JobAlarmReason = JOB_OK; - if (JobActive == false) + if (JobActive == true) { LOG_ERROR(JobActive, "Job started while active"); } @@ -612,7 +615,17 @@ void JobRequestFunc(MessageContainer* requestContainer) if (CurrentRequest!= NULL) job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = request; - + n_segments = 0; + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + LOG_ERROR(JobActive, "Job upload strategy file"); + uploadstrategy = JOB_UPLOAD_STRATEGY__JobDescriptionFile; + } + else + { + uploadstrategy = JOB_UPLOAD_STRATEGY__Default; + n_segments = CurrentJob->n_segments; + } status = PASSED; JobEndReason = JOB_OK; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); @@ -649,7 +662,8 @@ void JobRequestFunc(MessageContainer* requestContainer) } if (status == PASSED) { - Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,Ticket->n_segments, Ticket->intersegmentlength); + Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,n_segments, Ticket->intersegmentlength); + OpenJobFile(); StartJob(CurrentJob); } } @@ -941,6 +955,7 @@ Void jobTask(UArg arg0, UArg arg1) case JobRequestMsg: JobEndReason = JOB_OK; JobActive = true; + setmachineActive(true); /*ValidateState (CurrentJob); break; case ValidationResultsOk:*/ @@ -964,6 +979,8 @@ Void jobTask(UArg arg0, UArg arg1) break; case PrintingResultsOk: JobActive = false; + setmachineActive(false); + resetIdleCounter(); CurrentJob = NULL; //if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); @@ -975,6 +992,8 @@ Void jobTask(UArg arg0, UArg arg1) break; case PrintingResultsFail: JobActive = false; + setmachineActive(false); + resetIdleCounter(); CurrentJob = NULL; //if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c index 53057c170..c52ed8b4c 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -25,6 +25,10 @@ #include "PMR/Hardware/UploadHardWareConfigurationRequest.pb-c.h" #include "PMR/Hardware/HardwareMotorType.pb-c.h" #include "modules/General/process.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "Common/SWUpdate/FileSystem.h" +#include "drivers/Flash_Memory/fatfs/ff.h" ////////////////////////////////State machine operation//////////////////////////////////// //the state machine operation is used to operate in runtime correct profile flow execution //by recieved esign flow of the user from the UI @@ -38,7 +42,7 @@ static uint32_t PreSegmentState(void *Segment, int); static uint32_t SegmentState(void *Segment, int); uint32_t EndState(void *JobDetails, char *Message); //static uint32_t ExitState(void *JobDetails); - +uint16_t n_segments = 0; /********************************************************************** * the array and enum of PrintingState_t below must be in sync order ***********************************************************************/ @@ -65,9 +69,174 @@ ModuleStateEnum EndWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,M bool Configured[MAX_SYSTEM_MODULES] = {false,false,false,false,false}; bool SuspendLargeMessages = false; +/* +Parsing the job description file. +The job description file simply contains an array of segments and their brush stops. +The job description file is meant to be read brush stop by brush stop while the job is in progress. +The following diagram represents a single job description file segment structure. +The process of reading the whole file is simply repeating that reading order. -/******************************************************************************************************************** - * this function is for development initial stages. it analyses the hardware configuration to determine which modules are operational +Each JobDescriptionFileSegment contains a “BrushStopsCount” field that should be used to determine how many brush stops are associated +with the current segment and how many times the process of reading brush stops should be repeated. +1. 32bit integer containing the next JobFileDescriptionSegment message byte count +2. JobDescriptionFileSegment message +3. 32bit integer containing the next JobDescriptionFileBrushStop message byte count +4. JobDescriptionFileBrushStop message + +1. Read segment message length. +2. Read segment message. +a. Read brush stop message length. +b. Read brush stop message. +c. Go to step 2.a x Segment.BrushStopsCount. +3. Go to step 1 until end of file. +*/ + +//job file reading functions +uint32_t bBytes = 0,readbBytes = 0,ImmediateRead = 0,SegmentSize = 0,BrushStopSize = 0; +FRESULT Fresult = FR_OK; +uint8_t *SegmentPtr = 0, *BrushStopPtr = 0; +FIL *JobRequestFileHandle = 0; //the system supports a single active file +FRESULT OpenJobFile() +{ + //n_segments = 0; + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + JobRequestFileHandle = my_malloc(sizeof(FIL)); + + Fresult = FileOpen(CurrentJob->jobdescriptionfile, &bBytes, JobRequestFileHandle); + if (Fresult == FR_OK) + { + readbBytes = 0; + } + REPORT_MSG(bBytes,"OpenJobFile"); + } + return Fresult; +} +FRESULT CloseJobFile() +{ + Fresult = f_close(JobRequestFileHandle); + readbBytes = 0; + ImmediateRead = 0; + SegmentSize = 0; + BrushStopSize = 0; + my_free (JobRequestFileHandle); + JobRequestFileHandle = NULL; + if (BrushStopPtr) + my_free(BrushStopPtr); + if (SegmentPtr) + my_free(SegmentPtr); + REPORT_MSG(Fresult,"CloseJobFile"); + + return Fresult; +} +JobDescriptionFileSegment *GetNextSegmentFromJobFile() +{ + uint32_t status = OK; + JobDescriptionFileSegment *Segment = NULL; + if (JobRequestFileHandle == NULL) + { + LOG_ERROR(JobRequestFileHandle,"JobRequestFileHandle == NULL"); + return NULL; + } + if(readbBytes < bBytes) + { + Fresult = f_read(JobRequestFileHandle,&SegmentSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + if (SegmentPtr) + my_free(SegmentPtr); + SegmentPtr = my_malloc (SegmentSize); + if (SegmentPtr) + { + Fresult = f_read(JobRequestFileHandle,SegmentPtr,SegmentSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + //n_segments++; + Segment = job_description_file_segment__unpack(NULL, SegmentSize, SegmentPtr); + } + }// read segment data + my_free(SegmentPtr); + }//segment malloc + else + { + LOG_ERROR (SegmentPtr, "malloc error"); + status = ERROR; + } + }//segment read size + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + return Segment; +} +void FreeSegmentFileData(JobDescriptionFileSegment *Segment) +{ + job_description_file_segment__free_unpacked(Segment,NULL); + Segment = NULL; + if (SegmentPtr) + my_free(SegmentPtr); +} +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile() +{ + uint32_t status = OK; + JobDescriptionFileBrushStop *BrushStop = NULL; + if (JobRequestFileHandle == NULL) + { + LOG_ERROR(JobRequestFileHandle,"JobRequestFileHandle == NULL"); + return NULL; + } + Fresult = f_read(JobRequestFileHandle,&BrushStopSize,4,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + if (BrushStopPtr) + my_free(BrushStopPtr); + + BrushStopPtr = my_malloc (BrushStopSize); + if (BrushStopPtr) + { + Fresult = f_read(JobRequestFileHandle,BrushStopPtr,BrushStopSize,&ImmediateRead ); + if (Fresult == FR_OK) + { + readbBytes += ImmediateRead; + BrushStop = job_description_file_brush_stop__unpack(NULL, BrushStopSize, BrushStopPtr); + }//brushstop malloc ok + else + { + LOG_ERROR (Fresult, "f_read error"); + status = ERROR; + } + my_free(BrushStopPtr); + }//brushstop size read ok + else + { + LOG_ERROR (BrushStopPtr, "malloc error"); + status = ERROR; + } + }// if brush stop count + else + { + LOG_ERROR (0, "f_read error brush stop size error"); + status = ERROR; + } + REPORT_MSG(BrushStop->index,"BrushStop file Read Index"); + + return BrushStop; +} +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop) +{ + REPORT_MSG(BrushStop->index,"Free BrushStop file Read Index"); + if (BrushStop) + job_description_file_brush_stop__free_unpacked (BrushStop,NULL); + BrushStop = NULL; + if (BrushStopPtr) + my_free(BrushStopPtr); +} +/************************************************************************************************************************************/ +/* this function is for development initial stages. it analyses the hardware configuration to determine which modules are operational * according to the configuration map */ @@ -233,8 +402,8 @@ uint32_t SegmentReady(int ModuleId, ModuleStateEnum result) assert (ModuleId<MAX_SYSTEM_MODULES); assert (result<=ModuleFail); - REPORT_MSG (ModuleId, "SegmentReady"); - Report("IDSSegmentState",__FILE__,__LINE__,(int)ModuleId,RpWarning,(int)result,0); + //REPORT_MSG (ModuleId, "SegmentReady"); + Report("SegmentReady",__FILE__,__LINE__,(int)ModuleId,RpWarning,(int)result,0); if (SegmentWaiting[ModuleId] != ModuleWaiting) { @@ -410,6 +579,7 @@ uint32_t EndState(void *JobDetails, char *Message) //EndWaiting[Module_Thread] = ModuleWaiting; ThreadEndState(); } + CloseJobFile(); //ROM_IntMasterEnable(); SendJobProgress(0.0,0,true,Message); @@ -436,16 +606,18 @@ void StartPrinting(void) //******************************************************************************************************************** //******************************************************************************************************************** -void StopPrinting(void) -{ -} int SegmentId = 0; +JobDescriptionFileSegment *Segment; +JobSegment SSegment; + +//******************************************************************************************************************** +//******************************************************************************************************************** void PrintSTMMsgHandler(void * msg) { JobMessageStruc *Message = msg; PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message->messageData; - Report("PrintSTMMsgHandler",__FILE__,__LINE__, RpMessage,0x1000,Message->messageId,PrtMessage->messageId); + Report("PrintSTMMsgHandler",__FILE__,__LINE__, 1000,RpMessage,Message->messageId,PrtMessage->messageId); if ((Message->messageId != PrintMessage)&&(Message->messageId != Abort)) { @@ -456,10 +628,28 @@ void PrintSTMMsgHandler(void * msg) { case PrintRequest: SegmentId = 0; - PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + Segment = GetNextSegmentFromJobFile(); + SSegment.length = Segment->length; + SSegment.has_length = Segment->has_length; + SSegment.n_brushstops = Segment->brushstopscount; + PreSegmentState(&SSegment,SegmentId); + } + else + { + PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + } break; case PreSegmentResultsOk: - SegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + SegmentState(&SSegment,SegmentId); + } + else + { + SegmentState(CurrentJob->segments[SegmentId],SegmentId); + } break; case PreSegmentResultsFail: EndState(CurrentJob, "PreSegment Failed"); @@ -467,8 +657,9 @@ void PrintSTMMsgHandler(void * msg) break; case SegmentResultsOk: SegmentId++; - LOG_ERROR(SegmentId, "SegmentResultsOk segmentId"); - if (SegmentId >= CurrentJob->n_segments) + //REPORT_MSG(SegmentId, "SegmentResultsOk segmentId"); + Report("SegmentResultsOk segmentId",__FILE__,__LINE__, SegmentId,RpMessage,n_segments,0); + if (SegmentId >= n_segments) { if (dryerbufferlength == 0) EndState(CurrentJob, "Job Ended"); @@ -477,7 +668,21 @@ void PrintSTMMsgHandler(void * msg) } else { - PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) + { + if (Segment) + FreeSegmentFileData(Segment); + + Segment = GetNextSegmentFromJobFile(); + SSegment.length = Segment->length; + SSegment.has_length = Segment->has_length; + SSegment.n_brushstops = Segment->brushstopscount; + PreSegmentState(&SSegment,SegmentId); + } + else + { + PreSegmentState(CurrentJob->segments[SegmentId],SegmentId); + } } break; case SegmentResultsFail: diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h index 878e063b5..d7d8262f4 100644 --- a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h @@ -17,6 +17,9 @@ #include "PMR/Printing/JobRequest.pb-c.h" #include "PMR/Printing/JobTicket.pb-c.h" #include "PMR/Printing/JobResponse.pb-c.h" +#include "PMR/Printing/JobDescriptionFileBrushStop.pb-c.h" +#include "PMR/Printing/JobDescriptionFileSegment.pb-c.h" +#include "drivers/Flash_Memory/fatfs/ff.h" #define MAX_MSG_LEN 100 typedef enum @@ -166,8 +169,10 @@ uint32_t CurrentJobRequestFunc(MessageContainer* requestContainer); uint32_t ResumeCurrentJobRequestFunc(MessageContainer* requestContainer); bool JobIsActive(void); + extern bool SuspendLargeMessages; +extern uint16_t n_segments; void SendJobProgress(double ProcessedLength,int SegmentId, bool done, char *Message); uint32_t PrepareReady(int ModuleId, ModuleStateEnum result); @@ -179,4 +184,12 @@ uint32_t EndState(void *JobDetails, char *Message); bool GetHeatersPrepareWaiting(void); +extern JobUploadStrategy uploadstrategy; +FRESULT OpenJobFile(); +FRESULT CloseJobFile(); +JobDescriptionFileSegment *GetNextSegmentFromJobFile(); +void FreeSegmentFileData(JobDescriptionFileSegment *Segment); +JobDescriptionFileBrushStop *GetNextBrushStopFromJobFile(); +void FreeBrushStopFileData(JobDescriptionFileBrushStop *BrushStop); + #endif /* STATEMACHINES_PRINTSTM_H_ */ diff --git a/Software/PMR/Messages/EmbeddedParameters/ConfigurationParameters.proto b/Software/PMR/Messages/EmbeddedParameters/ConfigurationParameters.proto index 733651a34..1752307ad 100644 --- a/Software/PMR/Messages/EmbeddedParameters/ConfigurationParameters.proto +++ b/Software/PMR/Messages/EmbeddedParameters/ConfigurationParameters.proto @@ -62,7 +62,20 @@ message ConfigurationParameters double IDS_CleaningSpeed = 26; //cleaning dispenser stop before segment start double IDS_CleaningStopBeforeSegmentTime = 27; - double IDS_LeftCleaningMotorSpeed = 28; - double IDS_RightCleaningMotorSpeed = 29; + //cleaning dispenser start during pre segment + double IDS_CleaningStartSprayPreSegmentTime = 28; + double IDS_LeftCleaningMotorSpeed = 29; + double IDS_RightCleaningMotorSpeed = 30; + + uint32 SwitchToIdleTimeinSeconds = 31; + uint32 IdleDrierTemperature = 32; + uint32 IdleHeadTemperature = 33; + uint32 IdleMixerTemperature = 34; + + uint32 PowerOffTemperatureLimit = 35; //temperature to allow machine power off + + double IDS_PreSegment_WFCF_TimeBeforeSegment = 36; + + } diff --git a/Software/PMR/Messages/TCC/DetectionBenchmark.proto b/Software/PMR/Messages/TCC/DetectionBenchmark.proto index a512dfa5f..0a6fb42f2 100644 --- a/Software/PMR/Messages/TCC/DetectionBenchmark.proto +++ b/Software/PMR/Messages/TCC/DetectionBenchmark.proto @@ -9,7 +9,7 @@ message DetectionBenchmark int32 Green = 2; int32 Blue = 3; - int32 L = 4; - int32 A = 5; - int32 B = 6; + double L = 4; + double A = 5; + double B = 6; }
\ No newline at end of file diff --git a/Software/Stubs Collection/stubs/Poweroff_progress.cs b/Software/Stubs Collection/stubs/Poweroff_progress.cs new file mode 100644 index 000000000..a10bc4ed4 --- /dev/null +++ b/Software/Stubs Collection/stubs/Poweroff_progress.cs @@ -0,0 +1,23 @@ +using System; +using System.Text; +using System.Linq; +using System.Drawing; +using System.Diagnostics; +using System.Windows.Forms; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; +using Tango.PMR.Stubs; +using Tango.Stubs; + +public void OnExecute(StubManager stubManager) +{ + + +ProgressRequest progressRequest = new ProgressRequest(); +progressRequest.Amount = 10; +progressRequest.Delay = 10; + + var response = stubManager.Run<ProgressResponse>(progressRequest); + +}
\ No newline at end of file diff --git a/Software/Stubs Collection/stubs/technician view files/lp4 Tech Board.tpf b/Software/Stubs Collection/stubs/technician view files/lp4 Tech Board.tpf index 630461d99..f1c80020c 100644 --- a/Software/Stubs Collection/stubs/technician view files/lp4 Tech Board.tpf +++ b/Software/Stubs Collection/stubs/technician view files/lp4 Tech Board.tpf @@ -24,13 +24,13 @@ <Width>575</Width> <Height>201.64159292035407</Height> <Angle>0</Angle> - <ItemGuid>D7585119-4A42-4370-8F1E-F3E62553E588</ItemGuid> + <ItemGuid>AFB7B6F7-8FFB-4A7F-B814-04F0C163CAA1</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>701</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="ControllerItem"> <ID>ba743caa-95f2-4b20-8c32-8e5943ada3fc</ID> @@ -41,9 +41,9 @@ <Angle>0</Angle> <ItemGuid>78482AA4-3DF6-421F-944C-64328D3C3EF2</ItemGuid> <ColorNumber>-14774017</ColorNumber> - <UpdateInterval>10</UpdateInterval> <OptimalRangeMinimum>0</OptimalRangeMinimum> <OptimalRangeMaximum>70</OptimalRangeMaximum> + <UpdateInterval>10</UpdateInterval> <IsSetToDefault>true</IsSetToDefault> </TechItem> <TechItem xsi:type="DigitalOutItem"> @@ -123,13 +123,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>DryerAirHeater</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>97.389999999999986</CurrentValue> + <SetPoint>165</SetPoint> + <CurrentValue>149.02</CurrentValue> <IsActive>false</IsActive> - <IsRampingUp>false</IsRampingUp> - <IsInSetPoint>true</IsInSetPoint> + <IsRampingUp>true</IsRampingUp> + <IsInSetPoint>false</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>165</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>0ac64716-d30c-489b-939e-a26d06445866</ID> @@ -143,7 +143,7 @@ <HeaterState> <HeaterType>DryerMainHeater</HeaterType> <SetPoint>0</SetPoint> - <CurrentValue>170.61999999999998</CurrentValue> + <CurrentValue>249.91</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> @@ -162,7 +162,7 @@ <HeaterState> <HeaterType>DryerSecondaryHeater</HeaterType> <SetPoint>0</SetPoint> - <CurrentValue>167.51</CurrentValue> + <CurrentValue>251.47</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> @@ -180,13 +180,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone3</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>87.97</CurrentValue> + <SetPoint>110</SetPoint> + <CurrentValue>109.75999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>110</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>7e8dd386-cca6-4d07-8a3e-af5403756002</ID> @@ -199,13 +199,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone2</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>92.71</CurrentValue> + <SetPoint>110</SetPoint> + <CurrentValue>109.67999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>110</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>32a91e5f-27c8-490d-b187-8e39b6626a13</ID> @@ -218,13 +218,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone1</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>68.76</CurrentValue> + <SetPoint>80</SetPoint> + <CurrentValue>79.76</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>80</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>c844235a-8a29-4c2e-a964-e8f546d2ced7</ID> @@ -238,7 +238,7 @@ <HeaterState> <HeaterType>MixerHeater</HeaterType> <SetPoint>0</SetPoint> - <CurrentValue>72.5</CurrentValue> + <CurrentValue>283.75</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> @@ -256,13 +256,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone4</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>89.149999999999991</CurrentValue> + <SetPoint>120</SetPoint> + <CurrentValue>119.64999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>120</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>e6b3eb18-482b-450e-b8a8-d2ac6bba4fd4</ID> @@ -275,13 +275,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone5</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>109.14999999999999</CurrentValue> + <SetPoint>130</SetPoint> + <CurrentValue>129.72</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>130</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>efff2e67-e3a3-4667-9208-4704707d7cda</ID> @@ -294,13 +294,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone6</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>105.57</CurrentValue> + <SetPoint>140</SetPoint> + <CurrentValue>139.54</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>140</SetPoint> </TechItem> <TechItem xsi:type="MonitorItem"> <ID>f9936dba-cef8-41e3-a715-eb629dca1870</ID> @@ -421,7 +421,7 @@ <ItemGuid>96B89605-F999-43FE-A1CD-2645BFB33A36</ItemGuid> <ColorNumber>-1</ColorNumber> <UpdateInterval>10</UpdateInterval> - <DecimalPoints>0</DecimalPoints> + <DecimalPoints>2</DecimalPoints> </TechItem> <TechItem xsi:type="MonitorItem"> <ID>6be024c6-3d1b-4267-9b77-44473aba56b7</ID> @@ -433,7 +433,7 @@ <ItemGuid>FC60060A-3736-4910-B41A-FF6DABDF0E9E</ItemGuid> <ColorNumber>-1</ColorNumber> <UpdateInterval>10</UpdateInterval> - <DecimalPoints>0</DecimalPoints> + <DecimalPoints>2</DecimalPoints> </TechItem> <TechItem xsi:type="MonitorItem"> <ID>7c720f3b-00e1-49dd-92f9-fdd1e9686623</ID> @@ -445,7 +445,7 @@ <ItemGuid>4CE6A82E-D841-4D33-BBB2-11F0743A441C</ItemGuid> <ColorNumber>-1</ColorNumber> <UpdateInterval>10</UpdateInterval> - <DecimalPoints>0</DecimalPoints> + <DecimalPoints>2</DecimalPoints> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>3ebd6759-521b-4ed1-a353-ee1ad7801f28</ID> @@ -456,11 +456,11 @@ <Angle>0</Angle> <ItemGuid>D126DB23-784B-4F0C-8F88-D89A65A7549F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>1460</Duration> <Min>0</Min> <Max>16384</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>984b4126-3dda-4624-a79f-0646eb0e1358</ID> @@ -471,11 +471,11 @@ <Angle>0</Angle> <ItemGuid>10102BC3-0EAE-47FF-A8E5-8640780CAA3D</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>1516</Duration> <Min>0</Min> <Max>16384</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>8ebc3ab7-a02d-4b12-93b3-2563443831d7</ID> @@ -486,11 +486,11 @@ <Angle>0</Angle> <ItemGuid>C0BCCD5C-346B-4C4A-A080-39D28E9E1A0C</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>1398</Duration> <Min>0</Min> <Max>16384</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>acafb268-5e97-4277-8dc8-173250a9e3f8</ID> @@ -501,11 +501,22 @@ <Angle>0</Angle> <ItemGuid>9FBC5460-BA59-486B-8D85-BD7D8A959F98</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>1273</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> + </TechItem> + <TechItem xsi:type="MotorItem"> + <ID>3ccb1485-b0e9-4d36-a931-a1b3865edeaa</ID> + <Left>460</Left> + <Top>38.28761061946841</Top> + <Width>267</Width> + <Height>221.90707964601768</Height> + <Angle>0</Angle> + <ItemGuid>08d15ca1-d7d1-460f-8f37-42c37c287cd1</ItemGuid> + <ColorNumber>-1</ColorNumber> + <Speed>952.3546144121359</Speed> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>be4cb8d9-b516-4604-a6a5-1638cbc50251</ID> @@ -516,11 +527,11 @@ <Angle>0</Angle> <ItemGuid>4CE6A82E-D841-4D33-BBB2-11F0743A441C</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>514</Duration> <Min>0</Min> <Max>100000</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>75b99507-4eba-4b11-b52e-26732d4c5479</ID> @@ -531,11 +542,11 @@ <Angle>0</Angle> <ItemGuid>F1DF490B-0577-4FA7-ACA1-0EEF4F934E8F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>4</DecimalPlaces> <Duration>1398</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>4</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>a30e48de-be76-4230-92d0-d27d6f37b940</ID> @@ -546,11 +557,11 @@ <Angle>0</Angle> <ItemGuid>5F12B974-2C9E-4DDD-9B20-733251A5D7E6</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>4</DecimalPlaces> <Duration>1398</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>4</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>5ac4b368-093a-4192-98d4-e9d24f229b13</ID> @@ -561,31 +572,30 @@ <Angle>0</Angle> <ItemGuid>84CF23C9-D20D-4C08-BE1D-80201FC43C06</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>4</DecimalPlaces> <Duration>1398</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>4</DecimalPlaces> </TechItem> <TechItem xsi:type="MonitorRecorderItem"> <ID>9c34dc69-cfaa-48b4-9d02-8f0d9bba79dd</ID> - <Left>1358</Left> - <Top>123.61504424778764</Top> - <Width>170</Width> - <Height>573.5132743362833</Height> - <Angle>0</Angle> - <ColorNumber>-1</ColorNumber> - <SelectedMonitorsGuids /> - </TechItem> - <TechItem xsi:type="ThreadMotionItem"> - <ID>b083f678-c5ea-4700-bfa2-ca51ed62cf4b</ID> - <Left>480</Left> - <Top>23.300884955752224</Top> - <Width>317</Width> - <Height>192.52212389380532</Height> + <Left>1303</Left> + <Top>34.380530973454768</Top> + <Width>176</Width> + <Height>83.05309734512457</Height> <Angle>0</Angle> <ColorNumber>-1</ColorNumber> - <Speed>20</Speed> + <SelectedMonitorsGuids> + <string>F1DF490B-0577-4FA7-ACA1-0EEF4F934E8F</string> + <string>4CE6A82E-D841-4D33-BBB2-11F0743A441C</string> + <string>9ADF7823-B293-4275-9999-F62474D246AA</string> + <string>5F12B974-2C9E-4DDD-9B20-733251A5D7E6</string> + <string>FC60060A-3736-4910-B41A-FF6DABDF0E9E</string> + <string>96B89605-F999-43FE-A1CD-2645BFB33A36</string> + <string>84CF23C9-D20D-4C08-BE1D-80201FC43C06</string> + <string>89B7B89D-8050-4188-B568-35B1910CFB6F</string> + </SelectedMonitorsGuids> </TechItem> </Items> </MachineTechViewProjectTab> @@ -685,7 +695,7 @@ <Angle>0</Angle> <ItemGuid>8A957565-4165-49F7-854D-D21F95FFBE1B</ItemGuid> <ColorNumber>-724238</ColorNumber> - <Speed>1200</Speed> + <Speed>0</Speed> <DisplayName>Dispenser 8</DisplayName> </TechItem> <TechItem xsi:type="MonitorItem"> @@ -791,7 +801,7 @@ <Width>247</Width> <Height>122.24778761061873</Height> <Angle>0</Angle> - <ItemGuid>99cf8832-edf6-4343-9af4-a5808680becc</ItemGuid> + <ItemGuid>074b6ed8-0f87-4973-bbea-509838f9c3ed</ItemGuid> <ColorNumber>-1</ColorNumber> </TechItem> <TechItem xsi:type="DigitalOutItem"> @@ -813,9 +823,9 @@ <Angle>0</Angle> <ItemGuid>78482AA4-3DF6-421F-944C-64328D3C3EF2</ItemGuid> <ColorNumber>-14774017</ColorNumber> - <UpdateInterval>10</UpdateInterval> <OptimalRangeMinimum>0</OptimalRangeMinimum> <OptimalRangeMaximum>70</OptimalRangeMaximum> + <UpdateInterval>10</UpdateInterval> <IsSetToDefault>true</IsSetToDefault> </TechItem> <TechItem xsi:type="DigitalOutItem"> @@ -849,11 +859,11 @@ <Angle>0</Angle> <ItemGuid>D023F15D-3555-48E9-A9E9-5DF99F60D791</ItemGuid> <ColorNumber>0</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="MonitorItem"> <ID>46bdfce3-1c69-45dd-bbe9-582d1ac1e6f2</ID> @@ -1067,7 +1077,7 @@ <Height>167.26548672566202</Height> <Angle>0</Angle> <ColorNumber>-1</ColorNumber> - <Speed>20</Speed> + <Speed>40</Speed> </TechItem> <TechItem xsi:type="BreakSensorItem"> <ID>92607e12-2dd6-41c9-8f89-f051f386b734</ID> @@ -1169,11 +1179,11 @@ <Angle>0</Angle> <ItemGuid>D7585119-4A42-4370-8F1E-F3E62553E588</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>2962</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>c4e19f7c-e6e9-4f45-987e-f124456b2529</ID> @@ -1184,11 +1194,11 @@ <Angle>0</Angle> <ItemGuid>A8DB1D27-6B25-4FB4-A3F5-46A29BA51955</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>2817</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>b8b24455-1c20-417d-bd78-5fe4c7e3d023</ID> @@ -1199,11 +1209,11 @@ <Angle>0</Angle> <ItemGuid>6C0C1AB0-3EE9-40D7-8424-A79436FBC804</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>2982</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>2129a0cd-454f-4834-8197-3b048bf4b978</ID> @@ -1214,11 +1224,11 @@ <Angle>0</Angle> <ItemGuid>098F7CAB-030C-46B0-B2B8-A85AF2253032</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>2949</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>892fabb7-01fa-4b39-a19e-a557fafae0ac</ID> @@ -1229,11 +1239,11 @@ <Angle>0</Angle> <ItemGuid>DACEBF90-E2B4-4CC9-A973-B8B429AA0089</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>2628</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>4859974c-7224-42d5-97ca-0e2e549372f5</ID> @@ -1244,11 +1254,11 @@ <Angle>0</Angle> <ItemGuid>246C2551-5EFD-48E9-94F6-6313C5E5018F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>3153</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="PidItem"> <ID>81b78212-14d8-4a66-bf3a-eeea9900e0d6</ID> @@ -1319,11 +1329,11 @@ <Angle>0</Angle> <ItemGuid>AFB7B6F7-8FFB-4A7F-B814-04F0C163CAA1</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>3153</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>9330a6be-17f1-4ecb-978d-719adf9fec1f</ID> @@ -1334,11 +1344,11 @@ <Angle>0</Angle> <ItemGuid>9A3877B2-9F98-4A5C-9A93-DECA2836FA8A</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>2</DecimalPlaces> <Duration>3153</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>2</DecimalPlaces> </TechItem> <TechItem xsi:type="PidItem"> <ID>3228b2ba-83f3-4eb2-a6d2-7200301758a4</ID> @@ -1371,13 +1381,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone4</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>89.149999999999991</CurrentValue> + <SetPoint>120</SetPoint> + <CurrentValue>119.64999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>120</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>4fa7a50d-5155-4785-95a0-508cd40fad4d</ID> @@ -1390,13 +1400,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone1</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>68.76</CurrentValue> + <SetPoint>80</SetPoint> + <CurrentValue>79.76</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>80</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>9da56601-7b5b-4f0f-afbf-2b31970b104f</ID> @@ -1409,13 +1419,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone3</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>87.97</CurrentValue> + <SetPoint>110</SetPoint> + <CurrentValue>109.75999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>110</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>b700e59d-f923-4f13-9dcc-942050548c22</ID> @@ -1428,13 +1438,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone5</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>109.14999999999999</CurrentValue> + <SetPoint>130</SetPoint> + <CurrentValue>129.72</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>130</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>97bf8fa2-b07f-4f0e-87ac-820ea52d236e</ID> @@ -1448,7 +1458,7 @@ <HeaterState> <HeaterType>MixerHeater</HeaterType> <SetPoint>0</SetPoint> - <CurrentValue>72.5</CurrentValue> + <CurrentValue>283.75</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> @@ -1466,13 +1476,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone2</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>92.71</CurrentValue> + <SetPoint>110</SetPoint> + <CurrentValue>109.67999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>110</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>3020fbc5-305e-4adf-9f1e-d7a48168e2e7</ID> @@ -1485,13 +1495,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone6</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>105.57</CurrentValue> + <SetPoint>140</SetPoint> + <CurrentValue>139.54</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>140</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>a4049a51-7417-4eab-8bc1-837574307e93</ID> @@ -1504,13 +1514,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>DryerAirHeater</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>97.389999999999986</CurrentValue> + <SetPoint>165</SetPoint> + <CurrentValue>149.02</CurrentValue> <IsActive>false</IsActive> - <IsRampingUp>false</IsRampingUp> - <IsInSetPoint>true</IsInSetPoint> + <IsRampingUp>true</IsRampingUp> + <IsInSetPoint>false</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>165</SetPoint> </TechItem> </Items> </MachineTechViewProjectTab> @@ -1537,11 +1547,11 @@ <Angle>0</Angle> <ItemGuid>098F7CAB-030C-46B0-B2B8-A85AF2253032</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>3bf6782d-117d-4589-a1d6-6454b67e3862</ID> @@ -1552,11 +1562,11 @@ <Angle>0</Angle> <ItemGuid>6C0C1AB0-3EE9-40D7-8424-A79436FBC804</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>c7a89d21-7383-4caa-941e-b42e1109b16a</ID> @@ -1567,11 +1577,11 @@ <Angle>0</Angle> <ItemGuid>246C2551-5EFD-48E9-94F6-6313C5E5018F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>300</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>4c789472-cb4f-4ede-b22a-c733591117c8</ID> @@ -1584,13 +1594,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone3</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>87.97</CurrentValue> + <SetPoint>110</SetPoint> + <CurrentValue>109.75999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>110</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>ddda12e1-54ad-4ffd-9f77-5845372e134f</ID> @@ -1603,13 +1613,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone4</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>89.149999999999991</CurrentValue> + <SetPoint>120</SetPoint> + <CurrentValue>119.64999999999999</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>120</SetPoint> </TechItem> <TechItem xsi:type="HeaterItem"> <ID>479f6fd7-25bb-4583-985e-169e045895ce</ID> @@ -1622,13 +1632,13 @@ <ColorNumber>-1</ColorNumber> <HeaterState> <HeaterType>HeaterZone5</HeaterType> - <SetPoint>0</SetPoint> - <CurrentValue>109.14999999999999</CurrentValue> + <SetPoint>130</SetPoint> + <CurrentValue>129.72</CurrentValue> <IsActive>false</IsActive> <IsRampingUp>false</IsRampingUp> <IsInSetPoint>true</IsInSetPoint> </HeaterState> - <SetPoint>0</SetPoint> + <SetPoint>130</SetPoint> </TechItem> <TechItem xsi:type="ProcessParametersItem"> <ID>2eed9e1e-31cd-4dc4-9d44-dd35798ff733</ID> @@ -1764,9 +1774,9 @@ <Angle>0</Angle> <ItemGuid>78482AA4-3DF6-421F-944C-64328D3C3EF2</ItemGuid> <ColorNumber>-14774017</ColorNumber> - <UpdateInterval>10</UpdateInterval> <OptimalRangeMinimum>0</OptimalRangeMinimum> <OptimalRangeMaximum>70</OptimalRangeMaximum> + <UpdateInterval>10</UpdateInterval> <IsSetToDefault>true</IsSetToDefault> </TechItem> </Items> @@ -1783,11 +1793,11 @@ <Angle>0</Angle> <ItemGuid>A499E5E0-A812-4032-8F96-B38C6762C4BD</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>3600</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>aae29286-81b3-476a-9f58-c0fd246cae96</ID> @@ -1798,11 +1808,11 @@ <Angle>0</Angle> <ItemGuid>F33667BD-D9FA-4DC7-BC2C-0E89E60AE4BE</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>3600</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="TextItem"> <ID>7d94c7c4-1288-4f9d-b0e6-a06794829642</ID> @@ -1885,11 +1895,11 @@ <Angle>0</Angle> <ItemGuid>1F0F907A-EC16-4386-AFC8-B2B156F2A822</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>3600</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="TextItem"> <ID>1c254a92-c075-453f-9667-cdcc91cf8e6a</ID> @@ -1922,11 +1932,11 @@ <Angle>0</Angle> <ItemGuid>6B1DF4B0-BCC2-400C-A3B7-31C5119A55BB</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>3600</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="TextItem"> <ID>0bef6e9d-6da0-4f06-9e1a-c00142bde4c1</ID> @@ -1959,11 +1969,11 @@ <Angle>0</Angle> <ItemGuid>19645882-6587-4A50-BD85-AF06617DC654</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>3</DecimalPlaces> <Duration>3600</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>3</DecimalPlaces> </TechItem> <TechItem xsi:type="MonitorItem"> <ID>39f6a02c-c4d9-47d0-b92d-bdea0ed5d3ce</ID> @@ -1994,7 +2004,7 @@ <Width>244</Width> <Height>127.67256637168146</Height> <Angle>0</Angle> - <ItemGuid>7F9C5DE0-9E24-494D-841F-976DB440DBFD</ItemGuid> + <ItemGuid>481228F8-BA5F-4CE8-9384-EC3ACE80DDDC</ItemGuid> <ColorNumber>-1</ColorNumber> </TechItem> <TechItem xsi:type="ValveItem"> @@ -2031,11 +2041,11 @@ <Angle>0</Angle> <ItemGuid>96B89605-F999-43FE-A1CD-2645BFB33A36</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100000</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>3d0f66be-0002-403d-8d4b-0d49d85c0570</ID> @@ -2046,11 +2056,11 @@ <Angle>0</Angle> <ItemGuid>D126DB23-784B-4F0C-8F88-D89A65A7549F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>16384</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>6ce9bf4a-e710-4bc6-bcc1-e8055b77530c</ID> @@ -2061,11 +2071,11 @@ <Angle>0</Angle> <ItemGuid>FC60060A-3736-4910-B41A-FF6DABDF0E9E</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100000</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>da0aa379-4643-40cb-b990-45574e5545df</ID> @@ -2076,11 +2086,11 @@ <Angle>0</Angle> <ItemGuid>10102BC3-0EAE-47FF-A8E5-8640780CAA3D</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>16384</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>09b31ecb-8eaf-4c70-8057-1a11b5f10bad</ID> @@ -2091,11 +2101,11 @@ <Angle>0</Angle> <ItemGuid>89B7B89D-8050-4188-B568-35B1910CFB6F</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100000</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="SingleGraphItem"> <ID>2a970ff9-b593-4df4-977f-7d29ce25d0c6</ID> @@ -2106,11 +2116,11 @@ <Angle>0</Angle> <ItemGuid>84CF23C9-D20D-4C08-BE1D-80201FC43C06</ItemGuid> <ColorNumber>-14774017</ColorNumber> + <DecimalPlaces>1</DecimalPlaces> <Duration>10</Duration> <Min>0</Min> <Max>100</Max> <UseAutoRange>true</UseAutoRange> - <DecimalPlaces>1</DecimalPlaces> </TechItem> <TechItem xsi:type="PidItem"> <ID>eebe8aa9-cff0-45ef-b1dd-d71cbe3b2947</ID> @@ -2157,5 +2167,5 @@ </Items> </MachineTechViewProjectTab> </Tabs> - <SelectedTabIndex>2</SelectedTabIndex> + <SelectedTabIndex>0</SelectedTabIndex> </MachineTechViewProject>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/App.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/App.config index a6a2b7fa9..8b30e609b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/App.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/App.config @@ -1,2 +1,75 @@ <?xml version="1.0" encoding="utf-8"?> -<configuration />
\ No newline at end of file +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.4.2.0" newVersion="1.4.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Console" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-3.19.8.16603" newVersion="3.19.8.16603" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ColorCaptureSettings.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ColorCaptureSettings.cs new file mode 100644 index 000000000..63ed247ef --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ColorCaptureSettings.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.MachineStudio.ColorCapture.Models; +using Tango.Settings; + +namespace Tango.MachineStudio.ColorCapture +{ + public class ColorCaptureSettings : SettingsBase + { + public CaptureConfig Config { get; set; } + + public ColorCaptureSettings() + { + Config = new CaptureConfig(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs index af34e038d..93a5c07ab 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs @@ -16,7 +16,7 @@ namespace Tango.MachineStudio.ColorCapture.Controls set { SetValue(ColumnsProperty, value); } } public static readonly DependencyProperty ColumnsProperty = - DependencyProperty.Register("Columns", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0)); + DependencyProperty.Register("Columns", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0, (d, e) => (d as IndexedUniformGrid).Init())); public int Rows { @@ -24,7 +24,7 @@ namespace Tango.MachineStudio.ColorCapture.Controls set { SetValue(RowsProperty, value); } } public static readonly DependencyProperty RowsProperty = - DependencyProperty.Register("Rows", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0)); + DependencyProperty.Register("Rows", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0, (d, e) => (d as IndexedUniformGrid).Init())); public IndexedUniformGrid() { @@ -33,6 +33,14 @@ namespace Tango.MachineStudio.ColorCapture.Controls private void IndexedUniformGrid_Loaded(object sender, RoutedEventArgs e) { + Init(); + } + + private void Init() + { + ColumnDefinitions.Clear(); + RowDefinitions.Clear(); + for (int i = 0; i < Columns; i++) { ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) }); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs index dd32cde93..63ce7035e 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs @@ -19,7 +19,7 @@ namespace Tango.MachineStudio.ColorCapture.Graph AddDataSeries(new WpfDataSeries() { StrokeThickness = 1, - Stroke = Colors.Black, + Stroke = Colors.DodgerBlue, }); var renderer = new GraphScrollingRenderer<WpfDataSeries, DoubleDataPoint, DoubleDataPoint>() diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/BenchmarkItem.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/BenchmarkItem.cs new file mode 100644 index 000000000..d7d33e437 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/BenchmarkItem.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; +using Tango.Core; +using Tango.PMR.TCC; + +namespace Tango.MachineStudio.ColorCapture.Models +{ + public class BenchmarkItem : ExtendedObject + { + private int _Red; + public int Red + { + get { return _Red; } + set { _Red = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(Color)); } + } + + private int _Green; + public int Green + { + get { return _Green; } + set { _Green = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(Color)); } + } + + private int _Blue; + public int Blue + { + get { return _Blue; } + set { _Blue = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(Color)); } + } + + private double _L; + public double L + { + get { return _L; } + set { _L = value; RaisePropertyChangedAuto(); } + } + + private double _A; + public double A + { + get { return _A; } + set { _A = value; RaisePropertyChangedAuto(); } + } + + private double _B; + public double B + { + get { return _B; } + set { _B = value; RaisePropertyChangedAuto(); } + } + + public int Index { get; private set; } + + public Color Color + { + get { return Color.FromArgb(255, (byte)Red, (byte)Green, (byte)Blue); } + } + + public static BenchmarkItem FromDetectionBenchmark(DetectionBenchmark benchmark, int index) + { + BenchmarkItem item = new BenchmarkItem(); + + item.Red = benchmark.Red; + item.Green = benchmark.Green; + item.Blue = benchmark.Blue; + + item.L = benchmark.L; + item.A = benchmark.A; + item.B = benchmark.B; + + item.Index = index; + + return item; + } + + public DetectionBenchmark ToDetectionBenchmark() + { + DetectionBenchmark item = new DetectionBenchmark(); + + item.Red = Red; + item.Green = Green; + item.Blue = Blue; + + item.L = L; + item.A = A; + item.B = B; + + return item; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureConfig.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureConfig.cs new file mode 100644 index 000000000..c1f5d4f48 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureConfig.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.Helpers; + +namespace Tango.MachineStudio.ColorCapture.Models +{ + public class CaptureConfig : ExtendedObject + { + private int _columns; + public int Columns + { + get { return _columns; } + set { _columns = value; RaisePropertyChangedAuto(); } + } + + private int _rows; + public int Rows + { + get { return _rows; } + set { _rows = value; RaisePropertyChangedAuto(); } + } + + private int _targetIndex; + public int TargetIndex + { + get { return _targetIndex; } + set { _targetIndex = value; RaisePropertyChangedAuto(); } + } + + private String _samplesFolder; + public String SamplesFolder + { + get { return _samplesFolder; } + set { _samplesFolder = value; RaisePropertyChangedAuto(); } + } + + private String _benchmarksFile; + public String BenchmarksFile + { + get { return _benchmarksFile; } + set { _benchmarksFile = value; RaisePropertyChangedAuto(); } + } + + private String _templateFile; + public String TemplateFile + { + get { return _templateFile; } + set { _templateFile = value; RaisePropertyChangedAuto(); } + } + + private int _sampleWidth; + public int SampleWidth + { + get { return _sampleWidth; } + set { _sampleWidth = value; RaisePropertyChangedAuto(); } + } + + private int _sampleHeight; + public int SampleHeight + { + get { return _sampleHeight; } + set { _sampleHeight = value; RaisePropertyChangedAuto(); } + } + + public CaptureConfig() + { + Columns = 10; + Rows = 11; + TargetIndex = 89; + SampleWidth = 300; + SampleHeight = 330; + SamplesFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "TCC Samples"); + BenchmarksFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "TCC", "benchmarks_rgb_lab.csv"); + TemplateFile = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "TCC", "template.bmp"); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureItem.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureItem.cs new file mode 100644 index 000000000..66fe7d7af --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Models/CaptureItem.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace Tango.MachineStudio.ColorCapture.Models +{ + public class CaptureItem + { + public DateTime Time { get; set; } + + [JsonIgnore] + public String Folder { get; set; } + + [JsonIgnore] + public String Image { get; set; } + + public Color CapturedColor { get; set; } + public Color ProcessedColor { get; set; } + public Color RefColor { get; set; } + + public double RefL { get; set; } + public double RefA { get; set; } + public double RefB { get; set; } + + public double DeltaE { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj index 4d0c0fae5..1679f2af9 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj @@ -53,6 +53,15 @@ <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath> </Reference> + <Reference Include="Microsoft.WindowsAPICodePack.Shell, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.Shell.dll</HintPath> + </Reference> + <Reference Include="Microsoft.WindowsAPICodePack.ShellExtensions, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\Microsoft.WindowsAPICodePack-Shell.1.1.0.0\lib\Microsoft.WindowsAPICodePack.ShellExtensions.dll</HintPath> + </Reference> + <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> + <HintPath>..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.Data" /> @@ -87,10 +96,14 @@ <Compile Include="..\..\..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="ColorCaptureSettings.cs" /> <Compile Include="ColorLabModule.cs" /> <Compile Include="Controls\ColorMatrixControl.cs" /> <Compile Include="Controls\IndexedUniformGrid.cs" /> <Compile Include="Graph\WpfGraphController.cs" /> + <Compile Include="Models\BenchmarkItem.cs" /> + <Compile Include="Models\CaptureConfig.cs" /> + <Compile Include="Models\CaptureItem.cs" /> <Compile Include="Properties\AssemblyInfo.cs"> <SubType>Code</SubType> </Compile> @@ -113,6 +126,7 @@ <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> + <None Include="App.config" /> <None Include="packages.config" /> <None Include="Properties\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> @@ -140,6 +154,14 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> + <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj"> + <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> + <Name>Tango.Logging</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.PMR\Tango.PMR.csproj"> <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> <Name>Tango.PMR</Name> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml index 0a2ebbca8..87a3f1bf2 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml @@ -30,10 +30,10 @@ </ItemsControl.ItemTemplate> </ItemsControl> <controls:IndexedUniformGrid Columns="{TemplateBinding Columns}" Rows="{TemplateBinding Rows}"> - <Image Source="Images/topLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="0" /> - <Image Source="Images/topRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="0" /> - <Image Source="Images/bottomLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="{TemplateBinding Rows}" /> - <Image Source="Images/bottomRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="{TemplateBinding Rows}" /> + <Image Source="/Tango.MachineStudio.ColorCapture;component/Images/topLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="0" /> + <Image Source="/Tango.MachineStudio.ColorCapture;component/Images/topRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="0" /> + <Image Source="/Tango.MachineStudio.ColorCapture;component/Images/bottomLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="{TemplateBinding Rows}" /> + <Image Source="/Tango.MachineStudio.ColorCapture;component/Images/bottomRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="{TemplateBinding Rows}" /> </controls:IndexedUniformGrid> </Grid> </Border> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs index f21c403de..5b9d20bc4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs @@ -1,19 +1,28 @@ using ColorMine.ColorSpaces; using ColorMine.ColorSpaces.Comparisons; +using Microsoft.Win32; +using Microsoft.WindowsAPICodePack.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media; using System.Windows.Media.Imaging; +using Tango.Core; using Tango.Core.Commands; +using Tango.CSV; +using Tango.Logging; using Tango.MachineStudio.ColorCapture.Graph; +using Tango.MachineStudio.ColorCapture.Models; using Tango.MachineStudio.Common; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.Video; +using Tango.PMR.TCC; +using Tango.Settings; using Tango.TCC.BL; using Tango.Video.DirectCapture; @@ -24,6 +33,10 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels private INotificationProvider _notification; private CardDetector _cardDetector; private int _sampleCounter; + private bool _abort; + private BitmapSource _last_original_source; + private DetectionOutput _last_detection_output; + private byte[] templateBitmap; public IVideoCaptureProvider VideoProvider { get; set; } @@ -44,7 +57,7 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels public BitmapSource DetectedSource { get { return _detectedSource; } - set { _detectedSource = value; RaisePropertyChangedAuto(); } + set { _detectedSource = value; RaisePropertyChangedAuto(); InvokeUI(() => CreateSnapshotCommand.RaiseCanExecuteChanged()); } } private ObservableCollection<Color> _colors; @@ -89,18 +102,60 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels set { _measureB = value; RaisePropertyChangedAuto(); } } + public double DeltaE { get; set; } public WpfGraphController CaptureDeltaEController { get; set; } public RelayCommand ToggleCameraCommand { get; set; } + public SynchronizedObservableCollection<CaptureItem> CaptureItems { get; set; } + + private ObservableCollection<BenchmarkItem> _benchmarks; + public ObservableCollection<BenchmarkItem> Benchmarks + { + get { return _benchmarks; } + set { _benchmarks = value; RaisePropertyChangedAuto(); } + } + + private CaptureConfig _config; + public CaptureConfig Config + { + get { return _config; } + set { _config = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand ImportBenchmarksCommand { get; set; } + + public RelayCommand ExportBenchmarksCommand { get; set; } + + public RelayCommand CreateSnapshotCommand { get; set; } + + public RelayCommand<CaptureItem> OpenCaptureItemCommand { get; set; } + + public RelayCommand SelectSamplesFolderCommand { get; set; } + + public RelayCommand SelectBenchmarksFileCommand { get; set; } + + public RelayCommand SelectTemplateFileCommand { get; set; } + public MainViewVM() { + Config = new CaptureConfig(); + CaptureItems = new SynchronizedObservableCollection<CaptureItem>(); + Benchmarks = new ObservableCollection<BenchmarkItem>(); _cardDetector = new CardDetector(); ToggleCameraCommand = new RelayCommand(ToggleCamera); CaptureDeltaEController = new WpfGraphController(); CaptureDeltaEController.Range.AutoY = true; CaptureDeltaEController.Range.MaximumX = 1000; + + ImportBenchmarksCommand = new RelayCommand(OpenBenchmarksFile); + ExportBenchmarksCommand = new RelayCommand(SaveBenchmarksFile); + CreateSnapshotCommand = new RelayCommand(CreateSnapshot, () => DetectedSource != null); + OpenCaptureItemCommand = new RelayCommand<CaptureItem>(OpenCaptureItem); + SelectSamplesFolderCommand = new RelayCommand(SelectSamplesFolder); + SelectBenchmarksFileCommand = new RelayCommand(SelectBenchmarkFile); + SelectTemplateFileCommand = new RelayCommand(SelectTemplateFile); } public MainViewVM(IVideoCaptureProvider videoProvider, INotificationProvider notificationProvider) : this() @@ -110,16 +165,165 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels SelectedVideoDevice = videoProvider.AvailableCaptureDevices.FirstOrDefault(); } + private void SelectTemplateFile() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "Bitmap Files|*.bmp"; + if (dlg.ShowDialog().Value) + { + templateBitmap = File.ReadAllBytes(Config.TemplateFile); + Config.TemplateFile = dlg.FileName; + } + } + + private void SelectBenchmarkFile() + { + OpenBenchmarksFile(); + } + + private void SelectSamplesFolder() + { + CommonOpenFileDialog dlg = new CommonOpenFileDialog(); + dlg.Title = "Select samples folder."; + dlg.IsFolderPicker = true; + if (dlg.ShowDialog() == CommonFileDialogResult.Ok) + { + Config.SamplesFolder = dlg.FileName; + } + } + + private void OpenCaptureItem(CaptureItem item) + { + using (_notification.PushTaskItem("Opening snapshot folder...")) + { + Process.Start("explorer.exe", string.Format("/select,\"{0}\"", item.Image)); + } + } + + private void CreateSnapshot() + { + try + { + DateTime now = DateTime.Now; + + Directory.CreateDirectory(Config.SamplesFolder); + + String sample_folder = Config.SamplesFolder + "\\" + now.ToFileName(); + Directory.CreateDirectory(sample_folder); + + String rectified_file = sample_folder + "\\rectified.bmp"; + DetectedSource.SaveBmpFile(rectified_file); + + String original_file = sample_folder + "\\source.bmp"; + _last_original_source.SaveBmpFile(original_file); + + String means_file = sample_folder + "\\means.bmp"; + var bitmap = ColorDetector.DetectionOutputToImage(new DetectionInput() + { + Columns = Config.Columns, + Rows = Config.Rows, + TargetIndex = Config.TargetIndex + + }, _last_detection_output, Config.SampleWidth, Config.SampleHeight); + + bitmap.Save(means_file); + + String capture_item_file = sample_folder + "\\info.txt"; + + var rgb = new Lab(MeasureL, _measureA, _measureB).ToRgb(); + Color refColor = Color.FromArgb(255, (byte)rgb.R, (byte)rgb.G, (byte)rgb.B); + + var captureItem = new CaptureItem() + { + Image = rectified_file, + CapturedColor = CapturedColor, + ProcessedColor = ProcessedColor, + RefColor = refColor, + DeltaE = DeltaE, + RefL = MeasureL, + RefA = MeasureA, + RefB = MeasureB, + Time = now, + Folder = sample_folder, + }; + + File.WriteAllText(capture_item_file, captureItem.ToJsonString()); + + CaptureItems.Insert(0, captureItem); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error in color capture snapshot save method."); + _notification.ShowError($"An error occurred while trying to create the snapshot. Please try again.\n{ex.Message}"); + } + } + + private void SaveBenchmarksFile() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Filter = "CSV Files|*.csv"; + if (dlg.ShowDialog().Value) + { + try + { + ExportBenchmarks(dlg.FileName); + _notification.ShowInfo("Benchmarks successfully saved."); + } + catch (Exception ex) + { + _notification.ShowError($"An error occurred while trying to export the benchmark file.\n{ex.FlattenMessage()}"); + } + } + } + + private void OpenBenchmarksFile() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "CSV Files|*.csv"; + if (dlg.ShowDialog().Value) + { + try + { + ImportBenchmarks(dlg.FileName); + _notification.ShowInfo("Benchmarks successfully loaded."); + } + catch (Exception ex) + { + _notification.ShowError($"An error occurred while trying to import the benchmark file.\n{ex.FlattenMessage()}"); + } + } + } + + private void ExportBenchmarks(String file) + { + ColorDetector.SaveBenchmarks(file, Benchmarks.ToList().Select(x => x.ToDetectionBenchmark())); + } + + private void ImportBenchmarks(String file) + { + var marks = ColorDetector.LoadBenchmarks(file).ToList(); + var benchmarks = marks.Select(x => BenchmarkItem.FromDetectionBenchmark(x, marks.IndexOf(x))).ToList(); + Benchmarks = new ObservableCollection<BenchmarkItem>(benchmarks); + Config.BenchmarksFile = file; + } + private void ToggleCamera() { if (SelectedVideoDevice != null) { if (SelectedVideoDevice.IsStarted) { + _abort = true; SelectedVideoDevice.Stop(); + ProcessedColor = System.Windows.Media.Colors.Transparent; + CapturedColor = System.Windows.Media.Colors.Transparent; + Colors = null; + DetectedSource = null; + CaptureDeltaEController.Clear(); } else { + _abort = false; SelectedVideoDevice.Resolution = new Resolution(1280, 720); SelectedVideoDevice.Start(); } @@ -140,15 +344,28 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels } } - double deltaE = 0; private async void OnVideoFrameReceived(object sender, Video.DirectShow.EventArguments.FrameReceivedEventArgs args) { + if (_abort) return; + if (_cardDetector.CanDetect) { - var result = await _cardDetector.Detect(args.BitmapSource); + var result = await _cardDetector.Detect(args.BitmapSource, new CardDetectionConfig() + { + Benchmarks = Benchmarks.ToList().Select(x => x.ToDetectionBenchmark()).ToList(), + Columns = Config.Columns, + Rows = Config.Rows, + DesiredBitmapWidth = Config.SampleWidth, + DesiredBitmapHeight = Config.SampleHeight, + TargetIndex = Config.TargetIndex, + TemplateBitmapBytes = templateBitmap, + }); if (result.IsDetected) { + _last_original_source = result.Source; + _last_detection_output = result.ColorDetectionOutput; + DetectedSource = result.DetectedBitmap; if (Colors == null) @@ -166,20 +383,54 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels CapturedColor = Color.FromArgb(255, (byte)result.ColorDetectionOutput.RawColor.R, (byte)result.ColorDetectionOutput.RawColor.G, (byte)result.ColorDetectionOutput.RawColor.B); ProcessedColor = Color.FromArgb(255, (byte)result.ColorDetectionOutput.ProcessedColor.R, (byte)result.ColorDetectionOutput.ProcessedColor.G, (byte)result.ColorDetectionOutput.ProcessedColor.B); - }); - //calculate delta E. - Lab measureLab = new Lab(MeasureL, MeasureA, MeasureB); - deltaE = measureLab.Compare(new Rgb(ProcessedColor.R, ProcessedColor.G, ProcessedColor.B), new CieDe2000Comparison()); + //calculate delta E. + Lab measureLab = new Lab(MeasureL, MeasureA, MeasureB); + DeltaE = measureLab.Compare(new Rgb(ProcessedColor.R, ProcessedColor.G, ProcessedColor.B), new CieDe2000Comparison()); + }); } } - CaptureDeltaEController.PushData(_sampleCounter++, deltaE); + CaptureDeltaEController.PushData(_sampleCounter++, DeltaE); } public override void OnApplicationReady() { + Config = SettingsManager.Default.GetOrCreate<ColorCaptureSettings>().Config; + + //Load benchmarks. + if (File.Exists(Config.BenchmarksFile)) + { + try + { + ImportBenchmarks(Config.BenchmarksFile); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading benchmarks."); + } + } + else + { + LogManager.Log("Could not locate benchmarks csv file.", LogCategory.Warning); + } + + //Load template bitmap. + if (File.Exists(Config.TemplateFile)) + { + templateBitmap = File.ReadAllBytes(Config.TemplateFile); + } + else + { + LogManager.Log("Could not locate template bitmap file.", LogCategory.Warning); + } + } + public override void OnShuttingDown() + { + base.OnShuttingDown(); + SettingsManager.Default.GetOrCreate<ColorCaptureSettings>().Config = Config; + SettingsManager.Default.Save(); } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml index 259e3160e..c1555fbcd 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml @@ -10,190 +10,502 @@ xmlns:graphX="clr-namespace:RealTimeGraphX.WPF.Surfaces;assembly=RealTimeGraphX.WPF" xmlns:componentsX="clr-namespace:RealTimeGraphX.WPF.Components;assembly=RealTimeGraphX.WPF" xmlns:controls="clr-namespace:Tango.MachineStudio.ColorCapture.Controls" + xmlns:sharedControls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:realtimeGraphX="clr-namespace:RealTimeGraphX.WPF.Surfaces;assembly=RealTimeGraphX.WPF" xmlns:global="clr-namespace:Tango.MachineStudio.ColorCapture" xmlns:local="clr-namespace:Tango.MachineStudio.ColorCapture.Views" mc:Ignorable="d" - d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - <Grid Margin="20"> - <Grid.RowDefinitions> - <RowDefinition Height="247*"/> - <RowDefinition Height="113*"/> - </Grid.RowDefinitions> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="1*"/> - <ColumnDefinition Width="1*"/> - </Grid.ColumnDefinitions> + d:DesignHeight="1080" d:DesignWidth="1920" Background="#202020" Foreground="#BBBBBB" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + <UserControl.Resources> + <SolidColorBrush x:Key="Foreground" Color="#BBBBBB" /> + <SolidColorBrush x:Key="Background" Color="#202020" /> + <SolidColorBrush x:Key="Accent" Color="{StaticResource AccentColor}" /> + <SolidColorBrush x:Key="Red" Color="#FF5F5F" /> + <SolidColorBrush x:Key="Green" Color="#68E46E" /> + <SolidColorBrush x:Key="Blue" Color="#64B8EC" /> + <SolidColorBrush x:Key="BorderBrush" Color="#3E3E3E" /> + <SolidColorBrush x:Key="LightBackground" Color="#303030" /> + </UserControl.Resources> - <Border RenderOptions.BitmapScalingMode="Fant"> + <Grid Margin="20"> + <TabControl Background="{StaticResource Background}" Foreground="{StaticResource Foreground}"> + <TabControl.Resources> + <Style TargetType="TabPanel"> + <Setter Property="HorizontalAlignment" Value="Center"/> + </Style> + <Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}"> + <Setter Property="Padding" Value="20,2"></Setter> + </Style> + </TabControl.Resources> + <TabItem Header="CAPTURE" Foreground="{StaticResource Foreground}"> + <TabItem.HeaderTemplate> + <DataTemplate> + <TextBlock Text="{Binding}" FontSize="25" VerticalAlignment="Center"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TabItem},Path=IsSelected}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource Accent}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DataTemplate> + </TabItem.HeaderTemplate> <Grid> - <DockPanel> - <DockPanel DockPanel.Dock="Bottom" Margin="60 0" TextElement.FontSize="25"> - <TextBlock VerticalAlignment="Center">Capture Device</TextBlock> - <Button DockPanel.Dock="Right" Command="{Binding ToggleCameraCommand}" CommandParameter="{Binding}" Style="{StaticResource MaterialDesignFloatingActionMiniButton}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="60" Height="60" Padding="0"> - <materialDesign:PackIcon Width="40" Height="40"> - <materialDesign:PackIcon.Style> - <Style TargetType="materialDesign:PackIcon"> - <Setter Property="Kind" Value="Play"></Setter> + <Grid.RowDefinitions> + <RowDefinition Height="600"/> + <RowDefinition Height="1*"/> + </Grid.RowDefinitions> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="800"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + <Border RenderOptions.BitmapScalingMode="Fant"> + <Grid> + <DockPanel> + <DockPanel DockPanel.Dock="Top" TextElement.FontSize="16"> + <TextBlock VerticalAlignment="Center" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold">Capture Device</TextBlock> + <Button DockPanel.Dock="Right" Command="{Binding ToggleCameraCommand}" CommandParameter="{Binding}" Style="{StaticResource MaterialDesignFlatButton}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="50" Height="50" Padding="0"> + <materialDesign:PackIcon Width="40" Height="40"> + <materialDesign:PackIcon.Style> + <Style TargetType="materialDesign:PackIcon"> + <Setter Property="Kind" Value="Play"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True"> + <Setter Property="Kind" Value="Stop"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False"> + <Setter Property="Kind" Value="Play"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </materialDesign:PackIcon.Style> + </materialDesign:PackIcon> + </Button> + <ComboBox FontWeight="SemiBold" Margin="20 0" ItemsSource="{Binding VideoProvider.AvailableCaptureDevices}" SelectedItem="{Binding SelectedVideoDevice}" DisplayMemberPath="Device" BorderBrush="{StaticResource Foreground}"></ComboBox> + </DockPanel> + + <Border Padding="2" Background="{StaticResource LightBackground}" BorderThickness="1" BorderBrush="{StaticResource Accent}" Margin="0 10 0 0"> + <Image Source="{Binding SelectedVideoDevice.VideoSource,Mode=OneWay,IsAsync=True}" Stretch="Fill"> + <Image.Style> + <Style TargetType="Image"> + <Setter Property="Visibility" Value="Hidden"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True"> + <Setter Property="Visibility" Value="Visible"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False"> + <Setter Property="Visibility" Value="Hidden"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </Image.Style> + </Image> + </Border> + </DockPanel> + </Grid> + </Border> + + <Grid Grid.Column="1" Margin="200 60 0 0" HorizontalAlignment="Left"> + <Grid.RowDefinitions> + <RowDefinition Height="180*"/> + <RowDefinition Height="130*"/> + </Grid.RowDefinitions> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="500"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + <TextBlock Margin="0 -20 0 0" FontWeight="SemiBold" Foreground="{StaticResource Accent}">Rectified Image</TextBlock> + <Border Padding="2" Background="{StaticResource LightBackground}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="1" BorderBrush="{StaticResource Accent}"> + <Image Source="{Binding DetectedSource,Mode=OneWay,IsAsync=True}" Stretch="Fill"></Image> + </Border> + + <TextBlock Grid.Column="1" Margin="0 -20 0 0" FontWeight="SemiBold" Foreground="{StaticResource Accent}">Calculated Averages</TextBlock> + <Border Padding="2" HorizontalAlignment="Left" Grid.Column="1" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="1" BorderBrush="{StaticResource Accent}"> + <controls:ColorMatrixControl Colors="{Binding Colors,Mode=OneWay}" Columns="10" Rows="11" Background="{StaticResource LightBackground}" /> + </Border> + </Grid> + + <Grid Grid.Row="1"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="500"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + + <Grid Height="120" VerticalAlignment="Top" HorizontalAlignment="Left"> + <DockPanel> + <TextBlock Margin="0 10 0 0" DockPanel.Dock="Top" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" FontSize="16">Captured Color</TextBlock> + <DockPanel Margin="0 5 0 0" TextElement.FontSize="16"> + <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55"> + <TextBlock Foreground="{StaticResource Red}"><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.R,Mode=OneWay}"></Run></TextBlock> + <TextBlock Foreground="{StaticResource Green}"><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.G,Mode=OneWay}"></Run></TextBlock> + <TextBlock Foreground="{StaticResource Blue}"><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.B,Mode=OneWay}"></Run></TextBlock> + </UniformGrid> + <Border Padding="2" Width="300" BorderThickness="1" BorderBrush="{StaticResource Accent}" Background="{StaticResource LightBackground}"> + <Rectangle> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding CapturedColor,Mode=OneWay}" /> + </Rectangle.Fill> + </Rectangle> + </Border> + </DockPanel> + </DockPanel> + </Grid> + + <Grid Height="120" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1"> + <DockPanel> + <TextBlock Margin="0 10 0 0" DockPanel.Dock="Top" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" FontSize="16">Processed Color</TextBlock> + <DockPanel Margin="0 5 0 0" TextElement.FontSize="16"> + <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55"> + <TextBlock Foreground="{StaticResource Red}"><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.R,Mode=OneWay}"></Run></TextBlock> + <TextBlock Foreground="{StaticResource Green}"><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.G,Mode=OneWay}"></Run></TextBlock> + <TextBlock Foreground="{StaticResource Blue}"><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.B,Mode=OneWay}"></Run></TextBlock> + </UniformGrid> + <Border Padding="2" Width="300" BorderThickness="1" BorderBrush="{StaticResource Accent}" Background="{StaticResource LightBackground}"> + <Rectangle> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding ProcessedColor,Mode=OneWay}" /> + </Rectangle.Fill> + </Rectangle> + </Border> + </DockPanel> + </DockPanel> + </Grid> + + <DockPanel VerticalAlignment="Bottom" Grid.ColumnSpan="2" TextElement.FontSize="16"> + <TextBlock HorizontalAlignment="Center" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" FontSize="16">Delta E Reference Point</TextBlock> + <UniformGrid Columns="3" Margin="20 0 70 0"> + <DockPanel> + <TextBlock FontWeight="SemiBold">L:</TextBlock> + <mahapps:NumericUpDown BorderBrush="{StaticResource BorderBrush}" MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureL,UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="{StaticResource LightBackground}" FontSize="16" Foreground="{StaticResource Accent}" BorderThickness="1" /> + </DockPanel> + + <DockPanel> + <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">A:</TextBlock> + <mahapps:NumericUpDown BorderBrush="{StaticResource BorderBrush}" MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureA,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="{StaticResource LightBackground}" FontSize="16" Foreground="{StaticResource Accent}" BorderThickness="1" /> + </DockPanel> + + <DockPanel> + <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">B:</TextBlock> + <mahapps:NumericUpDown BorderBrush="{StaticResource BorderBrush}" MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureB,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="{StaticResource LightBackground}" FontSize="16" Foreground="{StaticResource Accent}" BorderThickness="1" /> + </DockPanel> + </UniformGrid> + </DockPanel> + </Grid> + </Grid> + </Grid> + + <Grid Grid.Row="1" Margin="0 40 0 0"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="800"/> + <ColumnDefinition Width="1*"/> + </Grid.ColumnDefinitions> + <DockPanel> + <DockPanel DockPanel.Dock="Top" LastChildFill="False"> + <TextBlock VerticalAlignment="Center" DockPanel.Dock="Left" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" FontSize="16">Snapshots</TextBlock> + <Button Command="{Binding CreateSnapshotCommand}" Height="35" DockPanel.Dock="Right" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1"> + <StackPanel Orientation="Horizontal"> + <materialDesign:PackIcon Kind="ChevronDoubleDown" VerticalAlignment="Center" /> + <TextBlock Margin="10 0 0 0">Create Snapshot</TextBlock> + </StackPanel> + </Button> + </DockPanel> + <sharedControls:DoubleClickDataGrid DoubleClickCommand="{Binding OpenCaptureItemCommand}" Style="{StaticResource {x:Type DataGrid}}" ItemsSource="{Binding CaptureItems}" GridLinesVisibility="None" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="False" IsReadOnly="True" Margin="0 10 0 0" Background="{StaticResource LightBackground}" Grid.ColumnSpan="2" TextElement.Foreground="Gainsboro" BorderBrush="{StaticResource Accent}" BorderThickness="1"> + <DataGrid.RowStyle> + <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + <Setter Property="BorderBrush" Value="#202020"></Setter> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Setter Property="BorderThickness" Value="0 0 0 1"></Setter> <Style.Triggers> - <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True"> - <Setter Property="Kind" Value="Stop"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False"> - <Setter Property="Kind" Value="Play"></Setter> - </DataTrigger> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + <Setter Property="Cursor" Value="Hand"></Setter> + </Trigger> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> </Style.Triggers> </Style> - </materialDesign:PackIcon.Style> - </materialDesign:PackIcon> - </Button> - <ComboBox FontWeight="SemiBold" Margin="20 0 20 0" ItemsSource="{Binding VideoProvider.AvailableCaptureDevices}" SelectedItem="{Binding SelectedVideoDevice}" DisplayMemberPath="Device"></ComboBox> - </DockPanel> + </DataGrid.RowStyle> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + </Style.Triggers> + </Style> + </DataGrid.CellStyle> + <DataGrid.ColumnHeaderStyle> + <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + </Style> + </DataGrid.ColumnHeaderStyle> + <DataGrid.Columns> + <DataGridTemplateColumn Header="#" Width="50"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Image Width="30" Height="30" Source="{Binding Image}"></Image> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="TIME" Binding="{Binding Time,StringFormat='HH:mm:ss.fff'}" /> + <DataGridTemplateColumn Header="REF" Width="80"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Rectangle Width="60"> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding RefColor}"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="CAPTURED" Width="90"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Rectangle Width="60"> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding CapturedColor}"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTemplateColumn Header="PROCESSED" Width="90"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Rectangle Width="60"> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding ProcessedColor}"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + + <DataGridTextColumn Header="REF L" Width="70" Binding="{Binding RefL}" /> + <DataGridTextColumn Header="REF A" Width="70" Binding="{Binding RefA}" /> + <DataGridTextColumn Header="REF B" Width="70" Binding="{Binding RefB}" /> + <DataGridTextColumn Header="DELTA E" Binding="{Binding DeltaE}" /> + </DataGrid.Columns> + </sharedControls:DoubleClickDataGrid> + </DockPanel> + + <DockPanel Grid.Column="1" Margin="120 0 60 0"> + <TextBlock HorizontalAlignment="Center" Margin="0 0 0 0" DockPanel.Dock="Top" Foreground="{StaticResource AccentColorBrush}" FontWeight="SemiBold" FontSize="16">Delta E Distance</TextBlock> + <Grid> + <Border Margin="0 10 0 0" Padding="20 0 20 0" BorderThickness="1" BorderBrush="#202020"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="55"/> + <ColumnDefinition Width="438*"/> + </Grid.ColumnDefinitions> - <Border BorderThickness="3" BorderBrush="#202020" Margin="40"> - <Image Source="{Binding SelectedVideoDevice.VideoSource,Mode=OneWay,IsAsync=True}" Stretch="Fill"> - <Image.Style> - <Style TargetType="Image"> - <Setter Property="Visibility" Value="Hidden"></Setter> + <Border Margin="0 1 0 2"> + <componentsX:GraphAxisControl Orientation="Vertical" Foreground="{StaticResource Accent}" FontSize="12" Surface="{Binding ElementName=Graph}" StringFormat="Δ 0.00;-#" /> + </Border> + <Border Grid.Column="1" BorderThickness="1" BorderBrush="{StaticResource Accent}" Margin="1 0 0 0" Background="{StaticResource LightBackground}"> + <Grid> + + <componentsX:GraphGridLines Foreground="#3E3E3E" /> + + <graphX:WpfGraphSurface x:Name="Graph"></graphX:WpfGraphSurface> + </Grid> + </Border> + </Grid> + </Border> + </Grid> + </DockPanel> + </Grid> + </Grid> + </Grid> + </TabItem> + <TabItem Header="BENCHMARKS" Foreground="{StaticResource Foreground}"> + <TabItem.HeaderTemplate> + <DataTemplate> + <TextBlock Text="{Binding}" FontSize="25" VerticalAlignment="Center"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TabItem},Path=IsSelected}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource Accent}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DataTemplate> + </TabItem.HeaderTemplate> + + <Grid Margin="0 20 20 20"> + <DockPanel> + <StackPanel Margin="0 10 0 0" HorizontalAlignment="Right" Orientation="Horizontal" DockPanel.Dock="Bottom"> + <Button Command="{Binding ImportBenchmarksCommand}" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1" Height="45" MinWidth="150">IMPORT</Button> + <Button Command="{Binding ExportBenchmarksCommand}" Margin="10 0 0 0" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1" Height="45" MinWidth="150">EXPORT</Button> + </StackPanel> + + <Grid> + <DataGrid BorderBrush="{StaticResource Accent}" BorderThickness="1" AlternationCount="1000" SelectionMode="Single" SelectionUnit="FullRow" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="False" IsReadOnly="True" GridLinesVisibility="None" ItemsSource="{Binding Benchmarks}" Background="{StaticResource LightBackground}"> + <DataGrid.RowStyle> + <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}"> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + <Setter Property="BorderBrush" Value="#202020"></Setter> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Setter Property="BorderThickness" Value="0 0 0 1"></Setter> <Style.Triggers> - <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True"> - <Setter Property="Visibility" Value="Visible"></Setter> - </DataTrigger> - <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False"> - <Setter Property="Visibility" Value="Hidden"></Setter> - </DataTrigger> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + <Setter Property="Cursor" Value="Hand"></Setter> + </Trigger> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + <Trigger Property="IsFocused" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> </Style.Triggers> </Style> - </Image.Style> - </Image> - </Border> - </DockPanel> - </Grid> - </Border> + </DataGrid.RowStyle> + <DataGrid.CellStyle> + <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="FocusVisualStyle" Value="{x:Null}"/> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + <Setter Property="VerticalContentAlignment" Value="Center"></Setter> + <Style.Triggers> + <Trigger Property="IsSelected" Value="True"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="Foreground" Value="{StaticResource AccentColorBrush}" /> + </Trigger> + </Style.Triggers> + </Style> + </DataGrid.CellStyle> + <DataGrid.ColumnHeaderStyle> + <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"> + <Setter Property="Foreground" Value="{StaticResource Foreground}"></Setter> + </Style> + </DataGrid.ColumnHeaderStyle> + <DataGrid.Columns> - <Grid Grid.Column="1"> - <Grid.RowDefinitions> - <RowDefinition Height="180*"/> - <RowDefinition Height="130*"/> - </Grid.RowDefinitions> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="1*"/> - <ColumnDefinition Width="1*"/> - </Grid.ColumnDefinitions> + <DataGridTextColumn Width="100" Header="#" Binding="{Binding Index}"></DataGridTextColumn> + <DataGridTextColumn Header="RED" Binding="{Binding Red}"></DataGridTextColumn> + <DataGridTextColumn Header="GREEN" Binding="{Binding Green}"></DataGridTextColumn> + <DataGridTextColumn Header="BLUE" Binding="{Binding Blue}"></DataGridTextColumn> - <Border Margin="0 40 0 0" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="3" BorderBrush="#202020"> - <Image Source="{Binding DetectedSource,Mode=OneWay,IsAsync=True}" Stretch="Fill"></Image> - </Border> + <DataGridTextColumn Header="L" Binding="{Binding L}"></DataGridTextColumn> + <DataGridTextColumn Header="A" Binding="{Binding A}"></DataGridTextColumn> + <DataGridTextColumn Header="B" Binding="{Binding B}"></DataGridTextColumn> - <Border Margin="0 40 0 0" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="3" BorderBrush="#202020" Grid.Column="1"> - <controls:ColorMatrixControl Colors="{Binding Colors,Mode=OneWay}" Columns="10" Rows="11" /> - </Border> + <DataGridTemplateColumn Header="#" Width="1*"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <Rectangle Width="200" HorizontalAlignment="Right"> + <Rectangle.Fill> + <SolidColorBrush Color="{Binding Color}"></SolidColorBrush> + </Rectangle.Fill> + </Rectangle> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + </DataGrid.Columns> + </DataGrid> + </Grid> + </DockPanel> </Grid> + </TabItem> + <TabItem Header="CONFIGURATION" Foreground="{StaticResource Foreground}"> + <TabItem.HeaderTemplate> + <DataTemplate> + <TextBlock Text="{Binding}" FontSize="25" VerticalAlignment="Center"> + <TextBlock.Style> + <Style TargetType="TextBlock"> + <Style.Triggers> + <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TabItem},Path=IsSelected}" Value="True"> + <Setter Property="Foreground" Value="{StaticResource Accent}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBlock.Style> + </TextBlock> + </DataTemplate> + </TabItem.HeaderTemplate> - <Grid Grid.Row="1"> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="1*"/> - <ColumnDefinition Width="1*"/> - </Grid.ColumnDefinitions> + <Border Width="700" Margin="0 100 0 0" VerticalAlignment="Center" TextElement.FontSize="20" Background="{StaticResource LightBackground}" Padding="20" CornerRadius="10"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="144*"/> + <ColumnDefinition Width="293*"/> + <ColumnDefinition Width="163*"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="50"/> + <RowDefinition Height="200"/> + <RowDefinition Height="705*"/> + </Grid.RowDefinitions> - <Grid Width="300" Height="190" VerticalAlignment="Top"> - <DockPanel> - <TextBlock DockPanel.Dock="Top" FontSize="20">Captured Color</TextBlock> - <DockPanel Margin="0 10 0 0" TextElement.FontSize="20"> - <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55"> - <TextBlock><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.R,Mode=OneWay}"></Run></TextBlock> - <TextBlock><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.G,Mode=OneWay}"></Run></TextBlock> - <TextBlock><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.B,Mode=OneWay}"></Run></TextBlock> - </UniformGrid> - <Border BorderThickness="1" BorderBrush="#202020"> - <Border.Background> - <SolidColorBrush Color="{Binding CapturedColor,Mode=OneWay}" /> - </Border.Background> - </Border> - </DockPanel> - </DockPanel> - </Grid> + <TextBlock VerticalAlignment="Bottom" Height="27">Columns</TextBlock> + <TextBox Grid.Column="1" Text="{Binding Config.Columns}"></TextBox> - <Grid Width="300" Height="190" VerticalAlignment="Top" Grid.Column="1"> - <DockPanel> - <TextBlock DockPanel.Dock="Top" FontSize="20">Processed Color</TextBlock> - <DockPanel Margin="0 10 0 0" TextElement.FontSize="20"> - <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55"> - <TextBlock><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.R,Mode=OneWay}"></Run></TextBlock> - <TextBlock><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.G,Mode=OneWay}"></Run></TextBlock> - <TextBlock><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.B,Mode=OneWay}"></Run></TextBlock> - </UniformGrid> - <Border BorderThickness="1" BorderBrush="#202020"> - <Border.Background> - <SolidColorBrush Color="{Binding ProcessedColor,Mode=OneWay}" /> - </Border.Background> - </Border> - </DockPanel> - </DockPanel> - </Grid> - </Grid> - </Grid> - </Grid> + <TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Rows</TextBlock> + <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Config.Rows}"></TextBox> - <Grid Grid.Row="1" Margin="0 10 0 0"> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="1*"/> - <ColumnDefinition Width="1*"/> - </Grid.ColumnDefinitions> - <DockPanel> - <TextBlock DockPanel.Dock="Top">HISTORY</TextBlock> - <DataGrid Margin="0 10 0 0" Background="Transparent" Grid.ColumnSpan="2"> - <DataGrid.Columns> - <DataGridTextColumn Header="TIME" /> - <DataGridTextColumn Header="CAPTURED COLOR" /> - <DataGridTextColumn Header="PROCESSED COLOR" /> - </DataGrid.Columns> - </DataGrid> - </DockPanel> + <TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Target Index</TextBlock> + <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Config.TargetIndex}"></TextBox> - <DockPanel Grid.Column="1" Margin="75 0 110 0"> - <Grid DockPanel.Dock="Top" TextElement.FontSize="20" Margin="0 0 0 10"> - <DockPanel> - <TextBlock HorizontalAlignment="Center">Delta E Reference Point</TextBlock> - <StackPanel Orientation="Horizontal" Margin="20 0 0 0"> - <TextBlock FontWeight="SemiBold">L:</TextBlock> - <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureL,UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" /> + <TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Sample Width</TextBlock> + <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Config.SampleWidth}"></TextBox> - <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">A:</TextBlock> - <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureA,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" /> + <TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Sample Height</TextBlock> + <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding Config.SampleHeight}"></TextBox> - <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">B:</TextBlock> - <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureB,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" /> - </StackPanel> - </DockPanel> - </Grid> - <Grid> - <Border Padding="20" BorderThickness="1" BorderBrush="#202020"> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="55"/> - <ColumnDefinition Width="438*"/> - </Grid.ColumnDefinitions> + <TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Samples Folder</TextBlock> + <TextBox Grid.Row="5" Grid.Column="1" Text="{Binding Config.SamplesFolder}" IsReadOnly="True" FontSize="10"></TextBox> + <Button Command="{Binding SelectSamplesFolderCommand}" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="5" Grid.Column="2" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1">SELECT</Button> - <Border Margin="0 1 0 2"> - <componentsX:GraphAxisControl Orientation="Vertical" FontSize="10" Surface="{Binding ElementName=Graph}" StringFormat="Δ 0.00;-#" /> - </Border> - <Border Grid.Column="1" BorderThickness="1" BorderBrush="Silver" Margin="1 0 0 0"> - <Grid> + <TextBlock Grid.Row="6" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Benchmarks</TextBlock> + <TextBox Grid.Row="6" Grid.Column="1" Text="{Binding Config.BenchmarksFile}" IsReadOnly="True" FontSize="10"></TextBox> + <Button Command="{Binding SelectBenchmarksFileCommand}" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="6" Grid.Column="2" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1">SELECT</Button> - <componentsX:GraphGridLines Foreground="Silver" /> + <TextBlock Grid.Row="7" Grid.Column="0" VerticalAlignment="Bottom" Height="27">Template</TextBlock> - <graphX:WpfGraphSurface x:Name="Graph"></graphX:WpfGraphSurface> - </Grid> - </Border> - </Grid> - </Border> + <DockPanel Grid.Row="7" Grid.Column="1"> + <TextBox Margin="0 10 0 0" DockPanel.Dock="Bottom" Text="{Binding Config.TemplateFile}" IsReadOnly="True" FontSize="10"></TextBox> + <Image Width="150" Height="150" Source="{Binding Config.TemplateFile}" Stretch="Fill"></Image> + </DockPanel> + <Button Command="{Binding SelectTemplateFileCommand}" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="7" Grid.Column="2" Style="{StaticResource MaterialDesignFlatButton}" BorderBrush="{StaticResource Accent}" BorderThickness="1">SELECT</Button> </Grid> - </DockPanel> - </Grid> - </Grid> + </Border> + </TabItem> + </TabControl> </Grid> </UserControl> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/packages.config index 37e4dd902..cf3d21396 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/packages.config @@ -7,4 +7,6 @@ <package id="MahApps.Metro" version="1.5.0" targetFramework="net461" /> <package id="MaterialDesignColors" version="1.1.2" targetFramework="net461" /> <package id="MaterialDesignThemes" version="2.3.1.953" targetFramework="net461" /> + <package id="Microsoft.WindowsAPICodePack-Shell" version="1.1.0.0" targetFramework="net461" /> + <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" /> </packages>
\ No newline at end of file diff --git a/Software/Visual_Studio/TCC/Benchmarks/benchmarks_rgb_lab.csv b/Software/Visual_Studio/TCC/Benchmarks/benchmarks_rgb_lab.csv new file mode 100644 index 000000000..141397cd4 --- /dev/null +++ b/Software/Visual_Studio/TCC/Benchmarks/benchmarks_rgb_lab.csv @@ -0,0 +1,111 @@ +Red,Green,Blue,L,A,B +0,0,0,0,0,0 +169,169,169,71.12,0.133333333,-0.051666667 +112,112,112,52.7025,-1.2625,0.225 +198,198,198,79.77166667,0.398333333,-1.038333333 +83,83,83,42.17166667,-1.261666667,-0.135 +226,226,226,87.19833333,0.988333333,-2.736666667 +54,54,54,33.112,-1.636,1.224 +255,255,255,94.06833333,1.695,-4.553333333 +26,26,26,24.80833333,-1.2,1.33 +0,0,0,0,0,0 +26,26,26,24.05,-1.5425,1.7175 +179,45,131,46.21333333,53.01666667,-15.06166667 +237,72,35,55.83,49.84666667,47.51333333 +54,70,61,36.79333333,-7.683333333,4.253333333 +38,58,111,30.57833333,8.741666667,-28.87166667 +212,132,66,63.97,19.78,39.89666667 +72,107,66,45.735,-19.39833333,17.27666667 +142,76,97,46.27333333,27.43,-0.658333333 +97,95,162,46.68166667,15.74333333,-30.815 +140,140,140,61.34833333,1.033333333,-0.151666667 +255,255,255,93.77333333,1.765,-4.411666667 +158,154,201,67.955,11.27333333,-20.06 +255,236,0,87.50166667,-12.59166667,78.655 +255,182,4,75.95833333,9.428333333,67.96333333 +243,107,33,61.09,39,52.50833333 +235,35,65,51.09833333,62.24166667,27.82333333 +106,55,134,36.80166667,32.49333333,-30.18666667 +255,185,59,76.87166667,9.426666667,57.305 +243,157,192,74.25,30.54,-7.908333333 +169,169,169,70.22333333,0.92,0.1 +54,54,54,30.775,-0.525,0.32 +116,59,54,39.87,20.87,12.47 +65,108,99,47.85833333,-15.3,1.538333333 +140,76,119,46.595,29.31666667,-10.93333333 +53,59,81,32.97333333,2.943333333,-12.37833333 +138,75,128,46.22333333,30.45666667,-15.91666667 +137,180,113,68.87833333,-23.25666667,27.84333333 +0,158,179,61.18,-20.86,-16.83833333 +113,207,244,78.175,-12.04333333,-22.53833333 +112,112,112,51.61,-0.502,-0.136 +226,226,226,87.13333333,1.495,-3.138333333 +184,50,46,45.52833333,42.72833333,29.61 +238,99,157,62.11,50.415,-7.06 +42,86,65,39.50666667,-17.82333333,8.103333333 +90,176,65,63.03166667,-42.46666667,43.37333333 +233,34,35,50.54666667,60.89166667,42.66 +190,230,250,86.84666667,-4.345,-12.96333333 +17,57,134,32.005,14.47333333,-34.95666667 +0,162,227,63.635,-10.44333333,-33.42166667 +198,198,198,79.01,1.025,-0.918333333 +83,83,83,42.464,-1.92,0.73 +0,172,198,64.285,-21.78166667,-20.35333333 +255,249,205,92.19333333,-3.3,13.94333333 +142,153,81,63.36833333,-13.99,33.38 +230,136,63,66.125,23.97666667,44.36833333 +141,76,111,45.82333333,28.36666667,-7.24 +231,22,127,52.11333333,66.82,-3.993333333 +190,157,147,68.685,10.07166667,7.398333333 +81,180,118,65.39166667,-38.2,21.53333333 +83,83,83,40.794,-0.94,-0.32 +198,198,198,79.14666667,0.791666667,-1.766666667 +234,31,101,52.21833333,64.01666667,8.343333333 +255,203,59,81.59333333,1.206666667,60.66833333 +252,173,144,76.00166667,19.22,17.49833333 +237,73,123,58.05833333,54.47333333,3.016666667 +206,138,159,66.82333333,23.78333333,-2.453333333 +143,76,82,45.865,25.65,7.266666667 +0,129,159,52.54833333,-15.35166667,-20.88666667 +0,130,198,54.21666667,-3.341666667,-36.37833333 +226,226,226,86.78666667,1.36,-2.605 +112,112,112,51.81,-0.583333333,-0.52 +0,152,77,56.07833333,-46.975,31.68 +0,164,72,58.71666667,-49.065,37.25166667 +137,75,137,45.86333333,31.94666667,-19.99 +167,210,173,79.54,-16.565,10.95166667 +59,109,116,47.90833333,-11.37166667,-8.108333333 +141,166,82,66.06833333,-20.29,37.86166667 +186,134,159,63.88,20.75166667,-5.778333333 +202,209,33,78.01833333,-18.415,67.03833333 +54,54,54,32.25,-1.4925,1.52 +169,169,169,71.545,-0.0625,-0.33 +244,110,79,62.268,39.444,32.43 +140,178,84,68.00333333,-25.05166667,39.31166667 +131,124,169,57.03833333,10.89833333,-19.545 +255,240,90,88.664,-11.328,60.484 +35,110,154,47.93333333,-5.69,-27.08833333 +0,125,73,48.08833333,-39.07333333,20.28 +0,86,159,38.855,7.425,-39.47166667 +138,190,85,69.98666667,-29.77333333,41.79833333 +255,255,255,93.715,1.663333333,-4.443333333 +140,140,140,61.934,-0.202,-0.038 +249,207,225,85.474,13.868,-6.676 +0,155,119,57.845,-37.60333333,9.745 +93,167,88,61.77166667,-35.645,29.3 +245,234,143,88.21833333,-8.618333333,37.94666667 +0,183,236,68.89666667,-15.51,-31.53166667 +81,60,92,34.46833333,13.13166667,-14.09 +255,245,153,90.20666667,-7.895,34.44333333 +70,108,81,46.88666667,-18.28333333,11.555 +26,26,26,23.2425,-0.405,0.9525 +0,0,0,0,0,0 +255,255,255,94.11333333,1.658333333,-4.575 +54,54,54,32.195,-1.735,1.2575 +226,226,226,86.62833333,1.258333333,-2.736666667 +83,83,83,40.4025,-0.7875,-1.06 +198,198,198,79.255,1.036666667,-1.23 +112,112,112,51.55,-0.24,-1.1725 +169,169,169,70.695,0.278333333,-0.368333333 +140,140,140,61.43833333,0.363333333,-0.338333333 +0,0,0,0,0,0 diff --git a/Software/Visual_Studio/TCC/Images/bottomLeft.bmp b/Software/Visual_Studio/TCC/Images/bottomLeft.bmp Binary files differnew file mode 100644 index 000000000..13b33704b --- /dev/null +++ b/Software/Visual_Studio/TCC/Images/bottomLeft.bmp diff --git a/Software/Visual_Studio/TCC/Images/bottomRight.bmp b/Software/Visual_Studio/TCC/Images/bottomRight.bmp Binary files differnew file mode 100644 index 000000000..d2116fad2 --- /dev/null +++ b/Software/Visual_Studio/TCC/Images/bottomRight.bmp diff --git a/Software/Visual_Studio/TCC/Images/template.bmp b/Software/Visual_Studio/TCC/Images/template.bmp Binary files differnew file mode 100644 index 000000000..a64493e0f --- /dev/null +++ b/Software/Visual_Studio/TCC/Images/template.bmp diff --git a/Software/Visual_Studio/TCC/Images/topRight.bmp b/Software/Visual_Studio/TCC/Images/topRight.bmp Binary files differnew file mode 100644 index 000000000..f008d454d --- /dev/null +++ b/Software/Visual_Studio/TCC/Images/topRight.bmp diff --git a/Software/Visual_Studio/TCC/Images/topleft.bmp b/Software/Visual_Studio/TCC/Images/topleft.bmp Binary files differnew file mode 100644 index 000000000..8115cf359 --- /dev/null +++ b/Software/Visual_Studio/TCC/Images/topleft.bmp diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionConfig.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionConfig.cs new file mode 100644 index 000000000..bd8b394ad --- /dev/null +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionConfig.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PMR.TCC; + +namespace Tango.TCC.BL +{ + public class CardDetectionConfig + { + public List<DetectionBenchmark> Benchmarks { get; set; } + public int DesiredBitmapWidth { get; set; } + public int DesiredBitmapHeight { get; set; } + public int Columns { get; set; } + public int Rows { get; set; } + public int TargetIndex { get; set; } + public byte[] TemplateBitmapBytes { get; set; } + + public CardDetectionConfig() + { + DesiredBitmapWidth = 300; + DesiredBitmapHeight = 330; + Columns = 10; + Rows = 11; + TargetIndex = 89; + Benchmarks = new List<DetectionBenchmark>(); + } + } +} diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs index 821d19330..0cf7f3d67 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs @@ -11,6 +11,7 @@ namespace Tango.TCC.BL public class CardDetectionResult { public bool IsDetected { get; set; } + public BitmapSource Source { get; set; } public BitmapSource DetectedBitmap { get; set; } public DetectionOutput ColorDetectionOutput { get; set; } } diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs index d10e99b81..c0f827e1b 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs @@ -1,11 +1,13 @@ using Google.Protobuf; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media; using System.Windows.Media.Imaging; +using Tango.Core.Helpers; using Tango.PMR.TCC; namespace Tango.TCC.BL @@ -13,6 +15,8 @@ namespace Tango.TCC.BL public class CardDetector { private ColorDetector _colorDetector; + private static byte[] _defaultTemplate; + private static List<DetectionBenchmark> _defaultBenchmarks; private bool _canDetect; public bool CanDetect @@ -23,11 +27,17 @@ namespace Tango.TCC.BL public CardDetector() { + if (_defaultTemplate == null) + { + _defaultTemplate = File.ReadAllBytes(AssemblyHelper.GetCurrentAssemblyFolder() + "\\TCC\\template.bmp"); + _defaultBenchmarks = ColorDetector.LoadBenchmarks(AssemblyHelper.GetCurrentAssemblyFolder() + "\\TCC\\benchmarks_rgb_lab.csv").ToList(); + } + CanDetect = true; _colorDetector = new ColorDetector(); } - public Task<CardDetectionResult> Detect(BitmapSource source) + public Task<CardDetectionResult> Detect(BitmapSource source, CardDetectionConfig config) { if (!CanDetect) { @@ -42,12 +52,14 @@ namespace Tango.TCC.BL return Task.Factory.StartNew<CardDetectionResult>(() => { CardDetectionResult detectionResult = new CardDetectionResult(); + detectionResult.Source = cloned; Tango.TCC.CardDetector.CardDetection detector = new TCC.CardDetector.CardDetection(); var result = detector.Detect(cloned.ToBytes(PixelFormats.Rgb24), new TCC.CardDetector.CardDetectionConfig() { - DesiredBitmapWidth = 300, - DesiredBitmapHeight = 310, + DesiredBitmapWidth = config.DesiredBitmapWidth, + DesiredBitmapHeight = config.DesiredBitmapHeight, + TemplateBitmap = config.TemplateBitmapBytes != null ? config.TemplateBitmapBytes : _defaultTemplate.ToArray(), }); if (result.IsDetected) @@ -55,14 +67,25 @@ namespace Tango.TCC.BL detectionResult.IsDetected = true; detectionResult.DetectedBitmap = result.DetectedBitmap.ToBitmapSource(); - detectionResult.ColorDetectionOutput = _colorDetector.Detect(new DetectionInput() + var input = new DetectionInput() { Bitmap = ByteString.CopyFrom(detectionResult.DetectedBitmap.ToBmpBytes()), - Columns = 10, - Rows = 11, - TargetIndex = 89, + Columns = config.Columns, + Rows = config.Rows, + TargetIndex = config.TargetIndex, RequestColorMatrix = true, - }); + }; + + if (config.Benchmarks.Count > 0) + { + input.Benchmarks.AddRange(config.Benchmarks); + } + else + { + input.Benchmarks.AddRange(_defaultBenchmarks); + } + + detectionResult.ColorDetectionOutput = _colorDetector.Detect(input); } CanDetect = true; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/ColorDetector.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/ColorDetector.cs index e3c80cb20..a41124c42 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.BL/ColorDetector.cs +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/ColorDetector.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using System.Web.Hosting; using Tango.Core.Helpers; +using Tango.CSV; using Tango.PMR; using Tango.PMR.TCC; @@ -152,6 +153,24 @@ namespace Tango.TCC.BL return index == 1 || index == columns || index == columns * rows || index == (columns * rows) - columns + 1; } + public static IEnumerable<DetectionBenchmark> LoadBenchmarks(String file) + { + var benchmarks = CsvFile.Read<DetectionBenchmark>(new CsvSource(file)).ToList(); + return benchmarks; + } + + public static void SaveBenchmarks(String file,IEnumerable<DetectionBenchmark> benchmarks) + { + CsvFile<DetectionBenchmark> csvFile = new CsvFile<DetectionBenchmark>(new CsvDestination(file)); + + foreach (var item in benchmarks) + { + csvFile.Append(item); + } + + csvFile.Dispose(); + } + public void Dispose() { if (!_isDisposed) diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj index bb82e8c5d..bb12c02cc 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj @@ -51,6 +51,7 @@ <Reference Include="WindowsBase" /> </ItemGroup> <ItemGroup> + <Compile Include="CardDetectionConfig.cs" /> <Compile Include="CardDetectionResult.cs" /> <Compile Include="CardDetector.cs" /> <Compile Include="ColorDetector.cs" /> @@ -59,6 +60,10 @@ <Compile Include="Web\ColorDetectionResponse.cs" /> </ItemGroup> <ItemGroup> + <Content Include="..\Benchmarks\benchmarks_rgb_lab.csv"> + <Link>TCC\benchmarks_rgb_lab.csv</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> <None Include="packages.config" /> </ItemGroup> <ItemGroup> @@ -66,6 +71,10 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> <ProjectReference Include="..\..\Tango.PMR\Tango.PMR.csproj"> <Project>{e4927038-348d-4295-aaf4-861c58cb3943}</Project> <Name>Tango.PMR</Name> @@ -96,6 +105,10 @@ <Link>Tango.TCC.LoadTestLib.dll</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="..\Images\template.bmp"> + <Link>TCC\template.bmp</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <PropertyGroup> diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp index 76923a5c6..52721368a 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp @@ -81,8 +81,6 @@ Mat ArucoUtils::applyHomography(Mat image, vector<cv::Point> vertices, Size dest pts_dst.push_back(Point2f(destination_size.width - 1, destination_size.height - 1)); pts_dst.push_back(Point2f(0, destination_size.height - 1)); - Mat im_temp = image.clone(); - Mat tform = findHomography(vertices, pts_dst); warpPerspective(image, im_dst, tform, destination_size); return im_dst; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp Binary files differindex 546c228db..3f3415e48 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h Binary files differindex db8f51406..05b137a7b 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h index f014c2159..a6e104b53 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h @@ -1,5 +1,7 @@ #pragma once +using namespace System; + namespace Tango { namespace TCC @@ -11,6 +13,7 @@ namespace Tango CardDetectionConfig(); property double DesiredBitmapWidth; property double DesiredBitmapHeight; + property cli::array<Byte>^ TemplateBitmap; }; } } diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp index 5a7734c0e..fe92c0f4c 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp @@ -462,7 +462,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe detectionOutput->colormatrix[i] = initDetectionColor(means[i].val[2], means[i].val[1], means[i].val[0]); } } - + //Put original target color. detectionOutput->rawcolor = initDetectionColor(target_mean.val[2], target_mean.val[1], target_mean.val[0]); @@ -471,7 +471,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe detectionInput->benchmarks[0]->l; //Put processed target color. - detectionOutput->processedcolor = initDetectionColor(255, 0, 0); + detectionOutput->processedcolor = initDetectionColor(target_mean.val[2] + 10, target_mean.val[1] + 10, target_mean.val[0] + 10); detectionOutput->has_number = true; detectionOutput->number = detectionInput->number + 10; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.c b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.c index afc3c7302..91e8dee86 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.c +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.c @@ -94,7 +94,7 @@ static const ProtobufCFieldDescriptor detection_benchmark__field_descriptors[6] "L", 4, PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, + PROTOBUF_C_TYPE_DOUBLE, offsetof(DetectionBenchmark, has_l), offsetof(DetectionBenchmark, l), NULL, @@ -106,7 +106,7 @@ static const ProtobufCFieldDescriptor detection_benchmark__field_descriptors[6] "A", 5, PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, + PROTOBUF_C_TYPE_DOUBLE, offsetof(DetectionBenchmark, has_a), offsetof(DetectionBenchmark, a), NULL, @@ -118,7 +118,7 @@ static const ProtobufCFieldDescriptor detection_benchmark__field_descriptors[6] "B", 6, PROTOBUF_C_LABEL_OPTIONAL, - PROTOBUF_C_TYPE_INT32, + PROTOBUF_C_TYPE_DOUBLE, offsetof(DetectionBenchmark, has_b), offsetof(DetectionBenchmark, b), NULL, diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.h index d7368eed8..b7f5c863d 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionBenchmark.pb-c.h @@ -33,11 +33,11 @@ struct _DetectionBenchmark protobuf_c_boolean has_blue; int32_t blue; protobuf_c_boolean has_l; - int32_t l; + double l; protobuf_c_boolean has_a; - int32_t a; + double a; protobuf_c_boolean has_b; - int32_t b; + double b; }; #define DETECTION_BENCHMARK__INIT \ { PROTOBUF_C_MESSAGE_INIT (&detection_benchmark__descriptor) \ diff --git a/Software/Visual_Studio/Tango.CSV/CsvFileReader.cs b/Software/Visual_Studio/Tango.CSV/CsvFileReader.cs index 1ae9404a7..6d1deded2 100644 --- a/Software/Visual_Studio/Tango.CSV/CsvFileReader.cs +++ b/Software/Visual_Studio/Tango.CSV/CsvFileReader.cs @@ -273,6 +273,8 @@ namespace Tango.CSV return (s) => String.IsNullOrEmpty(s) ? 0 : Int32.Parse(s); if (propertyType == typeof(DateTime)) return (s) => String.IsNullOrEmpty(s) ? DateTimeZero : DateTime.Parse(s); + else if (propertyType == typeof(Double)) + return (s) => String.IsNullOrEmpty(s) ? 0.0 : Double.Parse(s); else throw new NotImplementedException(); } diff --git a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DateTimeExtensions.cs b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DateTimeExtensions.cs index 8e1b539fb..e22bb0fe3 100644 --- a/Software/Visual_Studio/Tango.Core/ExtensionMethods/DateTimeExtensions.cs +++ b/Software/Visual_Studio/Tango.Core/ExtensionMethods/DateTimeExtensions.cs @@ -19,4 +19,14 @@ public static class DateTimeExtensions { return date.ToString("HH:mm:ss.ff"); } + + /// <summary> + /// Returns a string which can be used as a file name. + /// </summary> + /// <param name="date">The date.</param> + /// <returns></returns> + public static String ToFileName(this DateTime date) + { + return string.Format("{0:dd-MM-yyyy HH-mm-ss}", DateTime.Now); + } } diff --git a/Software/Visual_Studio/Tango.PMR/TCC/DetectionBenchmark.cs b/Software/Visual_Studio/Tango.PMR/TCC/DetectionBenchmark.cs index a7e2d47ae..cd106db9a 100644 --- a/Software/Visual_Studio/Tango.PMR/TCC/DetectionBenchmark.cs +++ b/Software/Visual_Studio/Tango.PMR/TCC/DetectionBenchmark.cs @@ -24,8 +24,8 @@ namespace Tango.PMR.TCC { string.Concat( "ChhEZXRlY3Rpb25CZW5jaG1hcmsucHJvdG8SDVRhbmdvLlBNUi5UQ0MiXwoS", "RGV0ZWN0aW9uQmVuY2htYXJrEgsKA1JlZBgBIAEoBRINCgVHcmVlbhgCIAEo", - "BRIMCgRCbHVlGAMgASgFEgkKAUwYBCABKAUSCQoBQRgFIAEoBRIJCgFCGAYg", - "ASgFQhkKF2NvbS50d2luZS50YW5nby5wbXIudGNjYgZwcm90bzM=")); + "BRIMCgRCbHVlGAMgASgFEgkKAUwYBCABKAESCQoBQRgFIAEoARIJCgFCGAYg", + "ASgBQhkKF2NvbS50d2luZS50YW5nby5wbXIudGNjYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { @@ -108,9 +108,9 @@ namespace Tango.PMR.TCC { /// <summary>Field number for the "L" field.</summary> public const int LFieldNumber = 4; - private int l_; + private double l_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int L { + public double L { get { return l_; } set { l_ = value; @@ -119,9 +119,9 @@ namespace Tango.PMR.TCC { /// <summary>Field number for the "A" field.</summary> public const int AFieldNumber = 5; - private int a_; + private double a_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int A { + public double A { get { return a_; } set { a_ = value; @@ -130,9 +130,9 @@ namespace Tango.PMR.TCC { /// <summary>Field number for the "B" field.</summary> public const int BFieldNumber = 6; - private int b_; + private double b_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int B { + public double B { get { return b_; } set { b_ = value; @@ -167,9 +167,9 @@ namespace Tango.PMR.TCC { if (Red != 0) hash ^= Red.GetHashCode(); if (Green != 0) hash ^= Green.GetHashCode(); if (Blue != 0) hash ^= Blue.GetHashCode(); - if (L != 0) hash ^= L.GetHashCode(); - if (A != 0) hash ^= A.GetHashCode(); - if (B != 0) hash ^= B.GetHashCode(); + if (L != 0D) hash ^= L.GetHashCode(); + if (A != 0D) hash ^= A.GetHashCode(); + if (B != 0D) hash ^= B.GetHashCode(); return hash; } @@ -192,17 +192,17 @@ namespace Tango.PMR.TCC { output.WriteRawTag(24); output.WriteInt32(Blue); } - if (L != 0) { - output.WriteRawTag(32); - output.WriteInt32(L); + if (L != 0D) { + output.WriteRawTag(33); + output.WriteDouble(L); } - if (A != 0) { - output.WriteRawTag(40); - output.WriteInt32(A); + if (A != 0D) { + output.WriteRawTag(41); + output.WriteDouble(A); } - if (B != 0) { - output.WriteRawTag(48); - output.WriteInt32(B); + if (B != 0D) { + output.WriteRawTag(49); + output.WriteDouble(B); } } @@ -218,14 +218,14 @@ namespace Tango.PMR.TCC { if (Blue != 0) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(Blue); } - if (L != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(L); + if (L != 0D) { + size += 1 + 8; } - if (A != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(A); + if (A != 0D) { + size += 1 + 8; } - if (B != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(B); + if (B != 0D) { + size += 1 + 8; } return size; } @@ -244,13 +244,13 @@ namespace Tango.PMR.TCC { if (other.Blue != 0) { Blue = other.Blue; } - if (other.L != 0) { + if (other.L != 0D) { L = other.L; } - if (other.A != 0) { + if (other.A != 0D) { A = other.A; } - if (other.B != 0) { + if (other.B != 0D) { B = other.B; } } @@ -275,16 +275,16 @@ namespace Tango.PMR.TCC { Blue = input.ReadInt32(); break; } - case 32: { - L = input.ReadInt32(); + case 33: { + L = input.ReadDouble(); break; } - case 40: { - A = input.ReadInt32(); + case 41: { + A = input.ReadDouble(); break; } - case 48: { - B = input.ReadInt32(); + case 49: { + B = input.ReadDouble(); break; } } |
