Assuming you’ve verified the ssc32 service is working by using the web browser to set the servos directly the next thing you’ll probably want to do is drive the servos from another Robotics Studio service. This tutorial will cover briefly how to send servo position commands. It won’t touch on sequencing or any higher-level coordination.
Assuming you’ve created a new service using the dssnewservice command you’ll need to make the following changes to it to talk to the SSC-32. This example will show how to do that on the same processor using a partnership. There are methods to effectively do the same thing from a remote PC but that won’t be covered here.
Near the top of the service source file you’ll need to make the namespace of the SSC-32 proxy available:
using ssc32p = CoroWare.Robotics.Services.Lynxmotion.Ssc32.Proxy;
This will also require adding a reference in the project to SSC32.Y2007.M01.Proxy. This is a fake service Microsoft created during the build that allows you to talk to the real service. To do that you’ll need to go to the project browser, right-click on references and select “Add Reference”.
A few lines down in the file there is a ServicePort attribute and then the creation of the _mainPort. Immediately after these lines add a specification that makes your service a partnership with the ssc32 service and define a port that can be used to communicate to the partner:
[Partner("SSC32", Contract = ssc32p.Contract.Identifier, CreationPolicy = PartnerCreationPolicy.UseExistingOrCreate)]
ssc32p.SSC32Operations _ssc32Port = new ssc32p.SSC32Operations();
Now, whenever you wish to send a new servo value to the ssc-32 you do the following. Create a new command body:
ssc32p.SSC32ServoMove body = new ssc32p.SSC32ServoMove();
Indicate how long you wish the move to take (the T command to the SSC-32. -1 indicates the service should not provide the T command in the servo move command):
body.Time = -1;
Indicate which channels you wish to command. Up to 32 can be listed. In this example we’ll control channel 2 and 5:
body.Channels = new int] { 2, 5 };
Now specify the new pulse widths. These should align with the channels above. For this example I’m setting channel 2 to 800 and channel 5 to 1250:
body.PulseWidths = new int] { 800, 1250 };
Now specify the speeds (the S argument to the SSC-32 move command). -1 indicates not to send the S argument. These should also align with the channels specified above:
body.Speeds = new int] { -1, -1 };
Now create the actual command that will be posted to the other service:
ssc32p.SendSSC32Command cmd = new ssc32p.SendSSC32Command(body);
Then post the command to the ssc-32:
_ssc32Port.Post(cmd);
You’re not done yet as there is a response that comes back to indicate whether the command was accepted or not. There are various failure reasons such as being unable to communicate to the servo controller. When a command is created it automatically creates a temporary port that is used to answer back. We want to wait on that port for the answer which can either be success or failure:
yield return Arbiter.Choice<ssc32p.SSC32ResponseType, Fault>(cmd.ResponsePort,
delegate(ssc32p.SSC32ResponseType response) {
// successful update
},
delegate(Fault fault) {
// failure has occurred, fault describes it
LogInfo("Update failed");
}
);
The “yield return” is necessary to allow for asynchronous processing. This allows other things to continue until the Arbiter receives a response at which time one of the specified delegates will be triggered.
That’s all it takes. What triggers the messages is up to you; you can set up timers to do things repetitively or use input from some other service.