The RMP Motion Controller APIs
PathMotion.cs
1
42using RSI.RapidCode.dotNET; // Import our RapidCode Library.
43using NUnit.Framework;
44using System;
45using System.Linq;
46using System.Threading;
47
48#if DOXYGEN // RSI internal documentation use only
49using RSI.RapidCode;
51#endif
52
53
54[TestFixture]
55[Category("Software")]
56public class PathMotion : SampleAppTestBase
57{
58 [SetUp]
59 public void Setup()
60 {
61 jointsMultiAxis?.AxisRemoveAll();
62 }
63
64 [TearDown]
65 public void Teardown()
66 {
67 robot?.EStop();
68 robot?.MotionDoneWait();
69 robot?.ClearFaults();
70 Robot.RobotDelete(controller, robot);
71 robot = null;
72
73 jointsMultiAxis?.Abort();
74 Thread.Sleep(50);
75 jointsMultiAxis?.ClearFaults();
76 }
77
78 private void VerifyModel(KinematicModel model, LinearUnits expectedUnits, string expectedName)
79 {
80 var actualUnits = model.UnitsGet();
81 Assert.That(actualUnits, Is.EqualTo(expectedUnits), $"Expected model units to be '{expectedUnits}' but was '{actualUnits}' instead!");
82 var actualName = model.NameGet();
83 Assert.That(actualName, Is.EqualTo(expectedName), $"Expected model name to be '{expectedName}' but was '{actualName}' instead!");
84 }
85
86 [Test]
87 public void GantryPrimeAxis()
88 {
89 prime_axis = z_axis;
91 // We assume the axes have been confgured and homed properly prior this this program.
92
93 const string xLabel = "X-Axis";
94 const string yLabel = "Y-Axis";
95 const string primeLabel = "Y-Prime";
96
97 // Set the expected labels for each axis.
98 x_axis.UserLabelSet(xLabel);
99 y_axis.UserLabelSet(yLabel);
100 prime_axis.UserLabelSet(primeLabel);
101
102 // The joint index of each axis is the index within the MultiAxis object.
103 // "X-Axis" has joint index 0
104 // "Y-Axis" has joint index 1
105 // "Y-Prime" has joint index 2
106 Axis[] axes = new Axis[] { x_axis, y_axis, prime_axis };
107 jointsMultiAxis.AxesAdd(axes, axes.Length);
108
109 const LinearUnits units = LinearUnits.Millimeters;
110 const string modelName = "RSI_XY_Yp";
111 const double scaling = 1.0, offset = 0.0;
112 LinearModelBuilder builder = new LinearModelBuilder(modelName);
113 builder.UnitsSet(units);
114 builder.JointAdd(new LinearJointMapping(0, CartesianAxis.X) { ExpectedLabel = xLabel, Scaling = scaling, Offset = offset });
115 builder.JointAdd(new LinearJointMapping(1, CartesianAxis.Y) { ExpectedLabel = yLabel, Scaling = scaling, Offset = offset });
116 builder.JointAdd(new LinearJointMapping(2, CartesianAxis.Y) { ExpectedLabel = primeLabel, Scaling = scaling, Offset = offset });
117
118 // Create a Robot object where the y and y prime will be geared 1:1
119 const int motionFrameBufferSize = 50; // This is the minimum valid motion frame buffer size.
120 robot = Robot.RobotCreate(controller, jointsMultiAxis, builder, motionFrameBufferSize);
123
124 VerifyModel(robot.ModelGet(), units, modelName);
125 }
126
127 [Test, Timeout(Constants.MAX_TEST_TIME)]
128 public void SimplePathMotion()
129 {
131 // We assume the axes have been confgured and homed properly prior this this program.
132 const string xLabel = "X-Axis";
133 const string yLabel = "Y-Axis";
134 const string zLabel = "Z-Axis";
135 const string aLabel = "A-Axis";
136 const string bLabel = "B-Axis";
137 const string cLabel = "C-Axis";
138
139 // Set the expected labels for each axis.
140 x_axis.UserLabelSet(xLabel);
141 y_axis.UserLabelSet(yLabel);
142 z_axis.UserLabelSet(zLabel);
143 a_axis.UserLabelSet(aLabel);
144 b_axis.UserLabelSet(bLabel);
145 c_axis.UserLabelSet(cLabel);
146
147 // The joint index of each axis is the index within the MultiAxis object.
148 // "X-Axis" has joint index 0
149 // "Y-Axis" has joint index 1
150 // "Z-Axis" has joint index 2
151 // "A-Axis" has joint index 3
152 // "B-Axis" has joint index 4
153 // "C-Axis" has joint index 5
154 Axis[] axes = new Axis[] { x_axis, y_axis, z_axis, a_axis, b_axis, c_axis };
155 jointsMultiAxis.AxesAdd(axes, axes.Length);
156 jointsMultiAxis.ClearFaults();
157
158 const LinearUnits units = LinearUnits.Meters;
159 const string modelName = "RSI_XYZABC_Meters";
160 const double scaling = 1.0, offset = 0.0;
161 LinearModelBuilder builder = new LinearModelBuilder(modelName);
162 builder.UnitsSet(units);
163 builder.JointAdd(new LinearJointMapping(0, CartesianAxis.X) { ExpectedLabel = xLabel, Scaling = scaling, Offset = offset });
164 builder.JointAdd(new LinearJointMapping(1, CartesianAxis.Y) { ExpectedLabel = yLabel, Scaling = scaling, Offset = offset });
165 builder.JointAdd(new LinearJointMapping(2, CartesianAxis.Z) { ExpectedLabel = zLabel, Scaling = scaling, Offset = offset });
166 builder.JointAdd(new LinearJointMapping(3, CartesianAxis.Roll) { ExpectedLabel = aLabel, Scaling = scaling, Offset = offset });
167 builder.JointAdd(new LinearJointMapping(4, CartesianAxis.Pitch) { ExpectedLabel = bLabel, Scaling = scaling, Offset = offset });
168 builder.JointAdd(new LinearJointMapping(5, CartesianAxis.Yaw) { ExpectedLabel = cLabel, Scaling = scaling, Offset = offset });
169
170 // Create a Robot object with a multi axis containing all joints and the kinematic type
171 robot = Robot.RobotCreate(controller, jointsMultiAxis, builder, MotionController.AxisFrameBufferSizeDefault);
173
174 robot.PathAccelerationSet(1000); // UserUnits per sec sqd
175 robot.PathVelocitySet(50); // UserUnits per sec
176
178 robot.PathProgrammingModeSet(PathMode.Absolute);
179 robot.PathLine(new Pose(1, 1, 0));
180 robot.PathArc(new Pose(0, 2, 0), new Vector3d(0, 1, 0), RotationDirection.Clockwise);
181
182 jointsMultiAxis.ClearFaults();
183 jointsMultiAxis.AmpEnableSet(true);
184 robot.Run(); // Starts the motion. Calling with the false arguement for non blocking behavior
185 bool isRunning = robot.IsRunning();
187
188 VerifyModel(robot.ModelGet(), units, modelName);
189 }
190
191 [Test]
192 public void ChangingUnits()
193 {
195 // We assume the axes have been confgured and homed properly prior this this program.
196 const string xLabel = "X-Axis";
197 const string yLabel = "Y-Axis";
198 const string zLabel = "Z-Axis";
199 const string aLabel = "A-Axis";
200 const string bLabel = "B-Axis";
201 const string cLabel = "C-Axis";
202
203 // Set the expected labels for each axis.
204 x_axis.UserLabelSet(xLabel);
205 y_axis.UserLabelSet(yLabel);
206 z_axis.UserLabelSet(zLabel);
207 a_axis.UserLabelSet(aLabel);
208 b_axis.UserLabelSet(bLabel);
209 c_axis.UserLabelSet(cLabel);
210
211 // The joint index of each axis is the index within the MultiAxis object.
212 // "X-Axis" has joint index 0
213 // "Y-Axis" has joint index 1
214 // "Z-Axis" has joint index 2
215 // "A-Axis" has joint index 3
216 // "B-Axis" has joint index 4
217 // "C-Axis" has joint index 5
218 Axis[] axes = new Axis[] { x_axis, y_axis, z_axis, a_axis, b_axis, c_axis };
219 jointsMultiAxis.AxesAdd(axes, axes.Length);
220
221 const LinearUnits units = LinearUnits.Millimeters;
222 const string modelName = "RSI_XYZABC_Millimeters";
223 const double scaling = 1.0, offset = 0.0;
224 LinearModelBuilder builder = new LinearModelBuilder(modelName);
225 builder.UnitsSet(units);
226 builder.JointAdd(new LinearJointMapping(0, CartesianAxis.X) { ExpectedLabel = xLabel, Scaling = scaling, Offset = offset });
227 builder.JointAdd(new LinearJointMapping(1, CartesianAxis.Y) { ExpectedLabel = yLabel, Scaling = scaling, Offset = offset });
228 builder.JointAdd(new LinearJointMapping(2, CartesianAxis.Z) { ExpectedLabel = zLabel, Scaling = scaling, Offset = offset });
229 builder.JointAdd(new LinearJointMapping(3, CartesianAxis.Roll) { ExpectedLabel = aLabel, Scaling = scaling, Offset = offset });
230 builder.JointAdd(new LinearJointMapping(4, CartesianAxis.Pitch) { ExpectedLabel = bLabel, Scaling = scaling, Offset = offset });
231 builder.JointAdd(new LinearJointMapping(5, CartesianAxis.Yaw) { ExpectedLabel = cLabel, Scaling = scaling, Offset = offset });
232
233 // Create a Robot object with a multi axis containing all joints and the kinematic type
234 robot = Robot.RobotCreate(controller, jointsMultiAxis, builder, MotionController.AxisFrameBufferSizeDefault);
236
237 //NOTE: to use the above kinematic model you must have a gantry (linear 1:1 kinematics) and each linear axis must have its user units scaled to millimeters
238
239 robot.PathAccelerationSet(10); //Sets the PATH acceleration to 10 Millimeters per second sqd
240 robot.PathVelocitySet(10); //Sets the PATH velocity to 10 Millimeters per second
241
242 Console.WriteLine(robot.PathUnitsGet());//This will print the int value for the enum for Millimeters
243
244 robot.PathUnitsSet(LinearUnits.Centimeters);
245
246 robot.PathAccelerationSet(10); //Sets the PATH acceleration to 10 Centimeters per second sqd
247 robot.PathVelocitySet(10); //Sets the PATH velocity to 10 Centimeters per second
248
249 Console.WriteLine(robot.PathLinearScalingGet());//Will print the scale factor to convert CM to MM
250
251 //NOTE: you can also set this directly. Doing so will result in PathUnitsGet() returning NONE
253
254 VerifyModel(robot.ModelGet(), units, modelName);
255 }
256
257 public void PathPoint()
258 {
260 const ulong frameCount = 500;
261 ulong totalFrames = frameCount;
262 ulong startFrame = 0;
263
264 while (totalFrames == frameCount)
265 {
266 RapidVectorRobotPosition positions = robot.PathPlannedPositionsGet(startFrame, frameCount);
267 totalFrames = positions.Size();
268
269 foreach (RobotPosition position in positions.ToArray())
270 {
271 Pose pose = position.Pose;
272 Vector3d spatial = pose.Position;
273 double xCoord = spatial.X, yCoord = spatial.Y, zCoord = spatial.Z;
274 Quaternion orientation = pose.Orientation;
275 }
276
277 //Add code here to create the rendering out of the positions you have collected.
278 //Use your prefered 3d library.
279 //Example:
280 //vector3 = new Vector3D(xPosition, yPosition, zPosition);
281 //linePositions.Add(Vector3DToVector3(vector3));
282
283 startFrame += totalFrames;
284 }
286 }
287}
static void CheckErrors(RapidCodeObject rsiObject)
Check if the RapidCodeObject has any errors.
Helper Functions for checking logged creation errors, starting the network, etc.
void UserLabelSet(const char *const userLabel)
Set the axis User defined Label.
Represents a single axis of motion control. This class provides an interface for commanding motion,...
Definition rsi.h:5664
void UnitsSet(LinearUnits units)
Set the units the built model will use.
Describes the mathematical kinematic model of a robot.
The Builder for a linear kinematic model. Constructs a single Linear Kinematic Model to use when crea...
void JointAdd(const LinearJointMapping &joint)
adds a joint to the model using the configuration specified within the LinearJoint structure.
Vector3d Position
The position component of the Pose.
Quaternion Orientation
The orientation component of the Pose.
Quaternion for representing rotations.
uint64_t MotionDoneWait()=0
Waits for a move to complete.
RapidVector< RobotPosition > PathPlannedPositionsGet(uint64_t startFrame, uint64_t frameCount)=0
Get Positions (see RobotPosition) representing the planned motion in cartesian space that will happen...
void PathVelocitySet(double unitsPerSecond)=0
Sets the target linear cartesian velocity for each move (UserUnits/second).
bool IsRunning()=0
Returns whether or not the robot is in motion (from executor or other source). Can be used to determi...
double PathLinearScalingGet() const =0
Gets scaling between input to path motion and output of path motion to the kinematic model.
static Robot * RobotCreate(MotionController *controller, MultiAxis *multiAxis, KinematicModelBuilder *builder, uint32_t motionFrameBufferSize)
Create a Robot object to use G-Code, path motion, etc.
void PathAccelerationSet(double unitsPerSecondSquared)=0
Sets the target acceleration for the machine (UserUnits/second^2). Should be set appropriately based ...
LinearUnits PathUnitsGet() const =0
Gets the units of path motion.
void PathArc(const Pose &target, double radius, RotationDirection direction)=0
Appends an arc on to the current on the PathPlaneGet() plane XY by default.
void PathUnitsSet(LinearUnits units)=0
Defines the units Cartesian Path Motion is in.
void PathLine(const Pose &target)=0
void EStop()=0
Commands a joint EStop and clears the loaded moves.
void PathProgrammingModeSet(PathMode mode)=0
Sets the programming mode (Relative/Absolute).
void Run()=0
Run the loaded path lines/arcs. The behavior is non-blocking. Use Robot.MotionDoneWait() to block.
Represents a collection of joints in Cartesian space with forward and inverse kinematics....
void ClearFaults()=0
Clears the MultiAxis fault then the Robot's error bit.
const KinematicModel & ModelGet()=0
Get the model this robot was created with Visit our Topic Page for more information.
static void RobotDelete(MotionController *controller, Robot *robot)
Delete a Robot.
A representation of the robot containing the Pose and the positions of the free axes.
Vector3d is used for three-dimensional points and vectors.
static constexpr int32_t AxisFrameBufferSizeDefault
The default value of the AxisFrameBufferSize, also the minimum allowable value.
Definition rsi.h:814
Represents the RMP soft motion controller. This class provides an interface to general controller con...
Definition rsi.h:762
void AxisRemoveAll()
Remove all axes from a MultiAxis group.s.
void AxesAdd(Axis **axes, int32_t axisCount)
void ClearFaults()
Clear all faults for an Axis or MultiAxis.
void AmpEnableSet(bool enable)
Enable all amplifiers.
void Abort()
Abort an axis.
PathMode
Motion types. For G-code use and Cartesian path motion.
CartesianAxis
This enum specifies which Cartesian axis a LinearJointMapping maps a robot joint to.
RotationDirection
Rotational directions about an axis.
LinearUnits
Unit types. For G-code use.
The Cartesian namespace.