Skip to content

Commit

Permalink
[NEW-FEATURE] Add message that the task's execute is not called cycli…
Browse files Browse the repository at this point in the history
…cally (#106)

* Create draft PR for #50

* wip failes to pass IAxoObject refernce to serve method of messenger

* clup report

* mend

---------

Co-authored-by: LukasKytka <LukasKytka@users.noreply.github.com>
Co-authored-by: Lukas Kytka <lukas.kytka@mts.sk>
  • Loading branch information
3 people authored Aug 31, 2023
1 parent 9574253 commit 0c5d65d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/core/ctrl/src/AxoMessaging/Static/AxoMessenger.st
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ NAMESPACE AXOpen.Messaging.Static
VAR_INPUT
_object : IAxoObject;
END_VAR

IF AXOpen.Core.IsNullContext(_object.GetContext()) THEN
RETURN;
END_IF;

THIS.Initialize(_object);

THIS.Serve(_object.GetContext());
Expand Down
28 changes: 22 additions & 6 deletions src/core/ctrl/src/AxoTask/AxoTask.st
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
USING AXOpen.Logging;
USING AXOpen.Timers;

USING AXOpen.Messaging;
USING AXOpen.Messaging.Static;

NAMESPACE AXOpen.Core

CLASS PUBLIC AxoTask EXTENDS AxoObject IMPLEMENTS IAxoTask, IAxoTaskState
Expand Down Expand Up @@ -63,6 +66,14 @@ NAMESPACE AXOpen.Core
/// Contains details about the error.
///</summary>
ErrorDetails : STRING[254];

///<summary>
/// Enable error message when task is not calling cyclically .
///</summary>
{#ix-set:MessageText = "<#Cyclic Execute is not called.#>"}
{#ix-set:Help = "<#Check task calling in the code, task is not calling cyclically #>"}
_CyclicExecuteIsNotCalled : AXOpen.Messaging.Static.AxoMessenger;

END_VAR

VAR PRIVATE
Expand Down Expand Up @@ -192,10 +203,15 @@ NAMESPACE AXOpen.Core

IF _isNullContext THEN
Status := eAxoTaskState#Error;
ErrorDetails := 'NULL CONTEXT';
ErrorDetails := 'NULL CONTEXT';
RETURN;
END_IF;

THIS.UpdateState();


_CyclicExecuteIsNotCalled.Serve(THIS);

IF Status = eAxoTaskState#Done AND THIS.IsNewInvokeCall() THEN
Status := eAxoTaskState#Ready;
END_IF;
Expand All @@ -205,11 +221,11 @@ NAMESPACE AXOpen.Core
// task should not be Invoked, if the execute method was not called in this or previous PLC cycle
IF Status = eAxoTaskState#Ready THEN
IF (THIS.IsExecuteCalledInThisPlcCycle() OR THIS.WasExecuteCalledInPreviousPlcCycle()) THEN
Status := eAxoTaskState#Kicking;
THIS.LogTask('Task invoked', eLogLevel#Verbose, THIS);
ELSE
THIS.LogTask('Cyclic execute is not called', eLogLevel#Debug, THIS);
END_IF;
Status := eAxoTaskState#Kicking;
THIS.LogTask('Task invoked', eLogLevel#Verbose, THIS);
ELSE
_CyclicExecuteIsNotCalled.Activate(eAxoMessageCategory#ProgrammingError);
END_IF;
END_IF;

Invoke := THIS;
Expand Down
24 changes: 18 additions & 6 deletions src/templates.simple/ctrl/src/Examples/PneumaticManipulator.st
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ NAMESPACE examples.PneumaticManipulator
///<summary>
/// Hardware output structure
///</summary>
Outputs : axosimple.Outputs;
Outputs : axosimple.Outputs;
END_VAR
THIS.Initialize(parent);
THIS.Execute(Inputs, Outputs);
Expand Down Expand Up @@ -341,7 +341,8 @@ NAMESPACE examples.PneumaticManipulator
CLASS PUBLIC GroundSequence
EXTENDS AXOpen.Core.AxoSequencerContainer
VAR PUBLIC
Steps : ARRAY[0..20] OF AxoStep;
Steps : ARRAY[0..20] OF AxoStep;
MoveToWork : AxoTask;
END_VAR
VAR PRIVATE
Components : REF_TO Components;
Expand All @@ -357,6 +358,9 @@ NAMESPACE examples.PneumaticManipulator
Components := _components;
ProcessData := _processData;
SUPER.Run(_parent);

// MoveToWork.Initialize(THIS);

END_METHOD
///<summary>
/// Contains logic of the steps of this sequence
Expand All @@ -373,16 +377,24 @@ NAMESPACE examples.PneumaticManipulator
THIS.SequenceMode := eAxoSequenceMode#RunOnce;
// This is more verbose but also more versatile way of executing step logic.
IF (Steps[0].Execute(THIS, TRUE, 'Move vertical cyclinder down.')) THEN
//-------------------------------------------------------
IF (components^.VerticalCylinder.MoveToHome.Invoke().IsDone()) THEN // <- waits for the task to be done.
THIS.MoveNext(); // <- This will move to the next step in the sequence.
END_IF;
//-------------------------------------------------------
END_IF;

IF (Steps[4].Execute(THIS, TRUE, 'This will break down')) THEN
//-------------------------------------------------------
THIS.MoveNext();
//-------------------------------------------------------
IF (components^.VerticalCylinder.MoveToHome.Invoke().IsDone()) THEN // <- waits for the task to be done.
THIS.MoveNext(); // <- This will move to the next step in the sequence.
END_IF;
//-------------------------------------------------------
END_IF;

// This is more concise way of writing steps when we execute only single task.
THIS.AndThen(Steps[1], components^.GripperCylinder.MoveToHome);
THIS.AndThen(Steps[2], components^.VerticalCylinder.MoveToHome);
THIS.AndThen(Steps[3], components^.HorizontalCylinder.MoveToHome);

// This will close the sequence and will return to the first step.
THIS.Close(Steps[20]);
END_METHOD
Expand Down

0 comments on commit 0c5d65d

Please sign in to comment.