UnderAutomation
Eine Frage?

[email protected]

Kontakt
UnderAutomation
⌘Q
Diese Seite ist nur auf Englisch verfügbar.

Send trajectories

Queue joint or Cartesian trajectories, send your own positions, and control the motion with override, pause and abort.

  • Queue trajectories
  • Cartesian trajectories
  • Send your own positions
  • Override, pause and abort
  • When the queue is empty
  • API reference

The easiest way to move the robot with Stream Motion is to give it complete trajectories. The client keeps them in a queue and sends them one after the other, at the communication cycle of the robot.

Queue trajectories

Create a trajectory with the motion planner, then call Enqueue(). It returns an identifier to wait for this motion.

var sm = robot.StreamMotion;
sm.StartMonitoring();
sm.MotionCompleted += (sender, e) => Console.WriteLine($"Motion {e.MotionId} completed");
var planner = new MotionPlanner(sm.JointLimits, null);
// Each trajectory starts where the previous one ends: QueueEndJointPosition
JointsPosition home = sm.QueueEndJointPosition;
var p1 = new JointsPosition(home.Values) { J1 = home.J1 + 15 };
int first = sm.Enqueue(planner.CreateJointPath(FanucMotion.ToJointValues(home)).MoveJoint(FanucMotion.ToJointValues(p1), 50, FanucMotion.Fine()).Build());
var p2 = new JointsPosition(p1.Values) { J2 = p1.J2 + 10 };
int second = sm.Enqueue(planner.CreateJointPath(FanucMotion.ToJointValues(sm.QueueEndJointPosition)).MoveJoint(FanucMotion.ToJointValues(p2), 50, FanucMotion.Fine()).Build());
int back = sm.Enqueue(planner.CreateJointPath(FanucMotion.ToJointValues(sm.QueueEndJointPosition)).MoveJoint(FanucMotion.ToJointValues(home), 50, FanucMotion.Fine()).Build());
// Wait for one motion, or for the whole queue
sm.WaitForMotion(first, 30000);
sm.WaitForIdle(60000);
robot.Disconnect();
}
Click to see the full code
The three trajectories of this example, played one after the other.The three trajectories of this example, played one after the other.
The three trajectories of this example, played one after the other.

Rules of the queue:

  • Each trajectory must start where the previous one ends. Use QueueEndJointPosition or QueueEndCartesianPosition as start position: when the queue is empty, it is the current position of the robot.
  • Trajectories are played one after the other without any change. To join two motions without stop, put them in the same trajectory (CNT, CR or spline).
  • All trajectories of a session use the same format, joint or Cartesian. To change the format, finish the session first (see one format per session). ActiveFormat gives the current format.
  • The session starts when the first trajectory is queued and a program waits on IBGN start. You can queue trajectories before.

WaitForMotion() returns when the robot received the last position of the trajectory, WaitForIdle() when the queue is empty and the robot is at rest. The MotionCompleted event is raised for each trajectory.

Cartesian trajectories

Cartesian trajectories work the same way. Give Cartesian limits to the planner, because the robot does not provide them:

var sm = robot.StreamMotion;
sm.StartMonitoring();
// Cartesian limits are not known by the robot: give yours
var cartesianLimits = new CartesianLimits(250, 1000, 5000, 45, 180, 900);
var planner = new MotionPlanner(sm.JointLimits, cartesianLimits);
// Cartesian positions sent to the robot: flange center in the world frame
XYZWPRPosition start = sm.QueueEndCartesianPosition;
var down = new XYZWPRPosition(start.X, start.Y, start.Z - 50, start.W, start.P, start.R);
Trajectory trajectory = planner.CreateCartesianPath(FanucMotion.ToCartesianPose(start))
.MoveLinear(FanucMotion.ToCartesianPose(down), 100, FanucMotion.Fine())
.MoveLinear(FanucMotion.ToCartesianPose(start), 100, FanucMotion.Fine())
.Build();
sm.WaitForMotion(sm.Enqueue(trajectory), 30000);
robot.Disconnect();
}
Click to see the full code

