Document toolboxDocument toolbox

WIP AGV Demo

Now that we have the basics down, we can move on to a more advanced example

In this tutorial we’ll be making a AGV(Automated Guided Vehicle) demo. We’ll be picking and dropping off boxes, moving it through a metal detector and then letting it be carried away.

The first step is to create a DESController by adding a new gameobject and adding the DESController script. All DES Participants will need to be children of the DESController.

Drawing the AGV Splines

The AGV route consists of two splines, the starting spline from outside where the AGV’s are spawned and the main loop. To draw these splines we’ve created shots of the AGV and generated the splines with the Actor Route Creator.

To create the loop spline there is a setting in the Actor Route Creator that closes the spline. Check the “Close the resulting main spline“ checkbox to generate a closed/loop spline.

After generating the spline you might see the following anomaly in corners. This can be fixed by selecting the spline point and shortening the yellow handle.

Spawning the AGV

First, add the AGV to the scene and attach the AGVActor script to it.

AGVActor

using u040.prespective.prescripted.des; namespace u040.agv { /// <summary> /// Basic motion actor for the agv /// </summary> public class AGVActor : DESActor { public CardBoxActor box; } }

CardBoxActor (Will be used later)

using u040.prespective.prescripted.des; namespace u040.agv { public class CardBoxActor : DESActor { public MotionTensorView motionTensorView; private MotionTensor motionTensor; public void StartMotion(double passedFrameTime) { motionTensorView.GenerateMotionTensor(this, out motionTensor); SimulationController.AddActivityMidFrame(passedFrameTime, SimulationController.FrameTime, this, motionTensor); } } }

Then create a gameobject for the spawner and attach the BlockableSpawner script. Then set the “Spawn Interval Range” X and Y to 10. This is how many seconds it takes between spawns. Select which object to spawn by setting the Spawn Recipies to 1 and then setting the Spawn prototype to the AGVActor. Then set the Starting Tensor to the following.

  • Spline: The spline on which to spawn, here we use the spawn spline.

  • Thickness: How much space it will take on the spline. Because the AGV’s don’t collide in our test we’ve set it to a random value of 0.05 so as that it has a thickness.

  • Velocity curve: Click the velocity curve and set it to 1.

  • Component motion mode: We’ve selected absolute as that is how we want to move.

  • Component Motion Type: Because the AGV changes it’s rotation and position over the spline we’ve selected “TRANSLATION_AND_ROTATION“.

  • Weight Curve: Set this to 1, we don’t use it so it can just use a default value

  • Start Perc override: We don’t use this feature so keep it at it’s default 0.

  • Look Offset: We don’t use this feature so keep it at it’s default 0.

And setting the “Max Active Spawns“ to 10. This will stop the spawning when 10 AGV’s are active in the scene.

When set correctly this spawns the AGV and will automatically give it the motion tensor to start moving.

Changing spline

Next up is the changing of the spline. After the AGV has spawned, it moves over the spawn spline. At the end of the spawn spline, it needs to move onto the loop spline. At the end of the spawn spline there is a cue that uses the ChangeSplineInstructor.

Create an object for the instructor, Attach the ChangeSplineInstructorscript and select the ChangeSplineInstructor object in the cue’s Cue Instructor field. Then set the “Next Spline“ field on the ChangeSplineInstructor to the loop spline and the velocity to 1.

ChangeSplineInstructor

using System.Collections.Generic; using u040.prespective.core; using u040.prespective.prescripted.des; /// <summary> /// Changes splines when /// </summary> public class ChangeSplineInstructor : DESInstructor { /// <summary> /// The new spline on which to transfer /// </summary> public DSpline nextSpline; /// <summary> /// The velocity of the new movement /// </summary> public double velocity; /// <summary> /// The thickness of the object /// </summary> public double thickness = 0.02; public override bool ApplyInstruction(ADESActor actor, ADESCue _cue, ActorCueIntersectionEvent _intersectionEvent) { if (_intersectionEvent.IntersectionType != ActorCueIntersectionEvent.CueIntersectionType.CENTER) { return false; } //Destroy the old movement List<MotionTensor> motionTensors = actor.getActivitiesByType<MotionTensor>(); foreach (MotionTensor tensor in motionTensors) { tensor.Destroy(_intersectionEvent.EventTime, SimulationController); } //Create a new movement on the new spline MotionTensorComponent mtc = new MotionTensorComponent(nextSpline, MotionMode.ABSOLUTE, MotionType.TRANSLATION_AND_ROTATION, thickness, 1d, velocity, 0d); mtc.LookOffsetPercentage = 0d; List<MotionTensorComponent> components = new List<MotionTensorComponent>() {mtc}; MotionTensor motionTensor = new MotionTensor(components); motionTensor.IsRunning = true; SimulationController.AddActivityMidFrame(_intersectionEvent.EventTime, SimulationController.FrameTime, actor, motionTensor); return true; } }

The ChangeSplineInstructor has two actions, destroying the old movement:

And creating the new one

It’s important to always destroy the old movement so they don’t counteract one another. Also note that this uses AddActivityMidFrame instead of AddActivity that was used in the BasicMotionActor in the introduction. This is because the instructor is called mid frame while the BasicMotionActor uses OnSimulationStart. The AddActivityMidFrame uses the frametime passed and the total frametime. The passed frame time is the time passed in the current frame and the total frame time is the total length of the current frame. The passed frametime can be retrieved from the ActorCueIntersectionEvent.EventTime in the Instructor.ApplyInstruction or it is explicitly passed. The total frametime can be retrieved from the SimulationController.FrameTime. Actions that change something mid frame in the DES system need these two variables to work, if it is an option they should be passed.

Waiting

Next up is the AGV waiting for a box to come down the conveyor belt. First of we’ll generate the Cardboard Box Spline by creating shots of the box and then creating a spline with the Actor Route Creator. Make sure to set the Spline Up Direction Mode in the Actor Route Creator to “Free” so the up direction of the box is defined by the spline.

When the AGV arrives we want it to spawn and wait for the box, so we add a waiting instructor to the Box_Pickup_From_Spawn cue. The instructor is the WaitForBoxSpawnInstructor we add a new gameobject, add the instructor and select it in the cue’s “Cue Instructor“ field.

WaitForBoxSpawnInstructor

This sets the motion tensor to zero, stopping the motion. Then setting the waiting AGV so that the box knows what to move on, and then spawns a box. To spawn a box we use a custom spawner named the CardBoxSpawner.

CardBoxSpawner

Create a new gameobject and attach the CardBoxSpawner, then add the cardboard box to the scene and attach the CardBoxActor to the box gameobject (can be found earlier in the article). Then add a motion tensor in the CardBoxActor.MotionTensorView. Using the recently created cardbox spline, velocity of 1 and Component Motion Type to TRANSLATION_AND_ROTATION.

Then go to the CardBoxSpawner and select the CardBoxActor in the ”spawnObject”. Then go to the WaitForBoxSpawnInstructor and set the “Custom Spawner“ field to the just created CardBoxSpawner.

When the box is at the end of the spline it hits the cue (Box_Spawn_End) to parent the box to the AGV and restart the AGV motion. This uses the SetBoxOnAGVSpawnerInstructor instructor. Create a new gameobject, add the SetBoxOnAGVSpawnerInstructor and connect it from the Box_Spawn_End “Cue Instructor“ field. Then set the SetBoxOnAGVSpawnerInstructor “Wait For Box Spawn Instructor“ field to the previously created WaitForBoxSpawnInstructor.

SetBoxOnAGVSpawnerInstructor

Drop off the package for the metal detector

Next up is dropping the package off to go through the metal detector. First we create the shots necessary for the box to be dropped off and picked up again. Then generate the spline with the Actor Route Creator.

The easiest way to create the metal detector spline is to first create a instructor that stops the AGVActor on the cue. And then getting the position of the box as a starting point.

Next up is creating the Instructor to stop the AGV temporarily and moving the box on the metal detector spline. The DropOffMetalDetectorInstructor can then be connected to the Box_Dropoff_Metal_Detector cue to pause the AGV and move the box onto the metal detector.

DropOffMetalDetectorInstructor

Waiting for the box after the metal detector

After the metal detector the box returns on top of the AGV. This is almost the same action as when the AGV waits for the spawned box.

Firstly stop the AGV at the Box_Pickup_Metal_Detector cue with the PickupMetalDetectorInstructor instructor. The PickupMetalDetectorInstructor sets the velocity to zero and keeps track of which AGV is waiting. This way we can get which AGV is waiting when the box hits the MetalDetector_End cue.

PickupMetalDetectorInstructor

Next we’ll add the instructor for when the box hits it’s end cue MetalDetector_End. This references PickupMetalDetectorInstructor to get the AGV waiting, destroys it’s old movement, parents it to the AGV and then restarts the movement of the AGV.

SetBoxOnAGVMetalDetectorInstructor

Moving the box onto the exit conveyor belt and destroying

This movement is the exact same as the drop off at the metal detector so we can re-use the same instructor (DropOffMetalDetectorInstructor) on a different gameobject.

At the end of the box spline we add one more cue with a destroy instructor to destroy the boxes.

DestroyInstructor

Conclusion

With the DES system we can move objects over time. By using cues and instructors we can create precise and discrete simulations.

 

Prespective Documentation