/// <summary>Method that executes a command for an instance of the CartesianMoveCommand class</summary> /// <author>Damian Jimenez</author> /// <param name="robot">The robot that is to be controlled via the API call</param> /// <param name="cartesianMove">Cartesian move object to handle calculating the motion of the robot</param> /// <returns><c>void</c></returns> public Response Execute(IAdeptRobot robot, CartesianMove cartesianMove) { string joint_string; string jsonString; string locationString; byte[] jsonBytes; if (app_config.ThreadingEnabled) { _SEMAPHORE.WaitOne(); } /*################################################################################ ########################## BEGINNING OF PROTECTED BLOCK ########################## ################################################################################*/ { _ROBOT_BUSY = true; _CURRENT_MOVE_CMDS += 1; try { // Get the current joint positions of the robot double[] jointPositions = robot.JointPosition; // Print out joint information for the user to see WriteOutput("Current joint values:"); foreach (var joint in jointPositions.Select((value, i) => new { i, value })) { WriteOutput($"joint[{joint.i}] = {joint.value}"); } // Assign the cartesianMove the parameters that were passed via the API call cartesianMove.Param.Accel = Accel; cartesianMove.Param.Decel = Decel; cartesianMove.Param.Speed = Speed; cartesianMove.Param.Straight = StraightMotion; cartesianMove.Param.MotionEnd = MOTION_END[MotionEnd]; cartesianMove.Param.SCurveProfile = SCurveProfile; // Transform the current joint position to a world location Transform3D loc = robot.JointToWorld(jointPositions); // Check if the current location is in-range Transform3D currentPosition = robot.WorldLocationWithTool; bool inRange = robot.InRange(currentPosition) == 0 ? true: false; WriteOutput($"[{currentPosition}]\nMotion in range: {inRange}\n"); // Get the current robot configuration IMoveConfiguration moveConfig = robot.GetMoveConfiguration(jointPositions); // Create a new Transform3D object specifying how the robot should move cartesianMove.MoveConfiguration = moveConfig; Transform3D transform = new Transform3D(X, Y, Z, Yaw, Pitch, Roll); // Calculate the new position of the robot based on the transform and the robots current position cartesianMove.WorldLocation = currentPosition * transform; // Write out the CartesianMove that is to be executed to the console and GUI WriteOutput(cartesianMove.Description); // Issue the move and wait until it is done robot.Move(cartesianMove); robot.WaitMoveDone(); // Force the robot to issue a DETACH robot.AutomaticControlActive = false; joint_string = String.Join(",", robot.JointPosition.Select(p => p.ToString()).ToArray()); locationString = String.Join(",", ($"{robot.WorldLocationWithTool}".Split(' ')).Select(p => p.ToString()).ToArray()); jsonString = $"{{\"robot_joints\": [{joint_string}]," + $"\"robot_with_tool_world_location\": [{locationString}]}}"; jsonBytes = Encoding.UTF8.GetBytes(jsonString); } catch (Exception e) { jsonString = $"{{\"error\": \"{e.Message}\"}}"; jsonBytes = Encoding.UTF8.GetBytes(jsonString); WriteOutput($"Unable to move the robot.\nERROR: {e.Message}\n"); } _CURRENT_MOVE_CMDS -= 1; _ROBOT_BUSY = (_CURRENT_MOVE_CMDS == 0 ? false : true); } /*################################################################################ ############################# END OF PROTECTED BLOCK ############################# ################################################################################*/ if (app_config.ThreadingEnabled) { _SEMAPHORE.Release(); } return(new Response() { StatusCode = HttpStatusCode.OK, ContentType = "application/json", ReasonPhrase = "POST request received for endpoint [/api/move/cartesian].", Headers = new Dictionary <string, string>() { { "Content-Type", "application/json" } }, Contents = c => c.Write(jsonBytes, 0, jsonBytes.Length) }); }
/// <summary>Method that executes a command for an instance of the JointMoveCommand class</summary> /// <author>Damian Jimenez</author> /// <param name="robot">The robot that is to be controlled via the API call</param> /// <param name="jointMove"><c>JointMove</c> object to handle calculating the motion of the joints of the robot</param> /// <returns><c>void</c></returns> public Response Execute(IAdeptRobot robot, JointMove jointMove) { string joint_string; string jsonString; string locationString; byte[] jsonBytes; if (app_config.ThreadingEnabled) { _SEMAPHORE.WaitOne(); } /*################################################################################ ########################## BEGINNING OF PROTECTED BLOCK ########################## ################################################################################*/ { _ROBOT_BUSY = true; _CURRENT_MOVE_CMDS += 1; try { jointMove.Initialize(); // Get the current joint positions of the robot double[] jointPositions = robot.JointPosition; // Print out joint information for the user to see WriteOutput("Current joint values:"); foreach (var joint in jointPositions.Select((value, i) => new { i, value })) { WriteOutput($"joint[{joint.i}] = {joint.value}"); } // Assign jointMove the parameters that were passed via the API call jointMove.Param.Accel = Accel; jointMove.Param.Decel = Decel; jointMove.Param.Speed = Speed; jointMove.Param.Straight = StraightMotion; jointMove.Param.MotionEnd = MOTION_END[MotionEnd]; jointMove.Param.SCurveProfile = SCurveProfile; jointMove.JointPosition = JointPosition; // Assigning the robot that was passed as the one that will execute the move jointMove.Robot = robot; // Write out the JointMove that is to be executed to the console and GUI WriteOutput(jointMove.Description); // Execute the move robot.Move(jointMove); // Wait for the robot to finish moving robot.WaitMoveDone(); // Force the robot to issue a DETACH robot.AutomaticControlActive = false; joint_string = String.Join(",", robot.JointPosition.Select(p => p.ToString()).ToArray()); locationString = String.Join(",", ($"{robot.WorldLocationWithTool}".Split(' ')).Select(p => p.ToString()).ToArray()); jsonString = $"{{\"robot_joints\": [{joint_string}]," + $"\"robot_with_tool_world_location\": [{locationString}]}}"; jsonBytes = Encoding.UTF8.GetBytes(jsonString); } catch (Exception e) { jsonString = $"{{\"error\": \"{e.Message}\"}}"; jsonBytes = Encoding.UTF8.GetBytes(jsonString); WriteOutput($"Unable to move the robot.\nERROR: {e.Message}\n"); } _CURRENT_MOVE_CMDS -= 1; _ROBOT_BUSY = (_CURRENT_MOVE_CMDS == 0 ? false : true); } /*################################################################################ ############################# END OF PROTECTED BLOCK ############################# ################################################################################*/ if (app_config.ThreadingEnabled) { _SEMAPHORE.Release(); } return(new Response() { StatusCode = HttpStatusCode.OK, ContentType = "application/json", ReasonPhrase = "POST request received for endpoint [/api/move/joints].", Headers = new Dictionary <string, string>() { { "Content-Type", "application/json" } }, Contents = c => c.Write(jsonBytes, 0, jsonBytes.Length) }); }
/// <summary>Method that loads the controller and robot specified in the GUI combo-boxes</summary> /// <author>Damian Jimenez</author> /// <param name="controllerPath">Specifies where the server should search for the controller, can be found by opening up a default workspace in Adept ACE and connecting to a desired robot.</param> /// <param name="robotPath">Specifies where the server should search for the robot, can be found by opening up a default workspace in Adept ACE and connecting to a desired robot.</param> /// <returns><c>void</c></returns> public void LoadControllerAndRobot(String controllerPath, String robotPath) { // Trim any leading and trailing white-space from the input controllerPath = controllerPath.Trim(); robotPath = robotPath.Trim(); // If either paths are empty, then let the user know if (controllerPath == "" || robotPath == "") { Console.WriteLine("\nERROR: A valid controller and/or robot path was not selected. Please select them from the dropdown menus and try again.\n"); } else { // If this is not the first time loading a controller, disable the current controller if (controller != null) { controller.HighPower = false; controller.Enabled = false; controller = null; } // Load the new controller controller = ace.Root[controllerPath] as IAdeptController; // If the new controller was successfully loaded do the following if (controller != null) { // Enable and calibrate the controller controller.Enabled = true; controller.HighPower = true; controller.Calibrate(); if (!controller.IsEVPlus) { controller.DryRun = true; controller.DryRun = false; } // Add all available robots to the controller AdeptControllerUtil.AddAllRobots(ace, controller, ace.Root); // Reset the current robot to null robot = null; // Assign the new robot as our current robot robot = ace.Root[robotPath] as IAdeptRobot; // If we loaded the robot successfully then let the user know if (robot != null) { Console.WriteLine($"Successfully loaded:\n\tController: {controllerPath}\n\tRobot: {robotPath}\n"); } // Else the robot wasn't found and the user should know that there is an issue else { Console.WriteLine("\nERROR: The specified robot was not found, please make sure the spelling is correct and that it exists.\n"); } } // Else the controller wasn't found and the user should know that there is an issue else { Console.WriteLine("\nERROR: The specified controller was not found, please make sure the spelling is correct and that it exists.\n"); } } }