Hello long story short I have a simulation that has a pneumatic pusher that I have named "Pusher" I want to script for it to read an analog value from my PLC via Codesys and manipulate the pusher speed and rotation along the y-axis. I have attached the entirety of my code to this post and want to see if anyone can help me. I have been at it for 2 weeks and this is my final portion that I need before my simulation is mostly complete. Any help would be appreciated.
There are 2 versions (any digital inputs are working correctly and dealt with correctly by the PLC):
Version:
// Machines Simulator - Machine Script Code
// FINAL FULL CODE
//
// Behavior:
// - DO_Launch controls the cylinder: TRUE = extend, FALSE = retract
// - AO_Pusher_Rotation is a 0–360° command that rotates the pusher about Y only
// - AO_Pusher_Speed is a 0–360 command that scales into Pusher.Speed
//
// Notes:
// - Pusher extend/retract is handled internally by the script (AdvanceCyl/BackCyl).
// ---------------- IO MAPPING ----------------
//// DIGITAL INPUTS ////
const int DI_PE1 = 0;
const int DI_PE2 = 1;
const int DI_PE3 = 2;
const int DI_PE4 = 3;
const int DI_PE5 = 4;
const int DI_PE6 = 5;
//// ANALOGIC OUTPUTS ////
const int AO_Pusher_Rotation = 0; // 0–360 degrees
const int AO_Pusher_Speed = 1; // 0–360 (speed command)
// DIGITAL OUTPUTS
const int DO_Catch_all_destroyer = 0;
const int DO_Box_Creator = 1;
const int DO_Launch = 2; // Your launch/extend command // TRUE = extend, FALSE = retract
// ---------------- TUNING ----------------
// Rotation limits (degrees)
const float ROT_MIN_DEG = 0.0f;
const float ROT_MAX_DEG = 360.0f;
// Fixed rotation step per Physics() call (deg/tick)
const float ROT_STEP_DEG = 2.0f; // tune (bigger = faster turning)
// Pusher speed range (tune to your model)
const float PUSH_SPEED_MIN = 0.1f;
const float PUSH_SPEED_MAX = 100.0f;
// ---------------- MAIN LOOP ----------------
public void Main()
{
// Cylinder command from PLC BOOL input
bool launch = IOManager.GetOutput(DO_Launch);
// When DO_Launch is TRUE -> extend
// When DO_Launch is FALSE -> retract
if (launch)
{
Pusher.AdvanceCyl(true);
Pusher.BackCyl(false);
}
else
{
Pusher.AdvanceCyl(false);
Pusher.BackCyl(true);
}
}
public void Physics()
{
// ---- 1) Read analog speed commands (value) ----
float rawSpeedDeg = IOManager.GetAOutput(AO_Pusher_Speed); // value
//float norm = Clamp01(rawSpeedDeg / 360.0f);
//float pushSpeed = Lerp(PUSH_SPEED_MIN, PUSH_SPEED_MAX, norm);
if (rawSpeedDeg > 0.0f)
{
Pusher.Speed = IOManager.SetAOutput(1,rawSpeedDeg);
Pusher2.Speed = IOManager.SetAOutput(1,20.0f);
}
}
// ---------------- HELPERS ----------------
float Clamp01(float v)
{
if (v < 0.0f) return 0.0f;
if (v > 1.0f) return 1.0f;
return v;
}
float Clamp(float v, float min, float max)
{
if (v < min) return min;
if (v > max) return max;
return v;
}
float Lerp(float a, float b, float t)
{
return a + (b - a) * t;
}
float Abs(float v)
{
return v < 0.0f ? -v : v;
}
_________________________________________________
Version 2:
// Machines Simulator - Machine Script Code
// FINAL FULL CODE
//
// Behavior:
// - DO_Launch controls the cylinder: TRUE = extend, FALSE = retract
// - AO_Pusher_Rotation is a 0–360° command that rotates the pusher about Y only
// - AO_Pusher_Speed is a 0–360 command that scales into Pusher.Speed
//
// Notes:
// - Pusher extend/retract is handled internally by the script (AdvanceCyl/BackCyl).
// ---------------- IO MAPPING ----------------
//// DIGITAL INPUTS ////
const int DI_PE1 = 0;
const int DI_PE2 = 1;
const int DI_PE3 = 2;
const int DI_PE4 = 3;
const int DI_PE5 = 4;
const int DI_PE6 = 5;
//// ANALOGIC OUTPUTS ////
const int AO_Pusher_Rotation = 0; // 0–360 degrees
const int AO_Pusher_Speed = 1; // 0–360 (speed command)
// DIGITAL OUTPUTS
const int DO_Catch_all_destroyer = 0;
const int DO_Box_Creator = 1;
const int DO_Launch = 2; // Your launch/extend command // TRUE = extend, FALSE = retract
// ---------------- TUNING ----------------
// Rotation limits (degrees)
const float ROT_MIN_DEG = 0.0f;
const float ROT_MAX_DEG = 360.0f;
// Fixed rotation step per Physics() call (deg/tick)
const float ROT_STEP_DEG = 2.0f; // tune (bigger = faster turning)
// Pusher speed range (tune to your model)
const float PUSH_SPEED_MIN = 0.1f;
const float PUSH_SPEED_MAX = 100.0f;
// ---------------- MAIN LOOP ----------------
public void Main()
{
// Cylinder command from PLC BOOL input
bool launch = IOManager.GetOutput(DO_Launch);
// When DO_Launch is TRUE -> extend
// When DO_Launch is FALSE -> retract
if (launch)
{
Pusher.AdvanceCyl(true);
Pusher.BackCyl(false);
}
else
{
Pusher.AdvanceCyl(false);
Pusher.BackCyl(true);
}
}
public void Physics()
{
// ---- 1) Read analog rotation and speed commands (0..360) ----
float rawRotDeg = IOManager.GetAOutput(AO_Pusher_Rotation); // 0..360
float rawSpeedDeg = IOManager.GetAOutput(AO_Pusher_Speed); // 0..360
// ---- 2) Rotate pusher about Y axis only ----
float targetY = Clamp(rawRotDeg, ROT_MIN_DEG, ROT_MAX_DEG);
Vector3 Rotation r = Pusher.Rotation;
float currY = r.y;
float error = targetY - currY;
float step;
float absErr = Abs(error);
if (absErr <= ROT_STEP_DEG)
step = error; // close enough: snap to target
else
step = (error > 0.0f ? 1.0f : -1.0f) * ROT_STEP_DEG;
float newY = currY + step;
// Lock rotation strictly to Y axis
Pusher.Rotation = new Vector3(0.0f, newY, 0.0f);
// ---- 3) Dynamic cylinder speed from analog ----
float norm = Clamp01(rawSpeedDeg / 360.0f);
float pushSpeed = Lerp(PUSH_SPEED_MIN, PUSH_SPEED_MAX, norm);
Pusher.Speed = pushSpeed;
}
// ---------------- HELPERS ----------------
float Clamp01(float v)
{
if (v < 0.0f) return 0.0f;
if (v > 1.0f) return 1.0f;
return v;
}
float Clamp(float v, float min, float max)
{
if (v < min) return min;
if (v > max) return max;
return v;
}
float Lerp(float a, float b, float t)
{
return a + (b - a) * t;
}
float Abs(float v)
{
return v < 0.0f ? -v : v;
}
Are you using a UDC or directly the code in the machine?
Can you share your .maq file in order to help you?
Hello! Yes I have the .maq attached here as a zip folder and I am directly coding in the Machine Simulator via scripting.
En el código hay varias cosas que no están bien hechas:
Script Code da error por dos cosas:
1- Deben existir la siguiente función:
public void Finish()
{
}
2- No se puede hacer:
Pusher.Speed = IOManager.SetAOutput(1,rawSpeedDeg);
Pusher2.Speed = IOManager.SetAOutput(1,20.0f);
SetAoutput no devuelve ningún valor.
En su lugar, puede hacer:
IOManager.SetAOutput(1,rawSpeedDeg);
IOManager.SetAOutput(1,20.0f);
Pusher.Speed = rawSpeedDeg;
Pusher2.Speed = 20.0f;
De igual forma, puede hacer:
Pusher.Speed = rawSpeedDeg;
Pusher2.Speed = 20.0f;
IOManager.SetAOutput(1,Pusher.Speed);
IOManager.SetAOutput(1,Pusher2.Speed);
Pero está asignando a la misma salida analógica (la 1) dos valores diferentes, lo que no es lógico.
Espero le haya servido
Saludos