Good to know:

  • The positions are the flange center in the world frame. Some controllers (for example the CRX) expect the position of the active tool: select a tool frame equal to zero, or give the planner the tool of the robot (see tool and user frames).
  • The robot converts each position into joint positions and checks the joint limits. The SDK cannot check them for Cartesian positions: choose prudent Cartesian limits and validate them on the robot.
  • Cartesian positions are always sent in single precision. At 2 ms, changes of orientation can exceed the jerk limit of the wrist because of rounding. Prefer joint trajectories for large changes of orientation.

Send your own positions

If your application already computes one position per cycle, create the trajectory from these samples. They are sent without any change, so check them first:

var sm = robot.StreamMotion;
sm.StartMonitoring();
// Your own positions, one per communication cycle
double cycle = sm.CycleTime;
JointsPosition start = sm.QueueEndJointPosition;
var samples = new List<JointsPosition>();
int count = (int)(3.0 / cycle);
for (int i = 0; i <= count; i++)
{
// J1 +10 degrees with a smooth cosine profile
double s = (1 - Math.Cos(Math.PI * i / count)) / 2;
samples.Add(new JointsPosition(start.Values) { J1 = start.J1 + 10 * s });
}
Trajectory trajectory = Trajectory.FromJointSamples(samples.Select(FanucMotion.ToJointValues).ToArray(), cycle);
// The positions are sent as they are: check them against the limits of the robot first
TrajectoryReport report = trajectory.Check(sm.JointLimits, cycle, sm.ProtocolVersion == 1);
if (!report.IsValid) trajectory = trajectory.Retime(sm.JointLimits, cycle, sm.ProtocolVersion == 1);
sm.WaitForMotion(sm.Enqueue(trajectory), 30000);
robot.Disconnect();
}
Click to see the full code

The period of the samples must be the communication cycle of the robot (CycleTime). To give positions at other times, use timed points (see Trajectories from points).

Override, pause and abort

The robot runs at 100% override during Stream Motion. The client can slow down the trajectories on their path:

var target = new JointsPosition(start.Values) { J1 = start.J1 + 30 };
sm.Enqueue(planner.CreateJointPath(FanucMotion.ToJointValues(start)).MoveJoint(FanucMotion.ToJointValues(target), 10, FanucMotion.Fine()).Build());
// Slow down the queued trajectories on their path (the robot runs at 100% override)
sm.Override = 50;
// Stop smoothly on the path, then continue
sm.Pause();
Thread.Sleep(2000);
sm.Resume();
// Stop smoothly on the path and cancel all queued trajectories. The session stays open.
sm.Abort();
sm.WaitForIdle(10000);
// The next trajectory starts from the stop position
JointsPosition stoppedAt = sm.QueueEndJointPosition;
robot.Disconnect();
}
Click to see the full code
Speed and progress on the queued trajectories with Override, Pause(), Resume() and Abort().Speed and progress on the queued trajectories with Override, Pause(), Resume() and Abort().
Speed and progress on the queued trajectories with Override, Pause(), Resume() and Abort().
  • Override (1 to 100%) changes the speed progressively. The positions are the same, only the time changes.
  • Pause() stops the robot smoothly on its path. Resume() continues.
  • Abort() stops the robot smoothly on its path, then cancels the current and the queued trajectories. The session stays open.

The HOLD button of the teach pendant is not available during a session: use Pause().

When the queue is empty

  • If the robot is at rest, the client keeps sending the last position and the session stays open.
  • If the robot is moving (the trajectories were not queued fast enough), the client stops the robot smoothly within its limits and raises the Underrun event.

API reference


Integrieren Sie Roboter von Universal Robots, Fanuc, Yaskawa, ABB oder Staubli ganz einfach in Ihre .NET-, Python-, LabVIEW- oder Matlab-Anwendungen

UnderAutomation
KontaktLegal

© All rights reserved.