RobotStudio event

IpcQueue.Receive timeout

I am having difficulty using the Messaging functionality of the PC SDK.  In particular, I can send messages to the controller, but am unable to receive messages sent from the controller to my PC application.

I am trying to implement the basic demo application from the RAB Application Manual.  The myQueue.Receive(...) call seems to always return immediately with a Timeout response.  It definitely isn't waiting the specified 5 seconds I have indicated as the desired timeout value.

Please review the attached example code that demonstrates this behavior.  Regardless of how I send the messages, I always get a "timeout" response immediately after pressing the "Send Message" button.

webwiz/2811/RAB_Messaging_timeout.zip

If it helps, my configuration is:
  RAB (PC SDK) 5.11
  RobotStudio   5.10.2400.147
    running a simulated robot based on RobotWare 5.11.0160

Thanks for any help you can give!
  - Jeremy Zoss
  Southwest Research Institute



Comments

  • We are having exactly the same problem. The only exception is when the robot controller is restarted (warm start) and the application creates a new RAB_Q queue. When we restart the application the queue already exists and only "c.Ipc.GetQueue("RAB_Q");" is called, and this is when we do not receive the correct message (gives the "Timeout" response instantly).

    Regards,
    Bergur and Kalle

  • We have tested your code, jzoss. It is Ok. But PC SDK messaging does not seem to work as it should when the thread is running as STA. Changing it to MTA will help. We will document this limitation in the Release Notes for 5.12.
     
    Best regards,

    Ingela Brorsson
    Software Engineer
    ABB Robotics, Sweden
  • Ingela,

    Thanks for your response.  I tried to implement your suggested fix several ways, in both C# and C++, but was unable to successfully receive any kind of message response back from the robot using IpcQueue.Receive.

    In reading about the MTAThread attribute, I saw several places that indicated that this might conflict with a Windows Forms application.  If this is a limitation of the PC SDK Messaging functionality, this would be unfortunate, as we are trying to do messaging through a GUI application.  Having to create a separate thread just for the robot communication would be extra effort.  As a test, I created an MTAThread console application, but this was also unable to receive communications back from the robot using IpcQueue.Receive.

    At this point, I am mostly unable to get IpcQueue.Receive to work as it's supposed to.  Can you please post source code for an example of a working bi-directional messaging test?  It would be helpful to determine if my problem is with my code, the SDK libraries, or some other configuration.

    Thanks for your help!
      Jeremy Zoss
      Manufacturing Systems Department
      Southwest Research Institute


  • Hi Jeremy,
     

    ( These comments are based in the cost that you upload in your first post)

     

    Create a thread for receiving IPC message.  The following code could serve as guidance ..

     

    1 - Create a thread ..

     


    // serverThread could be a static field<?: prefix = o ns = "urn:schemas-microsoft-com:office:office" />
    _serverThread = new Thread(new ThreadStart(ServerStart));
    _serverThread.Name = "MY_IPC_LISTENER";
    _serverThread.Start();

    2 - In the new thread, receive continuously, and only react when a message has been received:

     

    private static void ServerStart()
    {
    IpcMessage message;
    IpcReturnType ret;
    UTF8Encoding bdata = new UTF8Encoding();
    int timeOut = 50;
    try
    {
    // _ipcLocal must referred to your IPC queue created in the PC,
    // RAPID instructipns will sent IPC messages to this queue.
    while (_ipcLocal != null)
    {
    message = new IpcMessage(Ipc.MaxMessageSize);
    ret = _ipcLocal.Receive(timeOut, message);
     
    if (ret == IpcReturnType.OK)
    {                       
    //convert msg data to string                   
    string data = bdata.GetString(message.Data, 0, message.Size);
    // Here you can react to a received message                    
    }
    }
    }
    catch (ThreadAbortException)
    {}
    catch (Exception e)
    {
       MessageBox.Show(e.ToString());
    }
    }
     

    Hope this helps !!!

    BR/Carlos
    Carlos Martinez
    ABB
  • Carlos,

    Thanks for your help.  I modified my code to handle the IpcQueue.Receive in a separately-spawned thread, as indicated in your example.  This allowed me to pick up a valid response back from the robot controller in *some* cases.

    I am still having the same difficulties reported earlier in this thread by Bergur.  Specifically, a newly-created queue will work correctly, but an existing queue (connected using GetQueue) will *always* generate a timeout immediately after calling IpcQueue.Receive.  The only way to get my test application to run is to reboot the robot controller every time before I run my application.  Needless to say, this is not a very workable solution.

    I had tried to delete the queue if it exists, and then recreate as necessary.  But the DeleteQueue call throws an exception.

    I would appreciate if you could look into this issue further, as I don't really consider it resolved.  I don't think that running the IpcQueue.Receive call in an MTA thread fixes all the issues here.

    Thanks again for your help,
      - Jeremy


  • Hi Jeremy, <?: prefix = o ns = "urn:schemas-microsoft-com:office:office" />

     

    I have seen these cases: queue's not responding or can?_Tt be deleted. One of the possible causes is that the creator of the queue is the only one who has the right to delete this queue (I do not know if this also applies for receiving messages for this queue also, which it might get sense). By creator I mean the same Controller instance.

     

    If the creator does not delete a queue, the way to "reset" a queue is to either reboot the controller or wait for some minutes until the controller finds out that this thread is not used anymore.

     

    To avoid these situations, you must ensure that the creator of the queue deletes it. For example, it?_Ts often that while debugging your application, you hit the stop button inside VS in order to make a change and re-run your application. By doing this, you are not deleting the queue.

     

    Can you verify that you don?_Tt have this case?

     

    Keep us posted :)

    Carlos Martinez
    ABB
  • Carlos,

    Thanks again.  Your suggestion is indeed correct.  If I make sure and delete the queue before my thread exits, the DeleteQueue call does succeed.  This allows me to re-create the queue the next time my application runs, and the messaging appears to work correctly.

    So, for now, I think this is a workable solution.  It seems like the messaging functionality needs some refinement, though.  The behaviors we've observed in this thread feel like they could (should?) be handled more gracefully in the SDK:
      1) IpcQueue.Receive will timeout immediately if not run in a separate MTA thread from the main application (?)
      2) Closing an application without properly deleting the queue causes an undefined state:
              2a) GetQueue() returns the proper queue reference, but can only be used to SEND data, not RECEIVE any data (same symptoms as #1)
              2b) DeleteQueue() causes an exception if called from a different controller reference than the original queue creator.
      3) The only way to "recover" from the unknown queue state in #2 is to reboot the controller (or, apparently, wait for the controller to do some internal housekeeping cleanup)

    Thanks for your help!  I will move forward with the rest of my application development now.

      - Jeremy