Matrix Vision RC_Visard 3D Kamera

Die BVS 3D-RV0 ist eine smarte 3D-Kamera f�r Roboterapplikationen. Mit integriertem Prozessor und applikationsspezifischen Software-Modulen auf der Kamera bietet der rc_visard eine autarke 3D-Bildverarbeitung.

Ab horstFX Version 07.2021 (g�ltig f�r fr�here Versionen ohne Verwendung des Normalenvektors: Funktion "getSurfaceNormalByQuaternion(Q0, Q1, Q2, Q3); )

1. Einleitung

Verarbeitete 3D-Informationen wie Pick Points werden vom rc_visard direkt an die Roboter-Anwendung weitergeben.

Mit integriertem Prozessor und applikationsspezifischen Software-Modulen auf der Kamera bietet der rc_visard eine autarke 3D-Bildverarbeitung und kann somit als 3D-Stereosensor einfach verwendet werden. Verarbeitete 3D-Informationen wie Pick Points werden vom rc_visard direkt an die Roboter-Anwendung weitergeben.

Durch die kameraseitige Erkennung der Box sowie die M�glichkeit den Greifer in der Kamerasoftware zu definieren, kann eine Kollisionskontrolle zwischen Roboter/Greifer und der Box stattfinden.

Kommuniziert wird zwischen Roboter und Kamera �ber die REST API.

Die Einrichtung der Kamera ist sehr gut in den Dokumenten von Matrix Vision beschrieben. Daher wird in diesem Artikel haupts�chlich auf die roboterseitige Kommunikation zwischen Kamera und Roboter eingegangen.

2. Einrichtung

Als Stromversorgung ben�tigt die Kamera  24 V, min. 24 W und kann daher direkt �ber die Klemmen im Schaltschrank des Roboters gespeist werden.

Es ist darauf zu achten, dass sich die IP-Adressen der Teilnehmer in dem gleichen Subbereich befinden. Wie die IP des Roboters eingestellt werden kann, ist unter folgendem Artikel beschrieben IP-Adresse �ndern.

Per Browser kann auf die Weboberfl�che der Kamera zugegriffen werden. Entweder �ber die IP-Adresse der Kamera, oder �ber deren Hostname. Der Hostname der Kamera setzt sich aus "rc-visard-" und anschlie�end der Seriennummer der Kamera zusammen. 

Wie in den Dokumenten von Matrix-Vision beschrieben, kann die Kamera nun eingerichtet und per Hand-Auge-Kalibrierung an das Koordinatensystem des Roboters angeglichen werden.

Die Orientierung der Bauteile gibt die Kamera in Quaternionen aus. Qw, Qx, Qy, Qz der Kamera entsprechen dabei Q0, Q1, Q2, Q3 des Roboters.

3. Kommunikation

Die Grundlage der Kommunikation beschreibt die REST API.

Roboterseitig befinden sich die notwendigen Funktionen in der Java Klasse HttpURLconnection.

Nachfolgend wird die Kommunikation anhand des Kameramoduls Boxpick beschrieben. Dieses Beispiel ist sehr einfach auf die anderen Kameramodule �bertragbar.

3.1. Starten des Moduls:

Anlegen einer Variablen welche die URL zum Starten des Boxpick Moduls beinhaltet. 

var start_boxpick = "http://192.168.0.112/api/v1/nodes/rc_boxpick/services/start";

Mittels nachfolgender Funktion wird das Boxpick Modul in den Zustand "run" versetzt.

function startModule()
{
     // Lege URL an
     var url = new java.net.URL(start_boxpick);

     // Oeffne Connection
     connection = url.openConnection();     
     connection.setRequestMethod("PUT");
     connection.setDoOutput(true);

     // Sende leere Nachricht um Modul zu starten
     var out = new java.io.OutputStreamWriter(connection.getOutputStream());
     out.write("");
     out.close();
     connection.getInputStream();

     // Schliesse Connection
     connection.disconnect();
}

3.2. Senden des Trigger-Befehls:

Anlegen einer Variablen welche die URL zum Triggern der Kamera beinhaltet. 

var trigger_boxpick = "http://192.168.0.112/api/v1/nodes/rc_boxpick/services/compute_grasps"

�ber folgende Funktion wird die Verbindung zum Triggern der Kamera aufgebaut.

function triggerCam()
{
     var url = new java.net.URL(trigger_boxpick);

     connection = url.openConnection();
     connection.setDoOutput(true);
     connection.setRequestMethod("PUT");
     
     // Setze request property auf JSON Typ
     connection.setRequestProperty("Content-Type", "application/json; utf-8");

     connection.setConnectTimeout(5000);     // Timeout 5 sek.
     connection.setReadTimeout(5000);

}

Mittels folgender Funktion wird die Nachricht zum Triggern an die Kamera gesendet. Die Nachricht liegt hierbei im JSON Format vor. Die Bedeutung der einzelnen Parameter sind in den Dokumenten von Matrix-Vision beschrieben.

function messageToCam()
{
     var message = {
                 "args": {
                        "pose_frame": "external",
                        "collision_detection": {
                               "gripper_id": "Messspitze_3Module",
                               "pre_grasp_offset": {
                                 "x": 0,
                                 "y": 0,
                                 "z": 0
                                    }
                             },
                             "load_carrier_id": "KLT40x30",
                             "suction_surface_width": 0.02,
                             "suction_surface_length": 0.02,
                             "robot_pose": {},
                             "item_models": [
                          {
                       "rectangle": {
                              "min_dimensions": {
                                     "x": 0.05,
                                     "y": 0.05
                                   },
                              "max_dimensions": {
                                     "x": 0.07,
                                     "y": 0.07
                                   }
                            },
                            "type": "RECTANGLE"
                          }
                        ]
                 }
          }

     // Erzeuge JSON String
     message = JSON.stringify(message);
     
     // Schreibe Trigger Message ueber Streamwriter
      var out = new java.io.OutputStreamWriter(connection.getOutputStream());
     out.write(message);
     out.close();
     connection.getInputStream();     
}

3.3. Erhalten der Kameranachricht

Mittels folgender Funktion wird die Nachricht der Kamera eingelesen.

function getCameraMessage()
{
     var BufferedReader = 
          new java.io.BufferedReader(
               new java.io.InputStreamReader(
                                    connection.getInputStream()));

     var inputLine;
     var response = new java.lang.StringBuffer();
     while ((inputLine = BufferedReader.readLine()) != null) { 
          LOG.info(inputLine);
          CamString = response.append(inputLine);
     }
     BufferedReader.close();
}

3.4. Auslesen der Objektparameter

Mittels folgender Funktion werden aus der Kameranachricht die erforderlichen Objektparameter erhalten und der Normalenvektor zum Anfahren des St�tzpunktes ermittelt.

function getObjectCoordinates()
{
     // parse zu JSON Objekt
     CamResponse = JSON.parse(CamString);

     CamReturnCode = (CamResponse.response.return_code.value);
     
     if (CamReturnCode == "0")
     {

          CamX = parseFloat(CamResponse.response.grasps[0].pose.position.x);
          CamY = parseFloat(CamResponse.response.grasps[0].pose.position.y);
          CamZ = parseFloat(CamResponse.response.grasps[0].pose.position.z);
          CamQ0 = parseFloat(CamResponse.response.grasps[0].pose.orientation.w);
          CamQ1 = parseFloat(CamResponse.response.grasps[0].pose.orientation.x);
          CamQ2 = parseFloat(CamResponse.response.grasps[0].pose.orientation.y);
          CamQ3 = parseFloat(CamResponse.response.grasps[0].pose.orientation.z);
     
          /*
          show_info("CamX: " + CamX + "\nCamY: " + CamY + "\nCamZ: " + CamZ + 
                 "\nCamQ0: " + CamQ0 + "\nCamQ1: " + CamQ1 + "\nCamQ2: " + CamQ2 +
                 "\nCamQ3: " + CamQ3);
          */

     // Erstellen des Normalenvektors
     normal = getSurfaceNormalByQuaternion(CamQ0,  CamQ1,  CamQ2,  CamQ3);

     } else
     {     
          show_info(CamReturnCode);
     }
}

4.  Anfahren der Objektposition

Mittels folgender Funktion, kann die von der Kamera detektierte Objektposition angefahren werden. Eine Kollisionskontrolle zwischen Roboter/Greifer und Box kann stattfinden.

function moveToObject()
{
     // Stuetzpunkt ueber Box
     move({
          'Coord': 'JOINT', 
          'MoveType': 'JOINT', 
          'PoseRelation': 'ABSOLUTE', 
          'anyconfiguration': false, 
          'blendradius.orient': 180.0, 
          'blendradius.xyz': 0.08, 
          'speed.ratio': 1.0, 
          'target': {'joints': [-0.339172, 48.548237, -7.816559, 0.010483, 49.267242, -14.856720]}, 
          'tool': 'Messspitze_3Module'
      }, "Wegpunkt 1");

     // Relativer Steutzpunkt ueber Objekt
     move({
          "speed.ratio": 1.0,
          "movetype" : "JOINT",
          "poserelation" : "ABSOLUTE",
          "target" : {"xyz+quat" : [CamX - (moveFactor*normal.x), CamY - (moveFactor*normal.y), CamZ - (moveFactor*normal.z), CamQ0, CamQ1, CamQ2, CamQ3]},
          "blendradius.xyz" : 0.05,
          "blendradius.orient" : 180
     })

     // Objektposition
     move({
          "speed.ratio": 1.0,
          "movetype" : "LINEAR",
          "poserelation" : "ABSOLUTE",
          "target" : {"xyz+quat" : [CamX, CamY, CamZ, CamQ0, CamQ1, CamQ2, CamQ3]},
          "blendradius.xyz" : 0.0,
          "blendradius.orient" : 180
     })

     sleep(2000);

     // Objekt greifen
     output_literal( "TOOL_OUTPUT_1", 1.0 );
 
     // relativer Abfahrpunkt
     move({
         'Coord': 'CARTESIAN_TCP', 
          'MoveType': 'LINEAR', 
         'PoseRelation': 'RELATIVE', 
         'anyconfiguration': false, 
          'blendradius.orient': 180.0, 
          'blendradius.xyz': 0.05, 
          'speed.ratio': 1.0, 
          'target': {'xyz+quat': [0.000000, 0.000000, -0.100000, 1.000000, 0.000000, 0.000000, 0.000000]}, 
          'tool': 'Messspitze_3Module'
      }, "Rel. Wegpunkt 1");
}

5.  Gesamter Programmablauf

Folgender Code beschreibt einen kurzen grundlegenden Programmablauf durch den Aufruf obiger Funktionen. Der gesamte Code f�r horstFX ist im Anhang beigef�gt.

try {

     while (true)
     {
          
          // Bildaufnahmeposition
          move({
                     'Coord': 'JOINT', 
                     'MoveType': 'JOINT', 
                     'PoseRelation': 'ABSOLUTE', 
                     'anyconfiguration': false, 
                     'speed.ratio': 1.0, 
                     'target': {'joints': [26.043015, 34.412682, 8.933212, 0.010483, 46.667053, -10.683838]}, 
                     'tool': 'Messspitze_3Module'
            }, "Bildaufnahme");
     
          // Starte Kameramodul
          startModule();

          // trigger Kamera
          triggerCam();
     
          // Uebergabe Request Parameter
          messageToCam();

          // erhalte Kameranachricht
          getCameraMessage();     
     
          // schliesse Kameraverbindung
          connection.disconnect();

          // erhalte Objektkoordinaten
          getObjectCoordinates();
     
          // fahre Objektposition an
          moveToObject();

          // fahre Ablageposition an
          place();
     }     

} catch (e) {
     show_info(e);
} finally {
     connection.disconnect();

6. Download

Matrix Vision Box Pick