visose / Robots

Create and simulate ABB, KUKA, UR, and Staubli robot programs.
MIT License
305 stars 127 forks source link

[Bug] URRealTimeDataExchange not working, results in all zeros #273

Closed odbee closed 7 months ago

odbee commented 8 months ago

Is there an existing issue for this?

What Robots version are you using?

1.6.7

What Rhino version are you using?

Rhino 7 for Windows

Current Behavior

Hey, i'm looking to get real time info from the UR robot and instead of using URRealTime I would like to use URRealTimeDataExchange because I need some extra variables not available in URRealTime , now the problem is, it seems like the values arent updated or I am missing some function I have to run inbetween to Update the data? when i use it, all the values I receive are zeros

Screenshot 2024-03-06 160015

A minimal working example would really help.

Expected Behavior

expecting the URRealTimeDataExchange to give me proper data

Steps To Reproduce



using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using Grasshopper.Kernel.Special;
using Robots;

/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
  /// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  /// <param name="text">String to print.</param>
  private void Print(string text) { __out.Add(text); }
  /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  /// <param name="format">String format.</param>
  /// <param name="args">Formatting parameters.</param>
  private void Print(string format, params object[] args) { __out.Add(string.Format(format, args)); }
  /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj) { __out.Add(GH_ScriptComponentUtilities.ReflectType_CS(obj)); }
  /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj, string method_name) { __out.Add(GH_ScriptComponentUtilities.ReflectType_CS(obj, method_name)); }
#endregion

#region Members
  /// <summary>Gets the current Rhino document.</summary>
  private RhinoDoc RhinoDocument;
  /// <summary>Gets the Grasshopper document that owns this script.</summary>
  private GH_Document GrasshopperDocument;
  /// <summary>Gets the Grasshopper script component that owns this script.</summary>
  private IGH_Component Component; 
  /// <summary>
  /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
  /// Any subsequent call within the same solution will increment the Iteration count.
  /// </summary>
  private int Iteration;
#endregion

  /// <summary>
  /// This procedure contains the user code. Input parameters are provided as regular arguments, 
  /// Output parameters as ref arguments. You don't have to assign output parameters, 
  /// they will have a default value.
  /// </summary>
  private void RunScript(bool getData, string IP, List<string> variables, ref object DataNames, ref object DataDescription, ref object RobotData)
  {

    if(DataAsTree == null)
    {
      DataAsTree = new DataTree<double>();
    }
    if(FeedbackNames == null )
    {
      FeedbackNames = new List<string>();
    }

    if (getData == true)
    {
      DataAsTree.ClearData();
      List<double> datapack = new List<double>();
      var URConnection = new  URRealTimeDataExchange(IP, variables);
      URConnection.ReadOutputs();
      for (var i = 0; i < URConnection.Outputs.Length; i++)
      {
        if (FeedbackNames.Count > i)
        {
          FeedbackNames[i] = URConnection.Outputs[i].Name;
        }
        else
        {
          FeedbackNames.Add(URConnection.Outputs[i].Name);
        }
        datapack = new List<double>();
        foreach (var value in URConnection.Outputs[i].Values)
        {
          datapack.Add(value);
        }
        GH_Path path = new GH_Path(i);
        DataAsTree.AddRange(datapack, path);
      }
    }

    RobotData = DataAsTree;
    DataNames = FeedbackNames;

  }

  // <Custom additional code> 
    DataTree<double> DataAsTree;
  List<string> FeedbackNames;

  // </Custom additional code> 
}

### Anything else?

_No response_
visose commented 8 months ago

Hi @odbee, can you test with the attached Grasshopper file? URRealtimeDataExchange.zip

odbee commented 7 months ago

Hey ! Thanks alot!! This works perfectly.