Controlling Franka & ROS¶
Starting ROS to control Franka¶
The recommended setup for controlling the franka can be seen in the tree below. The top level shows the devices required and their IP address, the second tier shows the commands needed to run the files:
.
├── Franka Control Box (192.168.0.88)
├── Host workstation computer (192.168.0.77)
│ ├── roscore
│ └── ./franka_controller_sub 192.168.0.88
└── Project workstation computer
├── roslaunch openni2_launch openni2.launch
├── camera_subscriber.py (this does not need to be run seperately)
└── main.py
Tip
To test the image feed out without using it in main.py
you can use the test_camera.py
file in the tests
folder.
Networking with other workstations¶
Instead of running the master node and subscriber nodes on your own workstation, these can be running on the main workstation in the lab instead. This means that libfranka won’t need to be installed on your specific workstation.
To communicate over the lab network you need to change two main ROS variables. Firstly you need to find the IP address of your computer when connected to the lab network (via ethernet). To do this you can use ifconfig
in a terminal window to give you your <ip_address_of_pc>
.
You then need to run the following two commands in your terminal window (substitute in you IP address):
export ROS_MASTER_URI=http://192.168.0.77:11311
export ROS_IP=<ip_address_of_pc>
As you will see, this is connecting you to the static IP address of the main Franka workstation, 192.168.0.77
. In order for you to continue with running a Python publisher, you need to ensure that roscore and the subscriber is running on the main workstation.
Note
That this configuration of assigning IP addresses to ROS_MASTER_URI and ROS_IP is non-permanent, and is only active for the terminal window you are working in. This has to be repeated for every window you use to run rospy. Alternatively you can add these commands to your bashrc.
Running the subscriber¶
Once roscore
is running, the subsciber has to run in the background to read the messages from our Python publisher and execute them with libfranka. To run the subscriber (from the project folder), run:
cd franka/
./franka_controller_sub 192.168.0.88
Sometimes there is an “error with no active exception” thrown by this executable. This can sometimes be solved by simply manually moving the arm using the buttons a bit. Then rerun the command above again.
Warning
This subscriber is compiled for libfranka 0.1.0
. You can check your current libfranka
version with rosversion libfranka
command.
Using the publisher¶
First, make sure you are running roscore
and the subscriber, franka_controller_sub
on the main lab workstation.
Example
Assuming you are writing a script (script.py
) that wants to use control franka, the files should be stored as:
.
├── README.md
├── franka
│ ├── __init__.py
│ ├── franka_control_ros.py
│ ├── franka_controller_sub
│ ├── franka_controller_sub.cpp
│ ├── print_joint_positions
│ └── print_joint_positions.cpp
└── script.py
To use the FrankaRos
class in your own Python script would look something like this:
from franka.franka_control_ros import FrankaRos
franka = FrankaRos(debug_flag=True)
# we set the flag true to get prints to the console about what FrankaRos is doing
while True:
data = arm.get_position()
print("End effector position:")
print("X: ", data[0])
print("Y: ", data[1])
print("Z: ", data[2])
-
class
franka.franka_control_ros.
FrankaRos
(log=False, ip='192.168.0.88', debug=False, init_ros_node=False)[source]¶ -
get_position
()[source]¶ Get x, y, z position of end-effector and returns it to caller.
Returns: list as [x, y, z]
-
grasp
(object_width, speed, force)[source]¶ Grasp an object in the grippers. Note that this can only be called if the object width is smaller than the current distance between the grippers.
The grippers attempt to move to the width of the object defined with speed defined, and then proceed to apply a defined force against the object. If no object is present it evaluates as failed and moves to next task.
0 width defined == 2.2 cm difference real-world
Parameters: - object_width – width of target object to grab (float)
- speed – with which to move the gripper to object width (float)
- force – to apply to the object once the grippers are at object width (float)
-
move_gripper
(width, speed)[source]¶ Set gripper width by assigning
width
with a desired speed to move at. Note this must be called before grasping if gripper fingers are too close togethergrasp()
call.0 width defined == 2.2 cm difference real-world
Parameters: - width – desired distance between prongs on end-effector (in millimetres)
- speed – desired speed with which to move the grippers
-
move_relative
(dx, dy, dz, speed)[source]¶ Moves robot end effector in desired direction (in robot reference frame) given a target displacement and speed to travel at. The robot will not necessarily travel at this speed due to safety controls in the subscriber.
Parameters: - dx – float value displacement in robot reference axis
- dy – float value displacement in robot reference axis
- dz – float value displacement in robot reference axis
- speed – float value desired speed to target displaced position
-
move_to
(x, y, z, speed)[source]¶ Moves robot end effector to desired coordinates (in robot reference frame) given a target velocity. The robot will not necessarily travel at this speed due to safety controls in the subscriber.
Parameters: - x – float value position in robot reference axis
- y – float value position in robot reference axis
- z – float value position in robot reference axis
- speed – float value desired speed to target position
-
Using Franka without ROS¶
Note
This method is deprecated. It is now recommended you use ROS to control the Arm using a Python publisher, such as the way described above.
Setting Permissions¶
To control the Franka Arm, Fabian and Petar have written a small collection of C++ files which can be compiled to run as executables and control the Franka Arm using libfranka.
You need to ensure you have set the correct permissions for libfranka. You can check that in Using the franka_ros library.
Downloading the C++ Executables and Python Class¶
Now that you have libfranka set up properly you can get use the C++ files provided. These resources can be found in the /franka
directory of the repository. Firstly, go to your project directory in the terminal by using cd <project_dir>
. If you have already downloaded the files before and are replacing them with an up-to-date version, run rm -rf franka/
first. To download the necessary folder, run:
svn export https://github.com/nebbles/DE3-ROB1-CHESS/trunk/franka
Once this directory is downloaded into your project directory, you need to change directory and then make the binaries executable:
cd franka/
chmod a+x franka*
chmod a-x *.cpp
Warning
This next command will move the FRANKA. Make sure you have someone in charge of the external activation device (push button).
These binaries can now be used from the command line to control the Arm:
./franka_move_to_relative <ip_address> <delta_X> <delta_Y> <delta_Z>
Alternatively, you can control the Arm using the easy custom Python class Caller
(see below).
Python-Franka API with franka_control.py
¶
The Python-FRANKA module (franka_control.py
) is designed to allow easy access to the C++ controller programs provided by Petar. The provided Python module is structured as follows.
Example
To use the FrankaControl
class in your own Python script would look something like this:
from franka.franka_control import FrankaControl
arm = FrankaControl(debug_flag=True)
# we set the flag true to get prints to the console about what Caller is doing
arm.move_relative(dx=0.1, dy=0.0, dz=-0.3)
# we tell teh arm to move down by 30cm and along x away from base by 10cm
Note
This example code assumes you are following the general project structure guide. See below for more information. The code above would be called from a main script such as run.py
.
General Structure of Project¶
The structure of the project is important to ensure that importing between modules works properly and also seperates externally maintained code from your own. An example of a project tree is:
.
├── LICENSE.txt
├── README.md
├── run.py
├── __init__.py
├── docs
│ ├── Makefile
│ ├── build
│ ├── make.bat
│ └── source
├── franka
│ ├── __init__.py
│ ├── franka_control.py
│ ├── franka_get_current_position
│ ├── franka_get_current_position.cpp
│ ├── franka_move_to_absolute
│ ├── franka_move_to_absolute.cpp
│ ├── franka_move_to_relative
│ └── franka_move_to_relative.cpp
├── my_modules
│ ├── module1.py
│ ├── module2.py
│ ├── module3.py
│ ├── __init__.py
└── test_script.py
Additional Resources¶
https://frankaemika.github.io/docs/getting_started.html#operating-the-robot