diff --git a/Codesys/ArfBot.project b/Codesys/ArfBot.project index 1a63b98..ce7dc95 100644 Binary files a/Codesys/ArfBot.project and b/Codesys/ArfBot.project differ diff --git a/Codesys/ArfBot.xml b/Codesys/ArfBot.xml index ff776f2..36f154b 100644 --- a/Codesys/ArfBot.xml +++ b/Codesys/ArfBot.xml @@ -1,7 +1,7 @@  - - + + https://github.com/dalethomas81/ArfBotOS @@ -1733,7 +1733,7 @@ END_VAR - + git describe --tags --always --dirty (does not get the latest tag from main) @@ -1762,7 +1762,7 @@ END_VAR VAR_GLOBAL // git describe --tags --always --dirty (does not get the latest tag from main) // git describe --tags --always main (gets the latest tag from main but the commit is wrong because its from the branch we work from - dev) - sPlcVersion : STRING(80) := 'v2.2026.38.0-RoiEditor'; + sPlcVersion : STRING(80) := 'v2.2026.38.1-Cnc'; sRelease : STRING(80); sVersionLine : STRING(160); END_VAR @@ -12889,10 +12889,12 @@ VAR_OUTPUT END_VAR VAR _Filename: STRING := '_cnc/CNC_FromFile.cnc'; - _SMC_NCInterpreter: SMC_NCInterpreter; _SMC_ReadNCFile2: SMC_ReadNCFile2; + _SMC_NCInterpreter: SMC_NCInterpreter; + _SMC_SmoothPath: SMC_SmoothPath; _SMC_CheckVelocities: SMC_CheckVelocities; - _SMC_GEOINFO: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Ipo: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Smooth: ARRAY[0..50] OF SMC_GEOINFO; _StartPos: SMC_PosInfo; _OriConvention: SMC_ORI_CONVENTION := SMC_ORI_CONVENTION.ZYZ; _ExecuteRtrig: R_TRIG; @@ -12958,10 +12960,12 @@ VAR_OUTPUT END_VAR VAR _Filename: STRING := '_cnc/CNC_FromFile.cnc'; - _SMC_NCInterpreter: SMC_NCInterpreter; _SMC_ReadNCFile2: SMC_ReadNCFile2; + _SMC_NCInterpreter: SMC_NCInterpreter; + _SMC_SmoothPath: SMC_SmoothPath; _SMC_CheckVelocities: SMC_CheckVelocities; - _SMC_GEOINFO: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Ipo: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Smooth: ARRAY[0..50] OF SMC_GEOINFO; _StartPos: SMC_PosInfo; _OriConvention: SMC_ORI_CONVENTION := SMC_ORI_CONVENTION.ZYZ; _ExecuteRtrig: R_TRIG; @@ -12988,14 +12992,19 @@ END_VAR + + + + + - + - + @@ -13003,7 +13012,17 @@ END_VAR - + + + + + + + + + + + @@ -13077,10 +13096,12 @@ VAR_OUTPUT END_VAR VAR _Filename: STRING := '_cnc/CNC_FromFile.cnc'; - _SMC_NCInterpreter: SMC_NCInterpreter; _SMC_ReadNCFile2: SMC_ReadNCFile2; + _SMC_NCInterpreter: SMC_NCInterpreter; + _SMC_SmoothPath: SMC_SmoothPath; _SMC_CheckVelocities: SMC_CheckVelocities; - _SMC_GEOINFO: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Ipo: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Smooth: ARRAY[0..50] OF SMC_GEOINFO; _StartPos: SMC_PosInfo; _OriConvention: SMC_ORI_CONVENTION := SMC_ORI_CONVENTION.ZYZ; _ExecuteRtrig: R_TRIG; @@ -13128,10 +13149,12 @@ VAR_OUTPUT END_VAR VAR _Filename: STRING := '_cnc/CNC_FromFile.cnc'; - _SMC_NCInterpreter: SMC_NCInterpreter; _SMC_ReadNCFile2: SMC_ReadNCFile2; + _SMC_NCInterpreter: SMC_NCInterpreter; + _SMC_SmoothPath: SMC_SmoothPath; _SMC_CheckVelocities: SMC_CheckVelocities; - _SMC_GEOINFO: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Ipo: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Smooth: ARRAY[0..50] OF SMC_GEOINFO; _StartPos: SMC_PosInfo; _OriConvention: SMC_ORI_CONVENTION := SMC_ORI_CONVENTION.ZYZ; _ExecuteRtrig: R_TRIG; @@ -13217,10 +13240,13 @@ _SMC_NCInterpreter( bAppend:= , piStartPosition:= _StartPos, vStartToolLength:= , - nSizeOutQueue:= SIZEOF(_SMC_GEOINFO), - pbyBufferOutQueue:= ADR(_SMC_GEOINFO), + nSizeOutQueue:= SIZEOF(_SMC_GEOINFO_Ipo), + pbyBufferOutQueue:= ADR(_SMC_GEOINFO_Ipo), bEnableSyntaxChecks:= , - eOriConv:= _OriConvention, + eOriConv:= _OriConvention, + // A/B/C as independent axes so G91 A-45 is signed and can pass ±180. + // Tracker/trafo stay ZYX; do not set _OriConvention to ADDAXES (that feeds J4/J5/J6 as Euler and faults the group). + //eOriConv:= SMC_ORI_CONVENTION.ADDAXES, dCircleTolerance:= , pInterpreterStack:= , nInterpreterStackSizeBytes:= , @@ -13235,11 +13261,36 @@ _SMC_NCInterpreter( GCodeText=> , CallstackInfo=> , aActivePrograms=> ); + +_SMC_SmoothPath( + bExecute:= _SMC_ReadNCFile2.bExecute, + bAbort:= _Sequence = 999, + bAppend:= , + poqDataIn:= _SMC_NCInterpreter.poqDataOut, + dEdgeDistance:= , + dAngleTol:= , + nSizeOutQueue:= SIZEOF(_SMC_GEOINFO_Smooth), + pbyBufferOutQueue:= ADR(_SMC_GEOINFO_Smooth), + eMode:= , + bSymmetricalDistances:= , + bImprovedSymmetricCuts:= , + eAddAxMode:= , + dMinimumCurvatureRadius:= , + bCheckCurvature:= , + dRelativeCurvatureTol:= , + bCheckAddAxVelJump:= , + dMaxAddAxVelDifference:= , + bDone=> , + bBusy=> , + bError=> , + wErrorID=> , + poqDataOut=> , + udiStopsDueToCurvatureRadius=> ); _SMC_CheckVelocities( bExecute:= _SMC_NCInterpreter.bExecute, bAbort:= _Sequence = 999, - poqDataIn:= _SMC_NCInterpreter.poqDataOut, + poqDataIn:= _SMC_SmoothPath.poqDataOut, dAngleTol:= , bCheckAddAxVelJump:= , dMaxAddAxVelDifference:= , @@ -13251,6 +13302,7 @@ _SMC_CheckVelocities( _ErrorRtrig(); _ErrorRtrig.CLK:= _SMC_ReadNCFile2.bError OR _SMC_NCInterpreter.bError + OR _SMC_SmoothPath.bError OR _SMC_CheckVelocities.bError; IF _ErrorRtrig.Q THEN Error := TRUE; @@ -13266,6 +13318,12 @@ IF _ErrorRtrig.Q THEN CONCAT(' ', SMC_ErrorString(_SMC_NCInterpreter.wErrorID, SMC_Language_Type.english)))) ; END_IF + IF _SMC_SmoothPath.bError THEN + ErrorDescription := CONCAT(' SmoothPath Error: ', + CONCAT(TO_STRING(_SMC_SmoothPath.wErrorID), + CONCAT(' ', SMC_ErrorString(_SMC_SmoothPath.wErrorID, + SMC_Language_Type.english)))) ; + END_IF IF _SMC_CheckVelocities.bError THEN ErrorDescription := CONCAT(' CheckVelocities Error: ', CONCAT(TO_STRING(_SMC_CheckVelocities.wErrorID), @@ -13445,10 +13503,12 @@ VAR_OUTPUT END_VAR VAR _Filename: STRING := '_cnc/CNC_FromFile.cnc'; - _SMC_NCInterpreter: SMC_NCInterpreter; _SMC_ReadNCFile2: SMC_ReadNCFile2; + _SMC_NCInterpreter: SMC_NCInterpreter; + _SMC_SmoothPath: SMC_SmoothPath; _SMC_CheckVelocities: SMC_CheckVelocities; - _SMC_GEOINFO: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Ipo: ARRAY[0..50] OF SMC_GEOINFO; + _SMC_GEOINFO_Smooth: ARRAY[0..50] OF SMC_GEOINFO; _StartPos: SMC_PosInfo; _OriConvention: SMC_ORI_CONVENTION := SMC_ORI_CONVENTION.ZYZ; _ExecuteRtrig: R_TRIG; @@ -22363,7 +22423,7 @@ END_VAR - + @@ -22371,7 +22431,7 @@ END_VAR - + @@ -22379,7 +22439,7 @@ END_VAR - + @@ -22387,7 +22447,7 @@ END_VAR - + @@ -22403,10 +22463,10 @@ END_VAR FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -22446,6 +22506,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; @@ -22517,10 +22580,10 @@ END_VAR FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -22560,6 +22623,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; @@ -22706,10 +22772,10 @@ END_VAR FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -22749,6 +22815,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; @@ -22855,6 +22924,30 @@ END_VAR + + + + + + + + + + + + + + + + + + + + + + + + @@ -22900,10 +22993,10 @@ END_VAR FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -22943,6 +23036,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; @@ -23034,10 +23130,10 @@ END_VAR FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -23077,6 +23173,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; @@ -23253,7 +23352,6 @@ CASE WORD_TO_INT(_SMC_Interpolator.wM) OF // M200 - M215 wait on inputs 0 - 15 MCODE_INPUT_WAIT_START..MCODE_INPUT_WAIT_END: - // TODO should we put a timeout or bypass here? IF CmdIo.Input[WORD_TO_INT(_SMC_Interpolator.wM) - MCODE_INPUT_WAIT] THEN _SMC_Interpolator.bAcknM := TRUE; END_IF @@ -23267,6 +23365,13 @@ CASE WORD_TO_INT(_SMC_Interpolator.wM) OF MCODE_OUTPUT_CLR_START..MCODE_OUTPUT_CLR_END: CmdIo.Output[WORD_TO_INT(_SMC_Interpolator.wM) - MCODE_OUTPUT_CLR] := FALSE; _SMC_Interpolator.bAcknM := TRUE; + + // M500 - M515 wait on flags 0 - 49 + MCODE_FLAG_WAIT_START..MCODE_FLAG_WAIT_END: + IF SUPER^.Flags[WORD_TO_INT(_SMC_Interpolator.wM) - MCODE_FLAG_WAIT].Value THEN + SUPER^.Flags[WORD_TO_INT(_SMC_Interpolator.wM) - MCODE_FLAG_WAIT].Value := FALSE; + _SMC_Interpolator.bAcknM := TRUE; + END_IF END_CASE @@ -23288,7 +23393,7 @@ _SMC_Trafo_ArticulatedRobot_6DOF( dQ2_old:= J3.fActPosition, dQ3_old:= J4.fActPosition, dQ4_old:= J5.fActPosition, - dQ5_old:= J6.fActPosition, + dQ5_old:= -J6.fActPosition, armState:= _TrackPosition.Arm, elbowState:= _TrackPosition.Elbow, handState:= _TrackPosition.Hand, @@ -23386,7 +23491,7 @@ _SMC_ControlAxisByPos_J6( iStatus:= _SMC_Interpolator.iStatus, bEnable:= _SMC_Interpolator.bWorking, bAvoidGaps:= AvoidGaps, - fSetPosition:= _SMC_Trafo_ArticulatedRobot_6DOF.dQ5, + fSetPosition:= -_SMC_Trafo_ArticulatedRobot_6DOF.dQ5, fGapVelocity:= GapVelocity, fGapAcceleration:= GapAccel, fGapDeceleration:= GapAccel, @@ -23699,10 +23804,10 @@ _SMC_Interpolator.bExecute := FALSE; FUNCTION_BLOCK FB_CncCmdProcessor EXTENDS FB_Module VAR_INPUT - GapVelocity: LREAL := 500.0; - AvoidGaps: BOOL := TRUE; - GapAccel: LREAL := 10000.0; - GapJerk: LREAL := 10000000000000000.0; + GapVelocity: LREAL := 50.0; + AvoidGaps: BOOL := FALSE; + GapAccel: LREAL := 100.0; + GapJerk: LREAL := 1000.0; Command: STRING(GVL.COMMAND_LEN):=''; END_VAR VAR_IN_OUT @@ -23742,6 +23847,9 @@ VAR CONSTANT MCODE_OUTPUT_CLR: INT:=400; MCODE_OUTPUT_CLR_START: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_BEG; MCODE_OUTPUT_CLR_END: INT:=MCODE_OUTPUT_CLR+GVL.DIG_OUT_ARR_END; + MCODE_FLAG_WAIT: INT:=500; + MCODE_FLAG_WAIT_START: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_BEG; + MCODE_FLAG_WAIT_END: INT:=MCODE_FLAG_WAIT+GVL.FLG_ARR_END; END_VAR VAR CONSTANT _STEP_DONE: INT := 1000; diff --git a/Codesys/_cnc/CNC_Cone.cnc b/Codesys/_cnc/CNC_Cone.cnc index 95be012..0f5f3ef 100644 --- a/Codesys/_cnc/CNC_Cone.cnc +++ b/Codesys/_cnc/CNC_Cone.cnc @@ -1,26 +1,22 @@ -( G91 incremental | G17 xy | G02 cw with XY end and R ) -( Trafo ABC = yaw / pitch / roll. Look-at the apex at every corner. ) -( Jog TCP onto the apex, tool Z along the cone axis, then run. ) -( H = 40, R = 23.094, cone half-angle = 30 ) -( ) -( End of each quarter, ABC that point tool Z at the apex: ) -( start / N060: A0 B30 C0 lean in +X, pitch ) -( N070 +Y: A0 B0 C30 lean in -Y, roll ) -( N080 +X: A0 B-30 C0 lean in -X, pitch the other way ) -( N090 -Y: A0 B0 C-30 lean in +Y, roll the other way ) -( N100 -X: A0 B30 C0 back to start ) -( G91 values below are the deltas that reach those end angles. ) -N000 G91 -N020 G17 +( G17 xy plane | G18 zx plane | G16 ijk normal ) +( G91 incremental | G99 IJK relative to current TCP ) +( G55 rel DCS | G56 current pose = DCS origin | G53 reset DCS ) +( G51 start angle smoothing | G50 end ) +( A yaw, B pitch, C roll. Trafo is yaw/pitch/roll. ) +( Jog TCP onto the apex, tool Z along the cone axis, then run. ) -N050 G01 X0 Y0 Z0 A0 B30 C0 F30 -N060 G01 X-23.094 Y0 Z-40 A0 B0 C0 F30 +N000 G91 ( incremental, like CNC_FromFile ) +N010 G17 ( xy plane - circle is perpendicular to the cone axis ) -N070 G02 X23.094 Y23.094 R23.094 A0 B-30 C30 F30 -N080 G02 X23.094 Y-23.094 R23.094 A0 B-30 C-30 F30 -N090 G02 X-23.094 Y-23.094 R23.094 A0 B30 C-30 F30 -N100 G02 X-23.094 Y23.094 R23.094 A0 B30 C30 F30 +(N040 M510) ( wait for flag 10 ) +N050 G01 X-60 Y0 Z-80 A0 B10 C0 E300 F100 -N110 G01 X23.094 Y0 Z40 A0 B-30 C0 F30 -N130 G53 +N070 G02 X60 Y60 R60 A0 B-10 C-10 +N070 G02 X60 Y-60 R60 A0 B-10 C10 +N070 G03 X-60 Y60 R60 A0 B10 C-10 +N070 G03 X-60 Y-60 R60 A0 B10 C10 +N070 G03 X60 Y-60 R60 A0 B-10 C10 +N070 G03 X60 Y60 R60 A0 B-10 C-10 + +N140 G53 ( reset decoder coordinate system ) \ No newline at end of file diff --git a/Web/README.md b/Web/README.md index a6235e2..a923f76 100644 --- a/Web/README.md +++ b/Web/README.md @@ -4,15 +4,15 @@ One Flask app on port 5000 that hosts the operator pages: | URL | Page | | --- | --- | -| `http://:5000/vision` | Vision template capture and locate ROI | -| `http://:5000/vision/files` | Saved templates | +| `http://:5000/vision` | Vision: Capture, ROI, and Templates | +| `http://:5000/vision/templates` | Saved templates (old `/vision/files` redirects here) | | `http://:5000/animator` | 6-axis robot animator (joints, TCP / MCS / PCS, Euler convention) | | `http://:5000/bluetooth` | Bluetooth pairing (DualSense and other adapters) | | `http://:5000/vision/output_sized?width=365&height=255` | HMI vision result image | `/` redirects to `/vision` when vision is enabled, `/bluetooth` on a `--plc-only` install, or `/animator` if that is the only enabled page. Old `/template`, `/files/`, and `/output_sized` URLs redirect to the new paths. -The CODESYS HMI loads `/vision/output_sized`. Template files still go to `/var/opt/codesys/PlcLogic/Application/Vision/Templates`. Locate search ROI is `.../Vision/roi.yaml`, set from the Vision page ROI tab (`GET`/`POST /vision/roi`). The latest processed image is still `/var/opt/codesys/PlcLogic/visu/outputimage.jpg`. +The CODESYS HMI loads `/vision/output_sized`. Template files still go to `/var/opt/codesys/PlcLogic/Application/Vision/Templates`. Names cannot contain spaces; the capture size is appended (`screwdriver_640x400.jpg`) so a 2000×2000 snip is not used on a 640×400 Locate. Locate search ROI is `.../Vision/roi.yaml`, set from the Vision page ROI tab (`GET`/`POST /vision/roi`). The latest processed image is still `/var/opt/codesys/PlcLogic/visu/outputimage.jpg`. ## Capture size and HQ camera FOV diff --git a/Web/app/static/css/arfbot-night.css b/Web/app/static/css/arfbot-night.css index a2f023d..d69b4bb 100644 --- a/Web/app/static/css/arfbot-night.css +++ b/Web/app/static/css/arfbot-night.css @@ -469,17 +469,30 @@ pre.log { overflow: hidden; margin: 0 auto 12px; } -.mode-toggle button { +.mode-toggle button, +.mode-toggle a { border: none; border-radius: 0; margin: 0; background: var(--control); color: var(--muted); + text-decoration: none; + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px 16px; + font: inherit; + font-weight: 650; } -.mode-toggle button.active { +.mode-toggle button.active, +.mode-toggle a.active { background: var(--accent); color: var(--text-on-accent); } +.muted { + color: var(--muted); + font-size: 13px; +} #roi-status { color: var(--accent); font-weight: 650; @@ -571,6 +584,13 @@ pre.log { max-width: min(100%, 640px); height: auto; } +#template-preview { + width: 100%; + margin: 0; + color: var(--muted); + font-size: 12px; + font-weight: 650; +} #canvas { cursor: crosshair; border: 1px solid var(--frame-soft); diff --git a/Web/app/templates/base.html b/Web/app/templates/base.html index e8c3e8e..2ddd189 100644 --- a/Web/app/templates/base.html +++ b/Web/app/templates/base.html @@ -8,7 +8,7 @@ {% else %} ArfBot {% endif %} - + {% block head %}{% endblock %} @@ -36,8 +36,7 @@ {% endif %}