/* ======================================================================== * Copyright (c) 2005-2026 The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ * ======================================================================*/ using Opc.Ua; namespace Robotics { /// /// Fixed geometry of the sample cell, matching the prims authored in /// Cell.usda. /// /// /// The separations here are what make the cell collision free, so they are stated once /// and asserted by the choreography tests rather than being spread through the code. /// public static class CellLayout { /// /// The X position of the western transfer station, in metres. /// public const double TableAX = -2.6; /// /// The X position of the eastern transfer station, in metres. /// public const double TableBX = 2.6; /// /// The Y position of both transfer stations, in metres. /// public const double TableY = 1.2; /// /// The height of a table top's surface, in metres. /// public const double TableSurfaceZ = 0.770; /// /// The X offsets of the three part slots on a table, in metres. /// /// /// Held as a single immutable value rather than rebuilt per access: slot positions /// are resolved throughout the simulation, and an ArrayOf can be shared /// safely where a cached double[] would hand every caller a writable /// reference to the one copy. /// public static ArrayOf SlotOffsetsX { get; } = new double[] { -0.22, 0.0, 0.22 }; /// /// The Y position a robot parks at to work a table, in metres. /// public const double TableApproachY = 0.35; /// /// The Y position of the eastbound travel lane, in metres. /// public const double EastboundLaneY = 0.35; /// /// The Y position of the westbound travel lane, in metres. /// public const double WestboundLaneY = -1.15; /// /// The half width of the shared corridor along X, in metres. /// /// /// Everything beyond this on either side is an end zone, which only one robot may /// occupy. A robot working a table at keeps its arm within /// , so a deployed arm never reaches the corridor. /// public const double CorridorHalfWidthX = 1.3; /// /// The bounding radius of the platform with the arm folded for transport, in metres. /// public const double TransportRadius = 0.65; /// /// The furthest a deployed arm is allowed to reach along X from its platform, in /// metres. /// public const double DeployedArmHalfWidthX = 0.45; /// /// The X position of the western charging dock, in metres. /// public const double DockD1X = -0.8; /// /// The X position of the eastern charging dock, in metres. /// public const double DockD2X = 0.8; /// /// The Y position of both charging docks, in metres. /// public const double DockY = -2.0; /// /// Returns the cell position of a part resting in a table slot. /// /// The station the slot belongs to. /// The zero based slot index. /// The slot centre, in metres. public static (double X, double Y, double Z) SlotPosition(CellStation table, int slot) { ArrayOf offsets = SlotOffsetsX; int index = slot < 0 ? 0 : slot % offsets.Count; double tableX = table == CellStation.TableA ? TableAX : TableBX; return (tableX + offsets[index], TableY, TableSurfaceZ + 0.0175); } } /// /// The transfer stations a part can rest on. /// public enum CellStation { /// /// The western station. /// TableA, /// /// The eastern station. /// TableB } /// /// The exclusive areas of the cell a robot has to reserve before entering. /// public enum CellZone { /// /// No reservation held. /// None, /// /// The western end of the cell, including table A. /// EndZoneA, /// /// The eastbound lane of the shared corridor. /// CorridorEastbound, /// /// The westbound lane of the shared corridor. /// CorridorWestbound, /// /// The eastern end of the cell, including table B. /// EndZoneB, /// /// The western charging dock, which sits clear of table A's working area so a robot /// waiting for work does not block the station. /// DockA, /// /// The eastern charging dock, which sits clear of table B's working area. /// DockB } /// /// The step a robot is currently performing. /// public enum RobotCycleState { /// /// Waiting for work. /// Idle, /// /// Waiting for a zone reservation another robot holds. /// Blocked, /// /// Driving to the station it collects from. /// TravelToSource, /// /// Reaching the arm over the source slot. /// ReachToSource, /// /// Closing the jaws on the part. /// Grip, /// /// Lifting the part clear and folding the arm for transport. /// Lift, /// /// Driving to the station it delivers to. /// TravelToTarget, /// /// Reaching the arm over the target slot. /// ReachToTarget, /// /// Opening the jaws to release the part. /// Release, /// /// Folding the arm back for transport. /// Retreat, /// /// Driving to the charging dock. /// TravelToDock, /// /// Sitting on the dock taking charge. /// Charging } }