public MotionUpdateArgs(Vector pos, Rotation ori, Joints axes, ExternalAxes extax) { this.Position = pos; this.Rotation = ori; this.Axes = axes; this.ExternalAxes = extax; }
//public ActionJoints(double j1, double j2, double j3, double j4, double j5, double j6, bool relative) : base() //{ // this.type = ActionType.Joints; // this.joints = new Joints(j1, j2, j3, j4, j5, j6); // this.relative = relative; //} //public ActionJoints(Joints joints, bool relative) // : this(joints.J1, joints.J2, joints.J3, joints.J4, joints.J5, joints.J6, relative) { } // shallow copy public ActionAxes(Joints joints, bool relative) { this.type = ActionType.Axes; this.joints = new Joints(joints); // shallow copy this.relative = relative; }
/// <summary> /// Apply Detach Tool action /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionDetach action) { if (this.tool == null) { Console.WriteLine("Robot had no tool attached"); return(false); } // Relative transform // If user issued a relative action, make sure there are absolute values to work with. (This limitation is due to current lack of FK/IK solvers) if (this.position == null || this.rotation == null) { Console.WriteLine("Sorry, must provide absolute transform values before detaching a tool... " + this); return(false); } // Now undo the tool's transforms // TODO: at some point in the future, check for translationFirst here Rotation newRot = Rotation.Combine(this.rotation, Rotation.Inverse(this.tool.TCPOrientation)); // postmultiplication by the inverse rotation Vector worldVector = Vector.Rotation(this.tool.TCPPosition, this.rotation); Vector newPos = this.position - worldVector; this.prevPosition = this.position; this.position = newPos; this.prevRotation = this.rotation; this.rotation = newRot; this.prevJoints = this.joints; this.joints = null; // Detach the tool this.tool = null; return(true); }
/// <summary> /// Minimum information necessary to initialize a robot object. /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="joints"></param> /// <returns></returns> public bool Initialize(Vector position, Rotation rotation, Joints joints, double speed, double acceleration, double rotationSpeed, double jointSpeed, double jointAcceleration, double precision, MotionType mType, ReferenceCS refCS) { if (position != null) { this.position = new Vector(position); this.prevPosition = new Vector(position); } if (rotation != null) { this.rotation = new Rotation(rotation); this.prevRotation = new Rotation(rotation); } if (joints != null) { this.joints = new Joints(joints); this.prevJoints = new Joints(joints); } this.acceleration = acceleration; this.speed = speed; this.rotationSpeed = rotationSpeed; this.jointSpeed = jointSpeed; this.jointAcceleration = jointAcceleration; this.precision = precision; this.motionType = mType; this.referenceCS = refCS; this.externalAxes = new double?[] { null, null, null, null, null, null }; // @TODO: should this be passed as an argument? this.initialized = true; return(this.initialized); }
// ╔═╗╔═╗╦═╗╔═╗╔═╗╔╦╗ ╦ ╦╔═╗╔╦╗╔═╗╔╦╗╔═╗╔═╗ // ╠╣ ║ ║╠╦╝║ ║╣ ║║ ║ ║╠═╝ ║║╠═╣ ║ ║╣ ╚═╗ // ╚ ╚═╝╩╚═╚═╝╚═╝═╩╝ ╚═╝╩ ═╩╝╩ ╩ ╩ ╚═╝╚═╝ /// <summary> /// Force-update a full pose without going through Action application. /// Temporarily here for MotionUpdate cursors, until I figure out a better way of dealing with it... /// </summary> /// <param name="pos"></param> /// <param name="rot"></param> /// <param name="ax"></param> /// <param name="extax"></param> internal void UpdateFullPose(Vector pos, Rotation rot, Joints ax, ExternalAxes extax) { this.position = pos; this.rotation = rot; this.axes = ax; this.externalAxesCartesian = extax; }
/// <summary> /// Minimum information necessary to initialize a robot object. /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="joints"></param> /// <returns></returns> public bool Initialize(Vector position, Rotation rotation, Joints joints, double speed, double acceleration, double rotationSpeed, double jointSpeed, double jointAcceleration, double precision, MotionType mType, ReferenceCS refCS) { if (position != null) { this.position = new Vector(position); this.prevPosition = new Vector(position); } if (rotation != null) { this.rotation = new Rotation(rotation); this.prevRotation = new Rotation(rotation); } if (joints != null) { this.joints = new Joints(joints); this.prevJoints = new Joints(joints); } this.acceleration = acceleration; this.speed = speed; this.rotationSpeed = rotationSpeed; this.jointSpeed = jointSpeed; this.jointAcceleration = jointAcceleration; this.precision = precision; this.motionType = mType; this.referenceCS = refCS; this.initialized = true; return(this.initialized); }
public ActionIssuedArgs(Action last, Vector pos, Rotation ori, Joints axes, ExternalAxes extax) { this.LastAction = last; this.Position = pos; this.Rotation = ori; this.Axes = axes; this.ExternalAxes = ExternalAxes; }
/// <summary> /// Apply Rotation Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionRotation action) { Rotation newRot; // @TODO: implement some kind of security check here... if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with (this limitation is due to current lack of FK/IK solvers). if (position == null || rotation == null) { logger.Warning($"Cannot apply \"{action}\", must provide absolute rotation values first before applying relative ones... "); return(false); } prevRotation = rotation; if (referenceCS == ReferenceCS.World) { //rotation.RotateGlobal(action.rotation); newRot = Rotation.Global(rotation, action.rotation); // @TODO: TEST THIS } else { //rotation.RotateLocal(action.rotation); newRot = Rotation.Local(rotation, action.rotation); // @TODO: TEST THIS } } else { // Fail if issued abs rotation without prior position info (this limitation is due to current lack of FK/IK solvers). if (position == null) { logger.Warning($"Cannot apply \"{action}\", currently missing TCP position to work with... "); return(false); } newRot = new Rotation(action.rotation); } prevRotation = rotation; rotation = newRot; prevPosition = position; // to flag same-position change prevAxes = axes; axes = null; // flag joints as null to avoid Joint instructions using obsolete data if (isExtruding) { this.ComputeExtrudedLength(); } if (_logRelativeActions && action.relative) { logger.Verbose("TCP orientation at " + new Orientation(this.rotation)); } return(true); }
public Joints(Joints j) { this.J1 = j.J1; this.J2 = j.J2; this.J3 = j.J3; this.J4 = j.J4; this.J5 = j.J5; this.J6 = j.J6; }
public static Joints Add(Joints j1, Joints j2) { return(new Joints(j1.J1 + j2.J1, j1.J2 + j2.J2, j1.J3 + j2.J3, j1.J4 + j2.J4, j1.J5 + j2.J5, j1.J6 + j2.J6)); }
public void Set(Joints j) { this.J1 = j.J1; this.J2 = j.J2; this.J3 = j.J3; this.J4 = j.J4; this.J5 = j.J5; this.J6 = j.J6; }
public void Add(Joints j) { this.J1 += j.J1; this.J2 += j.J2; this.J3 += j.J3; this.J4 += j.J4; this.J5 += j.J5; this.J6 += j.J6; }
/// <summary> /// Minimum information necessary to initialize a robot object. /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="joints"></param> /// <returns></returns> public bool Initialize(Vector position, Rotation rotation, Joints joints, ExternalAxes extAx, double speed, double acceleration, double precision, MotionType mType, ReferenceCS refCS) { if (position != null) { this.position = new Vector(position); this.prevPosition = new Vector(position); } if (rotation != null) { this.rotation = new Rotation(rotation); this.prevRotation = new Rotation(rotation); } if (joints != null) { this.axes = new Joints(joints); this.prevAxes = new Joints(joints); } if (extAx != null) { // @TODO split this definition this.externalAxesCartesian = new ExternalAxes(extAx); this.externalAxesJoints = new ExternalAxes(extAx); } this.acceleration = acceleration; this.speed = speed; this.precision = precision; this.motionType = mType; this.referenceCS = refCS; this.availableTools = new Dictionary <string, Tool>(); // Add a "noTool" default object and make it the default. //this.availableTools["noTool"] = Tool.Create("noTool", 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.001, 0, 0, 0); //this.tool = this.availableTools["noTool"]; this.tool = null; // reverted back to default `null` tool... this.digitalOutputs = new Dictionary <string, bool>(); this.analogOutputs = new Dictionary <string, double>(); // Initialize temps to zero this.partTemperature = new Dictionary <RobotPartType, double>(); foreach (RobotPartType part in Enum.GetValues(typeof(RobotPartType))) { partTemperature[part] = 0; } isExtruding = false; extrusionRate = 0; extrudedLength = 0; this.initialized = true; return(this.initialized); }
internal void UpdateRobotStatus() { if (bot == null) { ResetRobotStatus(); return; } uiContext.Post(x => { Machina.Vector pos = bot.GetCurrentPosition(); string posStr = pos?.ToString(true) ?? "-"; lbl_Status_TCP_Position_Value.Content = posStr; Machina.Orientation ori = bot.GetCurrentRotation(); string oriStr = ori?.ToString(true) ?? "-"; lbl_Status_TCP_Orientation_Value.Content = oriStr; Machina.Joints axes = bot.GetCurrentAxes(); string axesStr = axes?.ToString(true) ?? "-"; lbl_Status_Axes_Value.Content = axesStr; Machina.ExternalAxes extax = bot.GetCurrentExternalAxes(); bool nullext = true; if (extax != null) { for (int i = 0; i < 6; i++) { if (extax[i] != null) { nullext = false; break; } } } lbl_Status_Ext_Axes_Value.Content = nullext ? "-" : extax.ToString(true); double speed = bot.GetCurrentSpeed(); double acc = bot.GetCurrentAcceleration(); string speedacc = Math.Round(speed, Machina.Geometry.STRING_ROUND_DECIMALS_MM) + " mm/s / " + Math.Round(acc, Machina.Geometry.STRING_ROUND_DECIMALS_MM) + " mm/s^2"; lbl_Status_SpeedAcceleration_Value.Content = speedacc; double precision = bot.GetCurrentPrecision(); lbl_Status_Precision_Value.Content = Math.Round(precision, Machina.Geometry.STRING_ROUND_DECIMALS_MM) + " mm"; Machina.MotionType mtype = bot.GetCurrentMotionMode(); lbl_Status_MotionMode_Value.Content = mtype.ToString(); lbl_Status_Tool_Value.Content = bot.GetCurrentTool()?.name ?? "(no tool)"; }, null); }
/// <summary> /// Returns a UR joint representation of the current state of the cursor. /// </summary> /// <returns></returns> internal static string GetJointTargetValue(RobotCursor cursor) { Joints jrad = new Joints(cursor.joints); // use a shallow copy jrad.Scale(Geometry.TO_RADS); // convert to radians return(string.Format("[{0},{1},{2},{3},{4},{5}]", Math.Round(jrad.J1, Geometry.STRING_ROUND_DECIMALS_RADS), Math.Round(jrad.J2, Geometry.STRING_ROUND_DECIMALS_RADS), Math.Round(jrad.J3, Geometry.STRING_ROUND_DECIMALS_RADS), Math.Round(jrad.J4, Geometry.STRING_ROUND_DECIMALS_RADS), Math.Round(jrad.J5, Geometry.STRING_ROUND_DECIMALS_RADS), Math.Round(jrad.J6, Geometry.STRING_ROUND_DECIMALS_RADS))); }
/// <summary> /// Apply Rotation Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionRotation action) { Rotation newRot; // @TODO: implement some kind of security check here... if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with (this limitation is due to current lack of FK/IK solvers). if (position == null || rotation == null) { Console.WriteLine("Sorry, must provide absolute rotation values first before applying relative ones... " + this); return(false); } prevRotation = rotation; if (referenceCS == ReferenceCS.World) { //rotation.RotateGlobal(action.rotation); newRot = Rotation.Global(rotation, action.rotation); // @TODO: TEST THIS } else { //rotation.RotateLocal(action.rotation); newRot = Rotation.Local(rotation, action.rotation); // @TODO: TEST THIS } } else { // Fail if issued abs rotation without prior position info (this limitation is due to current lack of FK/IK solvers). if (position == null) { Console.WriteLine("Sorry, currently missing TCP position to work with... " + this); return(false); } newRot = new Rotation(action.rotation); } prevRotation = rotation; rotation = newRot; prevJoints = joints; joints = null; // flag joints as null to avoid Joint instructions using obsolete data if (isExtruding) { this.ComputeExtrudedLength(); } return(true); }
internal bool InitializeRobotCursors() { if (_driver == null) { throw new Exception("Cannot initialize Robotcursors without a _comm object"); } // If successful, initialize robot cursors to mirror the state of the device Vector currPos = _driver.GetCurrentPosition(); Rotation currRot = _driver.GetCurrentOrientation(); Joints currJnts = _driver.GetCurrentJoints(); return(InitializeRobotCursors(currPos, currRot, currJnts)); }
/// <summary> /// Apply Joints Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionAxes action) { Joints newJnt; // @TODO: implement joint limits checks and general safety... // Modify current Joints if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with. // (This limitation is due to current lack of FK/IK solvers) if (axes == null) // could also check for motionType == MotionType.Joints ? { logger.Warning($"Cannot apply \"{action}\", must provide absolute Joints values first before applying relative ones..."); return(false); } newJnt = Joints.Add(axes, action.joints); } else { newJnt = new Joints(action.joints); } prevAxes = axes; axes = newJnt; // Flag the lack of other geometric data prevPosition = position; position = null; prevRotation = rotation; rotation = null; if (isExtruding) { this.ComputeExtrudedLength(); } if (_logRelativeActions && action.relative) { logger.Verbose("Axes at " + this.axes); } return(true); }
/// <summary> /// Apply Joints Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionAxes action) { Joints newJnt; // @TODO: implement joint limits checks and general safety... // Modify current Joints if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with. // (This limitation is due to current lack of FK/IK solvers) if (joints == null) // could also check for motionType == MotionType.Joints ? { Console.WriteLine("Sorry, must provide absolute Joints values first before applying relative ones..." + this); return(false); } newJnt = Joints.Add(joints, action.joints); } else { newJnt = new Joints(action.joints); } prevJoints = joints; joints = newJnt; // Flag the lack of other geometric data prevPosition = position; position = null; prevRotation = rotation; rotation = null; if (isExtruding) { this.ComputeExtrudedLength(); } return(true); }
/// <summary> /// Apply Transformation Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionTransformation action) { Vector newPos; Rotation newRot; // Relative transform if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with. (This limitation is due to current lack of FK/IK solvers) if (position == null || rotation == null) { logger.Warning($"Cannot apply \"{action}\", must provide absolute transform values first before applying relative ones..."); return(false); } // This is Translate + Rotate if (action.translationFirst) { if (referenceCS == ReferenceCS.World) { newPos = position + action.translation; newRot = Rotation.Combine(action.rotation, rotation); // premultiplication } else { //Vector worldVector = Vector.Rotation(action.translation, Rotation.Conjugate(this.rotation)); Vector worldVector = Vector.Rotation(action.translation, this.rotation); newPos = position + worldVector; newRot = Rotation.Combine(rotation, action.rotation); // postmultiplication } } // or Rotate + Translate else { if (referenceCS == ReferenceCS.World) { newPos = position + action.translation; newRot = Rotation.Combine(action.rotation, rotation); // premultiplication } else { // @TOCHECK: is this correct? newRot = Rotation.Combine(rotation, action.rotation); // postmultiplication //Vector worldVector = Vector.Rotation(action.translation, Rotation.Conjugate(newRot)); Vector worldVector = Vector.Rotation(action.translation, newRot); newPos = position + worldVector; } } } // Absolute transform else { newPos = new Vector(action.translation); newRot = new Rotation(action.rotation); } //// @TODO: this must be more programmatically implemented //if (Control.SAFETY_CHECK_TABLE_COLLISION) //{ // if (Control.IsBelowTable(newPos.Z)) // { // if (Control.SAFETY_STOP_ON_TABLE_COLLISION) // { // Console.WriteLine("Cannot perform action: too close to base XY plane --> TCP.z = {0}", newPos.Z); // return false; // } // else // { // Console.WriteLine("WARNING: too close to base XY plane, USE CAUTION! --> TCP.z = {0}", newPos.Z); // } // } //} prevPosition = position; position = newPos; prevRotation = rotation; rotation = newRot; prevAxes = axes; axes = null; // flag joints as null to avoid Joint instructions using obsolete data if (isExtruding) { this.ComputeExtrudedLength(); } if (_logRelativeActions && action.relative) { logger.Verbose("TCP transform at " + this.position + " " + new Orientation(this.rotation)); } return(true); }
// ╔╦╗╔═╗╔╦╗╦╔═╗╔╗╔ ╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗ // ║║║║ ║ ║ ║║ ║║║║ ╠═╣║ ║ ║║ ║║║║╚═╗ // ╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝ ╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ /// <summary> /// Apply Translation Action. /// </summary> /// <param name="action"></param> /// <returns></returns> public bool ApplyAction(ActionTranslation action) { Vector newPosition = new Vector(); if (action.relative) { // If user issued a relative action, make sure there are absolute values to work with. (This limitation is due to current lack of FK/IK solvers) if (position == null || rotation == null) { logger.Warning($"Cannot apply \"{action}\", must provide absolute position values first before applying relative ones... "); return(false); } if (referenceCS == ReferenceCS.World) { newPosition = position + action.translation; } else { //Vector worldVector = Vector.Rotation(action.translation, Rotation.Conjugate(this.rotation)); Vector worldVector = Vector.Rotation(action.translation, this.rotation); newPosition = position + worldVector; } } else { // Fail if issued abs movement without prior rotation info. (This limitation is due to current lack of FK/IK solvers) if (rotation == null) { logger.Warning($"Cannot apply \"{action}\", currently missing TCP orientation to work with... "); return(false); } newPosition.Set(action.translation); } // @TODO: this must be more programmatically implemented //if (Control.SAFETY_CHECK_TABLE_COLLISION) //{ // if (Control.IsBelowTable(newPosition.Z)) // { // if (Control.SAFETY_STOP_ON_TABLE_COLLISION) // { // Console.WriteLine("Cannot perform action: too close to base XY plane --> TCP.z = {0}", newPosition.Z); // return false; // } // else // { // Console.WriteLine("WARNING: too close to base XY plane, USE CAUTION! --> TCP.z = {0}", newPosition.Z); // } // } //} prevPosition = position; position = newPosition; prevRotation = rotation; // to flag same-orientation change prevAxes = axes; axes = null; // flag joints as null to avoid Joint instructions using obsolete data if (isExtruding) { this.ComputeExtrudedLength(); } if (_logRelativeActions && action.relative) { logger.Verbose("TCP position at " + this.position); } return(true); }
public ActionAxes(Joints joints, bool relative) : base() { this.joints = new Joints(joints); // shallow copy this.relative = relative; }
public ActionReleasedArgs(Action last, int pendingReleaseToDevice, Vector pos, Rotation ori, Joints axes, ExternalAxes extax) { this.LastAction = last; this.PendingReleaseToDevice = pendingReleaseToDevice; this.Position = pos; this.Rotation = ori; this.Axes = axes; this.ExternalAxes = ExternalAxes; }
///// <summary> ///// If there was a running Communication protocol, drop it and restart it again. ///// </summary> ///// <returns></returns> //private bool ResetCommunication() //{ // if (_driver == null) // { // Console.WriteLine("Communication protocol not established, please initialize first."); // } // DropCommunication(); // return InitializeCommunication(); //} /// <summary> /// Initializes all instances of robotCursors with base information /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="joints"></param> /// <returns></returns> internal bool InitializeRobotCursors(Point position = null, Rotation rotation = null, Joints joints = null, ExternalAxes extAx = null, double speed = Control.DEFAULT_SPEED, double acc = Control.DEFAULT_ACCELERATION, double precision = Control.DEFAULT_PRECISION, MotionType mType = Control.DEFAULT_MOTION_TYPE, ReferenceCS refCS = Control.DEFAULT_REFCS) { bool success = true; success &= IssueCursor.Initialize(position, rotation, joints, extAx, speed, acc, precision, mType, refCS); success &= ReleaseCursor.Initialize(position, rotation, joints, extAx, speed, acc, precision, mType, refCS); success &= ExecutionCursor.Initialize(position, rotation, joints, extAx, speed, acc, precision, mType, refCS); _areCursorsInitialized = success; return(success); }
///// <summary> ///// If there was a running Communication protocol, drop it and restart it again. ///// </summary> ///// <returns></returns> //private bool ResetCommunication() //{ // if (_driver == null) // { // Console.WriteLine("Communication protocol not established, please initialize first."); // } // DropCommunication(); // return InitializeCommunication(); //} /// <summary> /// Initializes all instances of robotCursors with base information /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <param name="joints"></param> /// <returns></returns> internal bool InitializeRobotCursors(Point position = null, Rotation rotation = null, Joints joints = null, double speed = Control.DEFAULT_SPEED, double acc = Control.DEFAULT_ACCELERATION, double rotationSpeed = Control.DEFAULT_ROTATION_SPEED, double jointSpeed = Control.DEFAULT_JOINT_SPEED, double jointAcceleration = Control.DEFAULT_JOINT_ACCELERATION, double precision = Control.DEFAULT_PRECISION, MotionType mType = Control.DEFAULT_MOTION_TYPE, ReferenceCS refCS = Control.DEFAULT_REFCS) { bool success = true; success &= virtualCursor.Initialize(position, rotation, joints, speed, acc, jointSpeed, jointAcceleration, rotationSpeed, precision, mType, refCS); success &= writeCursor.Initialize(position, rotation, joints, speed, acc, jointSpeed, jointAcceleration, rotationSpeed, precision, mType, refCS); success &= motionCursor.Initialize(position, rotation, joints, speed, acc, jointSpeed, jointAcceleration, rotationSpeed, precision, mType, refCS); _areCursorsInitialized = success; return(success); }
/// <summary> /// Issue a request to set the values of joint angles in configuration space. /// </summary> /// <param name="joints"></param> /// <param name="relJnts"></param> /// <param name="speed"></param> /// <param name="zone"></param> /// <returns></returns> public bool IssueJointsRequest(Joints joints, bool relJnts) => IssueApplyActionRequest(new ActionAxes(joints, relJnts));
public static ActionAxes Axes(Joints jointsInc) { return(new ActionAxes(jointsInc, true)); }
public static ActionAxes AxesTo(Joints joints) { return(new ActionAxes(joints, false)); }
public ActionExecutedArgs(Action last, int pendingExecutionOnDevice, int pendingExecutionTotal, Vector pos, Rotation ori, Joints axes, ExternalAxes extax) { this.LastAction = last; this.PendingExecutionOnDevice = pendingExecutionOnDevice; this.PendingExecutionTotal = pendingExecutionTotal; this.Position = pos; this.Rotation = ori; this.Axes = axes; this.ExternalAxes = ExternalAxes; }