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();