RobotStudio event

API - get current Instruction

Options
Hi there,

I am trying to implement a "remote Control" Interface (based on UDP network messages) for RobotStudio. I am using C# for this.

At the moment I am stuck. All I want is the following:
I created some simple instructions using the virtual flexpendant (like movej, movel, etc.).
Now I am running this code and during this execution I want to send the current executed command to my remote Control.

Also, can I somehow access the program counter (for getting the current line number in code which is executed).

And, last but not least: Can I send "pre-written" programs to RobotStudio with my remote Control?


Comments


  • Hi,

    The RobotStudio API doesn't contain functionality for communicating directly with the controller/VC. For that purpose you should use the PC SDK which is part of the Robot Application Builder product. With it you can upload programs, retrieve the program pointer and much more.


    Johannes Weiman2007-11-26 13:36:16
    Johannes Weiman
    Software Engineer
    ABB Robotics
  • Hi!

    I guess I need a function very similar to this.
    I have built a scene with the API and then I simulate a path.
    When there is a collision between the robot and the objects in the scene I need to know between which points of the path the collision took place.
    Therefore I want to write a new CollisionEventHandler.
    Is there a function which tells me which moveInstruction is currently active?





  • Hi again!

    Isn't there any possibility to get the current Instruction or at least the current position of the TCP during simulation?

    best regards, Matthias

  • apox
    Options


    Hi,

    you have to register an EventHandler for a mechanism. Here is a litle snippet:

                 //Register Event Handler for each mechanism
                 Station station = Project.ActiveProject as Station;

                 foreach (RsIrc5Controller _ctrl in station.Irc5Controllers)
                 {
                     foreach (RsTask _task in _ctrl.Tasks)
                     {
                         _task.Mechanism.JointValuesChanged += new EventHandler(MyJointListener);
                     }
                 }

    Every time a joint value changes (->JointValuesChanged), the method "MyJointListener" is called:

            private void MyJointListener(object sender, EventArgs e)
            {
                 Station station = Project.ActiveProject as Station;
                 if (station == null) return;

                 double[] deg = new double[6];
                 double[] conf = new double[6];

                 foreach (RsIrc5Controller _ctrl in station.Irc5Controllers)
                 {
                     int currentRobot = 0;
                     foreach (RsTask _task in _ctrl.Tasks)
                     {
                         Mechanism mechanism = _task.Mechanism;

                         double[] actualJointValues = mechanism.GetJointValues();
                         deg[0] = RADtoDEG(actualJointValues[0]);
                         deg[1] = RADtoDEG(actualJointValues[1]);
                         deg[2] = RADtoDEG(actualJointValues[2]);
                         deg[3] = RADtoDEG(actualJointValues[3]);
                         deg[4] = RADtoDEG(actualJointValues[4]);
                         deg[5] = RADtoDEG(actualJointValues[5]);

                         // get current Configurations
                         ConfigurationData confData = mechanism.GetConfiguration();

                         // get current TCP coords
                         RsToolData tool = _task.ActiveTool;
                         if (tool != null)
                         {
                               // Get the TCP position
                               Vector4 trans = tool.Frame.GlobalMatrix.t;
                               trans.x *= 1000.0;
                               trans.y *= 1000.0;
                               trans.z *= 1000.0;

                               String xStr = trans.x.ToString();
                               String yStr = trans.y.ToString();
                               String zStr = trans.z.ToString();

                         }//if tool
                     }// task
                 }// controller
            }

    with

            public double RADtoDEG(double d)
            {
                 return d * 180.0 / Math.PI;
            }


    Hope it helps.

    apox2007-11-29 9:29:26
  • Thank you! Your code snippet was really helpful.

    Best regards, Matthias

  • MaWi81
    Options

    [QUOTE=Johannes Weiman]The RobotStudio API doesn't contain functionality for communicating directly with the controller/VC. For that purpose you should use the PC SDK which is part of the Robot Application Builder product. With it you can upload programs, retrieve the program pointer and much more.

    [/QUOTE]
    Is it possible to combine both? Use PC SDK and connect to the RS-API?

    On the one hand I need the collisionReport-Feature of RS and on the other hand possibilities to retrieve the program pointer and to change a path if it causes collisions.
  • Niklas Skoglund
    Options

    It is possible to combine PC-SDK and RobotStudio API.

    Under Robot Application Builder you will find more information about PC-SDK and a download link.

    From your RobotStudio Add-In project, add references to the assemblies needed from the PC-SDK.


    Best Regards, Niklas Skoglund
    ABB Robotics

    Developer Center
    RobotStudio Blog
  • MaWi81
    Options
    Okay, that works generally, but one additional question: is it possible to directly include RobotStudio's Controllers in PC-SDK-classes? Explicit or implicit casting is not possible:
    [code]ABB.Robotics.Controllers.Controller controller = (ABB.Robotics.Controllers.Controller) station.Irc5Controllers[0];[/code]

    Background is still to either use RS for collision-detection and simultaneously to get the program pointer (or anything else) for automatically getting (and changing) the instructions that cause collisions. At the moment I try to use the NetworkScanner inside the AddIn but that seems to be a little bit long winded.

  • Niklas Skoglund
    Options

    Try this. (namespaces omitted)

    [code]RsIrc5Controller stationCtrl = ....

    Controller pcSdkCtrl = new Controller(stationCtrl.SystemId)[/code]

    Those two classes has nothing in common when it comes to inheritance, but they both represents a controller, in different ways.

    Some background if you want...

    The ABB.Robotics.RobotStudio.Stations.RsIrc5Controller represents the model of the controller in the Station Object Model. An important role for this object is to keep the task collection which in turns keeps information about targets, workobjects, tools etc.

    Lets take the RsRobtarget as an example. Its counterpart in RAPID is the robtarget datatype. But there is not a 1:1 relation between a RsRobtarget and a robtarget data declaration in RAPID. If you change the name of an RsRobtarget in a RobotStudio station, nothing will happen in the controller, because you are just modifying the station model.

    The ABB.Robotics.Controllers.Controller provides an API to a real or virtual controller. This class can be used to load/save RAPID modules, take mastership etc. If you make a modification to a RAPID data declaration using the Controller class, the real data in RAPID will be modified.

     

     


    Best Regards, Niklas Skoglund
    ABB Robotics

    Developer Center
    RobotStudio Blog
  • MaWi81
    Options
    Hm, this code-fragment did not work. image

    But the SystemId-hint is also usable with my former workaround:
    [code]
    RsIrc5Controller stationCtrl = ....

    ControllerInfo controllerInfo = null;
    if ((new NetworkScanner()).TryFind(new Guid(stationCtrl.SystemId), out controllerInfo))
        pcSdkController = ControllerFactory.CreateFrom(controllerInfo);
    [/code]

    Thank you for your extensive explanations!