### Shell Commands for URSim Docker Setup Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This snippet provides shell commands for setting up and running a UR robot simulator using Docker. It includes cloning the repository, installing Docker, building a custom Docker image for the URSim, and running the container with necessary port mappings. ```shell git clone https://github.com/urrsk/ursim_docker.git sudo apt update sudo apt install docker.io sudo systemctl start docker sudo systemctl enable docker sudo systemctl status docker sudo usermod -aG docker $USER su - $USER docker build ursim/e-series -t myursim --build-arg VERSION=5.11.1.108318 --build-arg URSIM="https://s3-eu-west-1.amazonaws.com/ur-support-site/118926/URSim_Linux-5.11.1.108318.tar.gz" docker run --rm -it -p 5900:5900 -p 29999:29999 -p 30001-30004:30001-30004 myursim ``` -------------------------------- ### Install Dependencies for Real-time Kernel Compilation on Ubuntu Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Installs necessary packages for compiling a real-time kernel on Ubuntu systems. These tools are required for building the kernel from source. It's recommended to perform this in a dedicated temporary directory with sufficient space. ```shell sudo apt-get install build-essential bc curl ca-certificates gnupg2 libssl-dev lsb-release zstd libncurses-dev dwarves gawk flex bison ``` ```shell mkdir -p ${HOME}/rt_kernel_build cd ${HOME}/rt_kernel_build ``` -------------------------------- ### Python RTDE Control and Receive Interface for UR Robots Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This Python snippet demonstrates the equivalent functionality to the C++ example using the RTDEControl and RTDEReceive interfaces. It includes setting up the interfaces, defining robot motion parameters, and executing a circular path with servoL. The code also features platform-specific real-time priority adjustments for Linux and Windows and handles KeyboardInterrupt for stopping the robot. ```python from rtde_control import RTDEControlInterface as RTDEControl from rtde_receive import RTDEReceiveInterface as RTDEReceive import datetime import math import os import psutil import sys def getCircleTarget(pose, timestep, radius=0.075, freq=1.0): circ_target = pose[:] circ_target[0] = pose[0] + radius * math.cos((2 * math.pi * freq * timestep)) circ_target[1] = pose[1] + radius * math.sin((2 * math.pi * freq * timestep)) return circ_target # Parameters vel = 0.5 acc = 0.5 rtde_frequency = 500.0 dt = 1.0/rtde_frequency # 2ms flags = RTDEControl.FLAG_VERBOSE | RTDEControl.FLAG_UPLOAD_SCRIPT ur_cap_port = 50002 robot_ip = "localhost" lookahead_time = 0.1 gain = 600 # ur_rtde realtime priorities rt_receive_priority = 90 rt_control_priority = 85 rtde_r = RTDEReceive(robot_ip, rtde_frequency, [], True, False, rt_receive_priority) rtde_c = RTDEControl(robot_ip, rtde_frequency, flags, ur_cap_port, rt_control_priority) # Set application real-time priority os_used = sys.platform process = psutil.Process(os.getpid()) if os_used == "win32": # Windows (either 32-bit or 64-bit) process.nice(psutil.REALTIME_PRIORITY_CLASS) elif os_used == "linux": # linux rt_app_priority = 80 param = os.sched_param(rt_app_priority) try: os.sched_setscheduler(0, os.SCHED_FIFO, param) except OSError: print("Failed to set real-time process scheduler to %u, priority %u" % (os.SCHED_FIFO, rt_app_priority)) else: print("Process real-time priority set to: %u" % rt_app_priority) time_counter = 0.0 # Move to init position using moveL actual_tcp_pose = rtde_r.getActualTCPPose() init_pose = getCircleTarget(actual_tcp_pose, time_counter) rtde_c.moveL(init_pose, vel, acc) try: while True: t_start = rtde_c.initPeriod() servo_target = getCircleTarget(actual_tcp_pose, time_counter) rtde_c.servoL(servo_target, vel, acc, dt, lookahead_time, gain) rtde_c.waitPeriod(t_start) time_counter += dt except KeyboardInterrupt: print("Control Interrupted!") rtde_c.servoStop() rtde_c.stopScript() ``` -------------------------------- ### Install Build Dependencies (Bash) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/debian/how_to_setup.md Installs essential packages required for building Debian packages. This command uses apt-get to fetch and install the specified build tools and utilities. ```bash sudo apt-get install build-essential devscripts ubuntu-dev-tools debhelper dh-make patch cdbs quilt gnupg fakeroot lintian ``` -------------------------------- ### Install Kernel Packages Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Installs the compiled Linux headers and image packages using dpkg. The packages are installed in the parent directory and should not have '-dbg' in their names. ```shell sudo dpkg -i ../linux-headers-*.deb ../linux-image-*.deb ``` -------------------------------- ### Control Robotiq Gripper with Python Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Demonstrates how to initialize, connect, and operate a Robotiq gripper using the robotiq_gripper Python module. The script includes methods for moving the gripper to specific positions and logging its current state. ```python import robotiq_gripper import time ip = "127.0.0.1" def log_info(gripper): print(f"Pos: {str(gripper.get_current_position()): >3} " f"Open: {gripper.is_open(): <2} " f"Closed: {gripper.is_closed(): <2} ") print("Creating gripper...") gripper = robotiq_gripper.RobotiqGripper() print("Connecting to gripper...") gripper.connect(ip, 63352) print("Activating gripper...") gripper.activate() print("Testing gripper...") gripper.move_and_wait_for_pos(255, 255, 255) log_info(gripper) gripper.move_and_wait_for_pos(0, 255, 255) log_info(gripper) ``` -------------------------------- ### Git Build Package Installation (Bash) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/debian/how_to_setup.md Installs the git-buildpackage tool, which simplifies the process of building Debian packages from Git repositories. This command is a prerequisite for managing package versions and building. ```bash sudo apt-get install git-buildpackage ``` -------------------------------- ### Verify Downloaded Files with GPG Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Verifies the integrity of the downloaded kernel and patch files using GPG. This step is optional but recommended to ensure files are not corrupted or tampered with. It requires downloading the public keys of the signers first. ```shell gpg2 --verify linux-*.tar.sign gpg2 --verify patch-*.patch.sign ``` -------------------------------- ### DPUT Configuration File Example (INI) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/debian/how_to_setup.md Configuration for the dput tool, specifying how to upload packages to a Launchpad Personal Package Archive (PPA). It includes details like the PPA's fully qualified domain name (FQDN), upload method, incoming directory, and Launchpad user ID. ```ini [ur-rtde] fqdn = ppa.launchpad.net method = ftp incoming = ~sdurobotics/ur-rtde/ubuntu/ login = allow_unsigned_uploads = 0 ``` -------------------------------- ### Linux: Configure Real-time Group and Limits Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This snippet demonstrates how to create a 'realtime' group, add the current user to it, and configure system limits for real-time operations in `/etc/security/limits.conf`. These steps are crucial for enabling user-level threads to achieve real-time priority on Linux systems. ```shell sudo groupadd realtime sudo usermod -aG realtime $(whoami) ``` ```shell @realtime soft rtprio 99 @realtime soft priority 99 @realtime soft memlock 102400 @realtime hard rtprio 99 @realtime hard priority 99 @realtime hard memlock 102400 ``` -------------------------------- ### C++: Set RTDE Interface Real-time Priorities Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This C++ code example shows how to instantiate the RTDEControlInterface and RTDEReceiveInterface with specific real-time priorities. It also demonstrates calling a utility function to set the application's real-time priority. The priorities are specified as integers, with higher values indicating higher priority. ```c++ #include #include #include #include #include using namespace ur_rtde; using namespace std::chrono; // interrupt flag bool running = true; void raiseFlag(int param) { running = false; } std::vector getCircleTarget(const std::vector &pose, double timestep, double radius=0.075, double freq=1.0) { std::vector circ_target = pose; circ_target[0] = pose[0] + radius * cos((2 * M_PI * freq * timestep)); circ_target[1] = pose[1] + radius * sin((2 * M_PI * freq * timestep)); return circ_target; } int main(int argc, char* argv[]) { // Setup parameters std::string robot_ip = "localhost"; double rtde_frequency = 500.0; // Hz double dt = 1.0 / rtde_frequency; // 2ms uint16_t flags = RTDEControlInterface::FLAG_VERBOSE | RTDEControlInterface::FLAG_UPLOAD_SCRIPT; int ur_cap_port = 50002; // ur_rtde realtime priorities int rt_receive_priority = 90; int rt_control_priority = 85; RTDEControlInterface rtde_control(robot_ip, rtde_frequency, flags, ur_cap_port, rt_control_priority); RTDEReceiveInterface rtde_receive(robot_ip, rtde_frequency, {}, true, false, rt_receive_priority); // Set application real-time priority RTDEUtility::setRealtimePriority(80); return 0; } ``` -------------------------------- ### Configure and Compile Kernel Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Configures the kernel build using the existing .config file and then compiles the kernel into Debian packages. The multithreading option -j is set to the number of CPU cores for faster compilation. ```shell make olddefconfig make menuconfig make -j$(nproc) deb-pkg ``` -------------------------------- ### C++ RTDE Control and Receive Interface for UR Robots Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This C++ snippet demonstrates how to initialize and use the RTDEControlInterface and RTDEReceiveInterface for controlling a UR robot. It includes setting real-time priorities, defining movement parameters, and executing a circular motion using servoL within a loop. Error handling for exceptions is also included. ```cpp RTDEControlInterface rtde_control(robot_ip, rtde_frequency, flags, ur_cap_port, rt_control_priority); RTDEReceiveInterface rtde_receive(robot_ip, rtde_frequency, {}, true, false, rt_receive_priority); // Set application realtime priority RTDEUtility::setRealtimePriority(80); // Move parameters double vel = 0.5; double acc = 0.5; // Servo control parameters double lookahead_time = 0.1; double gain = 600; signal(SIGINT, raiseFlag); double time_counter = 0.0; // Move to init position using moveL std::vector actual_tcp_pose = rtde_receive.getActualTCPPose(); std::vector init_pose = getCircleTarget(actual_tcp_pose, time_counter); rtde_control.moveL(init_pose, vel, acc); try { while (running) { steady_clock::time_point t_start = rtde_control.initPeriod(); std::vector servo_target = getCircleTarget(actual_tcp_pose, time_counter); rtde_control.servoL(servo_target, vel, acc, dt, lookahead_time, gain); rtde_control.waitPeriod(t_start); time_counter += dt; } std::cout << "Control interrupted!" << std::endl; rtde_control.servoStop(); rtde_control.stopScript(); } catch(std::exception& e) { std::cerr << "error: " << e.what() << "\n"; return 1; } catch(...) { std::cerr << "Exception of unknown type!\n"; } return 0; } ``` -------------------------------- ### UR RTDE I/O Control: Set and Get Digital/Analog Outputs (C++, Python) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst Demonstrates how to set and get the state of standard and tool digital outputs, as well as set analog outputs using the RTDEIOInterface and RTDEReceiveInterface. Requires the ur_rtde library. Inputs include output channel numbers and boolean states/current ratios. Outputs are printed to the console. ```cpp #include #include #include #include using namespace ur_rtde; int main(int argc, char* argv[]) { RTDEIOInterface rtde_io("127.0.0.1"); RTDEReceiveInterface rtde_receive("127.0.0.1"); /** How-to set and get standard and tool digital outputs. Notice that we need the * RTDEIOInterface for setting an output and RTDEReceiveInterface for getting the state * of an output. */ if (rtde_receive.getDigitalOutState(7)) std::cout << "Standard digital out (7) is HIGH" << std::endl; else std::cout << "Standard digital out (7) is LOW" << std::endl; if (rtde_receive.getDigitalOutState(16)) std::cout << "Tool digital out (16) is HIGH" << std::endl; else std::cout << "Tool digital out (16) is LOW" << std::endl; rtde_io.setStandardDigitalOut(7, true); rtde_io.setToolDigitalOut(0, true); std::this_thread::sleep_for(std::chrono::milliseconds(10)); if (rtde_receive.getDigitalOutState(7)) std::cout << "Standard digital out (7) is HIGH" << std::endl; else std::cout << "Standard digital out (7) is LOW" << std::endl; if (rtde_receive.getDigitalOutState(16)) std::cout << "Tool digital out (16) is HIGH" << std::endl; else std::cout << "Tool digital out (16) is LOW" << std::endl; // How to set a analog output with a specified current ratio rtde_io.setAnalogOutputCurrent(1, 0.25); return 0; } ``` ```python import rtde_io import rtde_receive import time rtde_io_ = rtde_io.RTDEIOInterface("127.0.0.1") rtde_receive_ = rtde_receive.RTDEReceiveInterface("127.0.0.1") # How-to set and get standard and tool digital outputs. Notice that we need the # RTDEIOInterface for setting an output and RTDEReceiveInterface for getting the state # of an output. if rtde_receive_.getDigitalOutState(7): print("Standard digital out (7) is HIGH") else: print("Standard digital out (7) is LOW") if rtde_receive_.getDigitalOutState(16): print("Tool digital out (16) is HIGH") else: print("Tool digital out (16) is LOW") rtde_io_.setStandardDigitalOut(7, True) rtde_io_.setToolDigitalOut(0, True) time.sleep(0.01) if rtde_receive_.getDigitalOutState(7): print("Standard digital out (7) is HIGH") else: print("Standard digital out (7) is LOW") if rtde_receive_.getDigitalOutState(16): print("Tool digital out (16) is HIGH") else: print("Tool digital out (16) is LOW") # How to set a analog output with a specified current ratio rtde_io_.setAnalogOutputCurrent(1, 0.25) ``` -------------------------------- ### Robotiq Gripper Control: Activation and Status Check (C++) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst This C++ example demonstrates how to initialize, connect to, and activate a Robotiq Gripper via the RTDE interface. It also shows how to check the gripper's fault status and set its units. Dependencies include the ur_rtde library. The code prints status information to the console. ```cpp #include #include #include #include using namespace std; using namespace ur_rtde; /** * Print object detection status of gripper */ void printStatus(int Status) { switch (Status) { case RobotiqGripper::MOVING: std::cout << "moving"; break; case RobotiqGripper::STOPPED_OUTER_OBJECT: std::cout << "outer object detected"; break; case RobotiqGripper::STOPPED_INNER_OBJECT: std::cout << "inner object detected"; break; case RobotiqGripper::AT_DEST: std::cout << "at destination"; break; } std::cout << std::endl; } int main(int argc, char* argv[]) { std::cout << "Gripper test" << std::endl; ur_rtde::RobotiqGripper gripper("127.0.0.1", 63352, true); gripper.connect(); // Test emergency release functionality if (!gripper.isActive()) { gripper.emergencyRelease(RobotiqGripper::OPEN); } std::cout << "Fault status: 0x" << std::hex << gripper.faultStatus() << std::dec << std::endl; std::cout << "activating gripper" << std::endl; gripper.activate(); // Test setting of position units and conversion of position values gripper.setUnit(RobotiqGripper::POSITION, RobotiqGripper::UNIT_DEVICE); ``` -------------------------------- ### Configure Kernel Preemption Model Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst This snippet illustrates the selection of the 'Fully Preemptible Kernel (RT)' option within the kernel's menuconfig interface, specifically under the Preemption Model settings. This is crucial for real-time performance. ```none Preemption Model 1. No Forced Preemption (Server) (PREEMPT_NONE) > 2. Voluntary Kernel Preemption (Desktop) (PREEMPT_VOLUNTARY) 3. Preemptible Kernel (Low-Latency Desktop) (PREEMPT__LL) (NEW) 4. Preemptible Kernel (Basic RT) (PREEMPT_RTB) (NEW) 5. Fully Preemptible Kernel (RT) (PREEMPT_RT_FULL) (NEW) choice[1-5]: 5 ``` -------------------------------- ### Integrate ur_rtde with CMake Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst Demonstrates how to locate and link the ur_rtde library in a C++ project using CMake's find_package command. It includes standard configuration and methods for handling non-standard installation paths. ```cmake cmake_minimum_required(VERSION 3.5) project(ur_rtde_cmake_example) find_package(ur_rtde REQUIRED) add_executable(ur_rtde_cmake_example main.cpp) target_link_libraries(ur_rtde_cmake_example PRIVATE ur_rtde::rtde) # Alternative for non-standard paths: find_package(ur_rtde REQUIRED PATHS "/a/possible/path/to/ur_rtde" "/another/possible/path/to/ur_rtde") ``` -------------------------------- ### Decompress Downloaded Files Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Decompresses all .xz files in the current directory using the xz command. This is used to extract the kernel source and patch files after downloading. ```shell xz -d *.xz ``` -------------------------------- ### Start Recording Robot Data to CSV (C++) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst Initiates the recording of robot data to a specified CSV file. This function allows for selective recording of robot variables by passing a vector of variable names. If no variables are specified, all available data is recorded by default. ```c++ std::vector record_variables = {"timestamp", "actual_q", "actual_TCP_pose"}; rtde_receive.startFileRecording("robot_data.csv", record_variables); ``` -------------------------------- ### Enable Real-time Kernel Beta on Ubuntu 22.04 Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Commands to enable the real-time kernel beta on Ubuntu 22.04 using the 'ua' tool. This requires attaching to an Ubuntu Advantage subscription and enabling the 'realtime-kernel' feature. Ensure 'ubuntu-advantage-tools' is updated to at least version 27.8. ```shell ua attach ``` ```shell ua version ``` ```shell sudo apt install ubuntu-advantage-tools=27.8~22.04.1 ``` ```shell ua enable realtime-kernel --beta ``` -------------------------------- ### MoveL Path With Blending Example in C++ and Python Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst This example demonstrates executing a linear path with blending between waypoints using the moveL command. Each waypoint in the path is defined by a 9-dimensional vector including joint pose, velocity, acceleration, and blend radius. This functionality is useful for creating smooth, continuous robot movements. ```c++ #include using namespace ur_rtde; int main(int argc, char* argv[]) { RTDEControlInterface rtde_control("127.0.0.1"); double velocity = 0.5; double acceleration = 0.5; double blend_1 = 0.0; double blend_2 = 0.02; double blend_3 = 0.0; std::vector path_pose1 = {-0.143, -0.435, 0.20, -0.001, 3.12, 0.04, velocity, acceleration, blend_1}; std::vector path_pose2 = {-0.143, -0.51, 0.21, -0.001, 3.12, 0.04, velocity, acceleration, blend_2}; std::vector path_pose3 = {-0.32, -0.61, 0.31, -0.001, 3.12, 0.04, velocity, acceleration, blend_3}; std::vector> path; path.push_back(path_pose1); path.push_back(path_pose2); path.push_back(path_pose3); // Send a linear path with blending in between - (currently uses separate script) rtde_control.moveL(path); rtde_control.stopScript(); return 0; } ``` ```python import rtde_control rtde_c = rtde_control.RTDEControlInterface("127.0.0.1") velocity = 0.5 acceleration = 0.5 blend_1 = 0.0 blend_2 = 0.02 blend_3 = 0.0 path_pose1 = [-0.143, -0.435, 0.20, -0.001, 3.12, 0.04, velocity, acceleration, blend_1] path_pose2 = [-0.143, -0.51, 0.21, -0.001, 3.12, 0.04, velocity, acceleration, blend_2] path_pose3 = [-0.32, -0.61, 0.31, -0.001, 3.12, 0.04, velocity, acceleration, blend_3] path = [path_pose1, path_pose2, path_pose3] # Send a linear path with blending in between - (currently uses separate script) rtde_c.moveL(path) rtde_c.stopScript() ``` -------------------------------- ### Extract and Patch Kernel Source Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Extracts the Linux kernel source code from the tar archive and applies the real-time patch. It then copies the current kernel configuration as a default for the new real-time kernel. ```shell tar xf linux-*.tar cd linux-* patch -p1 < ../patch-*.patch cp -v /boot/config-$(uname -r) .config ``` -------------------------------- ### Download Real-time Kernel Sources for Ubuntu 20.04 Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Downloads the source code for Linux kernel version 5.9.1 for Ubuntu 20.04. This is the initial step in the manual process of compiling a real-time kernel. Corresponding real-time patches would typically be downloaded next. ```shell curl -SLO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.9.1.tar.xz ``` -------------------------------- ### Download GPG Public Keys Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Downloads the necessary public GPG keys from a keyserver to verify the signatures of the kernel and patch files. The key IDs (e.g., 6092693E, 2872E4CC) may vary for different kernel versions. ```shell gpg2 --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 6092693E gpg2 --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 2872E4CC ``` -------------------------------- ### Record Robot Data to CSV (C++) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst This C++ example demonstrates how to record robot data to a CSV file using the RTDE receive interface. It allows configuration of the robot IP address, output file name, and recording frequency via command-line arguments. The recording can be interrupted by pressing Ctrl+C. ```cpp #include #include #include #include #include #include namespace po = boost::program_options; volatile sig_atomic_t flag_loop = 1; void raiseFlag(int sig) { flag_loop = 0; } int main(int argc, char* argv[]) { try { // program options po::options_description desc; desc.add_options() ("help", "produce help message") ("robot_ip", po::value()->default_value("localhost"), "IP address of the UR robot") ("frequency", po::value()->default_value(500.0), "the frequency at which the data is recorded (default is 500Hz)") ("output", po::value()->default_value("robot_data.csv"), "data output (.csv) file to write to (default is \"robot_data.csv\"") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help")) { std::cout << desc << "\n"; return 0; } signal(SIGINT, raiseFlag); double frequency = vm["frequency"].as(); double dt = 1.0 / frequency; RTDEReceiveInterface rtde_receive(vm["robot_ip"].as(), frequency); rtde_receive.startFileRecording(vm["output"].as()); std::cout << "Data recording started. press [Ctrl-C] to end recording." << std::endl; int i=0; while (flag_loop) { auto t_start = steady_clock::now(); if (i % 10 == 0) { std::cout << '\r'; printf("%.3d samples.", i); std::cout << std::flush; } auto t_stop = steady_clock::now(); auto t_duration = std::chrono::duration(t_stop - t_start); if (t_duration.count() < dt) { std::this_thread::sleep_for(std::chrono::duration(dt - t_duration.count())); } i++; } // Stop data recording. rtde_receive.stopFileRecording(); std::cout << "\nData recording stopped." << std::endl; } catch(std::exception& e) { std::cerr << "error: " << e.what() << "\n"; return 1; } catch(...) { std::cerr << "Exception of unknown type!\n"; } return 0; } ``` -------------------------------- ### Record Robot Data to CSV (Python) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst This Python example demonstrates how to record robot data to a CSV file using the RTDE receive interface. It utilizes the `argparse` module for command-line argument parsing, allowing users to specify the robot IP, output file, and recording frequency. The recording can be stopped by interrupting the script with Ctrl+C. ```python from rtde_receive import RTDEReceiveInterface as RTDEReceive import time import argparse import sys def parse_args(args): """Parse command line parameters Args: args ([str]): command line parameters as list of strings Returns: :obj:`argparse.Namespace`: command line parameters namespace """ parser = argparse.ArgumentParser( description="Record data example") parser.add_argument( "-ip", "--robot_ip", dest="ip", help="IP address of the UR robot", type=str, default='localhost', metavar="") parser.add_argument( "-o", "--output", dest="output", help="data output (.csv) file to write to (default is \"robot_data.csv\"", type=str, default="robot_data.csv", metavar="") parser.add_argument( "-f", "--frequency", dest="frequency", help="the frequency at which the data is recorded (default is 500Hz)", type=float, default=500.0, metavar="") return parser.parse_args(args) def main(args): """Main entry point allowing external calls Args: args ([str]): command line parameter list """ args = parse_args(args) dt = 1 / args.frequency rtde_r = RTDEReceive(args.ip, args.frequency) rtde_r.startFileRecording(args.output) print("Data recording started, press [Ctrl-C] to end recording.") i = 0 try: while True: start = time.time() if i % 10 == 0: sys.stdout.write("\r") sys.stdout.write("{:3d} samples.".format(i)) sys.stdout.flush() end = time.time() duration = end - start if duration < dt: time.sleep(dt - duration) i += 1 except KeyboardInterrupt: rtde_r.stopFileRecording() print("\nData recording stopped.") if __name__ == "__main__": main(sys.argv[1:]) ``` -------------------------------- ### SpeedJ Robot Control Example in C++ and Python Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst This example demonstrates controlling robot joint speeds continuously using the speedJ command within a high-frequency control loop. It requires the ur_rtde library and involves setting joint positions, speeds, accelerations, and a control loop duration. The output is a continuous movement of the first two joints. ```c++ #include #include #include using namespace ur_rtde; using namespace std::chrono; int main(int argc, char* argv[]) { RTDEControlInterface rtde_control("127.0.0.1"); // Parameters double acceleration = 0.5; double dt = 1.0/500; // 2ms std::vector joint_q = {-1.54, -1.83, -2.28, -0.59, 1.60, 0.023}; std::vector joint_speed = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // Move to initial joint position with a regular moveJ rtde_control.moveJ(joint_q); // Execute 500Hz control loop for 2 seconds, each cycle is ~2ms for (unsigned int i=0; i<1000; i++) { steady_clock::time_point t_start = rtde_control.initPeriod(); rtde_control.speedJ(joint_speed, acceleration, dt); joint_speed[0] += 0.0005; joint_speed[1] += 0.0005; rtde_control.waitPeriod(t_start); } rtde_control.speedStop(); rtde_control.stopScript(); return 0; } ``` ```python import rtde_control rtde_c = rtde_control.RTDEControlInterface("127.0.0.1") # Parameters acceleration = 0.5 dt = 1.0/500 # 2ms joint_q = [-1.54, -1.83, -2.28, -0.59, 1.60, 0.023] joint_speed = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Move to initial joint position with a regular moveJ rtde_c.moveJ(joint_q) # Execute 500Hz control loop for 2 seconds, each cycle is 2ms for i in range(1000): t_start = rtde_c.initPeriod() rtde_c.speedJ(joint_speed, acceleration, dt) joint_speed[0] += 0.0005 joint_speed[1] += 0.0005 rtde_c.waitPeriod(t_start) rtde_c.speedStop() rtde_c.stopScript() ``` -------------------------------- ### Component Group and Install Type Setup Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/CMakeLists.txt Defines component groups and install types for the UR RTDE package. This allows users to select specific parts of the installation, such as development files or dependencies. ```cmake get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) # Get all components include(CPack) # Setup Install Groupes #### cpack_add_component_group(UR_RTDE DISPLAY_NAME "ur_rtde" DESCRIPTION "Libraries for controlling UR robots" EXPANDED BOLD_TITLE ) cpack_add_component_group(MISC DISPLAY_NAME "Miscellaneous" DESCRIPTION "These are miscellaneous packages" ) cpack_add_component_group(DEP DISPLAY_NAME "Dependencies" DESCRIPTION "These are external dependencies for the ur_rtde" ) cpack_add_component_group(DEVEL DISPLAY_NAME "Development Files" DESCRIPTION "These are packages needed when you want to use ur_rtde for development" ) # Setup Install Types #### cpack_add_install_type(Full DISPLAY_NAME "Full") # Setup Install Components cpack_add_component( ur_rtde_lib DISPLAY_NAME "DevelFiles" DESCRIPTION "This package includes the files necessary to run a program that depends on ur_rtde" GROUP UR_RTDE DEPENDS ur_rtde_lib INSTALL_TYPES Full # DOWNLOADED ARCHIVE_FILE #Name_of_file_to_generate_for_download ) ``` -------------------------------- ### NSIS Setup for UR RTDE Installer Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/CMakeLists.txt Configures the NSIS (Nullsoft Scriptable Install System) generator for creating Windows installers for the UR RTDE project. Sets display name, help links, and manages PATH modifications based on build type. ```cmake set(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}") set(CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_NSIS_HELP_LINK ${CPACK_PACKAGE_HOMEPAGE_URL}) set(CPACK_NSIS_URL_INFO_ABOUT ${CPACK_PACKAGE_HOMEPAGE_URL}) set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) # When installing on a previus # instalation ask to uninstall first set(CPACK_NSIS_UNINSTALL_NAME "ur_rtde_uninstall") set(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT}) # Make sure the system findes the project at installation if(BUILD_STATIC) set(CPACK_NSIS_MODIFY_PATH OFF) # Add the binary folder to PATH else() set(CPACK_NSIS_MODIFY_PATH ON) # Add the binary folder to PATH endif() set( CPACK_NSIS_EXTRA_INSTALL_COMMANDS # let cmake find ur_rtde "WriteRegStr HKCU \"Software${SLASH}Kitware${SLASH}CMake${SLASH}Packages${SLASH}ur_rtde\" \"Location\" \"$INSTDIR\"" "WriteRegStr HKLM \"Software${SLASH}Kitware${SLASH}CMake${SLASH}Packages${SLASH}ur_rtde\" \"Location\" \"$INSTDIR\"" ) set( CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS # clean up when uninstalling ur_rtde "DeleteRegKey HKCU \"Software${SLASH}Kitware${SLASH}CMake${SLASH}Packages${SLASH}ur_rtde\"" "DeleteRegKey HKLM \"Software${SLASH}Kitware${SLASH}CMake${SLASH}Packages${SLASH}ur_rtde\"" ) string( REPLACE ";" "\n" CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}" ) string( REPLACE ";" "\n" CPACK_NSIS_EXTRA_UNSTALL_COMMANDS "${CPACK_NSIS_EXTRA_UNSTALL_COMMANDS}" ) ``` -------------------------------- ### Move Robot with RTDE Control Interface Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst Shows how to initialize the RTDE Control Interface and execute a linear move (moveL) command to a specific pose. Inputs include the robot IP, target pose vector, speed, and acceleration. ```c++ RTDEControlInterface rtde_control("127.0.0.1"); rtde_control.moveL({-0.143, -0.435, 0.20, -0.001, 3.12, 0.04}, 0.5, 0.2); ``` ```python import rtde_control rtde_c = rtde_control.RTDEControlInterface("127.0.0.1") rtde_c.moveL([-0.143, -0.435, 0.20, -0.001, 3.12, 0.04], 0.5, 0.3) ``` -------------------------------- ### Configure Static Library Build (CMake) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/installation/installation.rst Controls whether UR RTDE is built as a static library (ON) or a dynamic-link library (OFF, default). Building statically increases compile time and output size but simplifies deployment by avoiding separate DLL files. ```cmake cmake -DBUILD_STATIC=ON .. cmake -DBUILD_STATIC=OFF .. ``` -------------------------------- ### Upload Package to Launchpad (Bash) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/debian/how_to_setup.md Executes a build script to upload a Debian package to Launchpad. The '-c deb-upload' option configures the changelog and initiates the upload process. This script automates the packaging and distribution workflow. ```bash ./debian/ur_rtde_build.sh -c deb-upload ``` -------------------------------- ### Jog UR Robot with RTDEControlInterface Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/examples/examples.rst Demonstrates jogging a UR robot in the tool frame using keyboard input. It initializes the RTDE control interface and ncurses for keyboard input. The robot can be jogged along the X, Y, and Z axes of the tool frame by pressing the arrow keys. Press 'q' to exit. ```cpp #include #include #include #include #include using namespace ur_rtde; using namespace std::chrono; int main(int argc, char* argv[]) { RTDEControlInterface rtde_control("127.0.0.1"); // Curses Initialisations initscr(); raw(); keypad(stdscr, TRUE); noecho(); timeout(10); // Parameters double speed_magnitude = 0.15; std::vector speed_vector = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); std::string instructions("[ Use arrow keys to control the robot, to exit press 'q' ]"); int c, row, col; getmaxyx(stdscr, row, col); mvprintw(row / 2, (col-strlen(instructions.c_str())) / 2, "%s", instructions.c_str()); while ((c = getch()) != 'q') { steady_clock::time_point t_start = rtde_control.initPeriod(); c = getch(); switch (c) { case KEY_UP: speed_vector = {0.0, 0.0, -speed_magnitude, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); break; case KEY_DOWN: speed_vector = {0.0, 0.0, speed_magnitude, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); break; case KEY_LEFT: speed_vector = {speed_magnitude, 0.0, 0.0, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); break; case KEY_RIGHT: speed_vector = {-speed_magnitude, 0.0, 0.0, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); break; default: speed_vector = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; rtde_control.jogStart(speed_vector, RTDEControlInterface::FEATURE_TOOL); break; } } endwin(); // Curses end return 0; } ``` -------------------------------- ### Download Real-time Kernel Sources and Patches for Ubuntu 18.04 Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/guides/guides.rst Downloads the source code for Linux kernel version 5.4.19 and the corresponding real-time patches (5.4.19-rt10) for Ubuntu 18.04. This is part of the manual process to compile a real-time kernel. ```shell curl -SLO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.19.tar.xz curl -SLO https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.19.tar.sign curl -SLO https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patch-5.4.19-rt10.patch.xz curl -SLO https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patch-5.4.19-rt10.patch.sign ``` -------------------------------- ### Clone and Build UR RTDE (Shell) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/doc/installation/installation.rst Clones the UR RTDE repository and compiles the interface using CMake and MSBuild on Windows. Requires Boost to be installed. The CMake command configures the build, and MSBuild performs the compilation. ```shell git clone https://gitlab.com/sdurobotics/ur_rtde.git cd ur_rtde mkdir Build cd Build cmake -DBOOST_ROOT=">" -DBOOST_LIBRARYDIR="\>" -DPYTHON_BINDINGS=OFF .. msbuild ur_rtde.sln /property:Configuration=Release /maxcpucount: ``` -------------------------------- ### CPack Setup for UR RTDE Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/CMakeLists.txt Configures CPack for packaging the UR RTDE project. Sets package name, vendor, description, homepage, and contact information. It also defines versioning and file naming conventions for the generated installer. ```cmake set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_VENDOR "University of Southern Denmark") set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "A C++ interface for sending and receiving data to/from a UR robot using the Real-Time Data Exchange (RTDE) interface of the robot" ) set(CPACK_PACKAGE_HOMEPAGE_URL "https://sdurobotics.gitlab.io/ur_rtde/") set(CPACK_PACKAGE_INSTALL_DIRECTORY "ur_rtde") set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}${SLASH}LICENSE") set(CPACK_PACKAGE_CONTACT "Anders Prier Lindvig (anpl@mmmi.sdu.dk)") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-install) ``` -------------------------------- ### Generate GPG Key (Bash) Source: https://gitlab.com/sdurobotics/ur_rtde/-/blob/master/debian/how_to_setup.md Generates a new GPG key pair for signing packages. The user is prompted for key type, keysize, validity period, and a passphrase. The output shows the fingerprint and details of the created key. ```bash gpg --gen-key # Options: # "Please select what kind of key you want:" select (1) # "What keysize do you want? " selecting (2048) should be fine # "Key is valid for?" selecting (0) means it is valid forever and you need to revoke it # Verify your email and name with (Y) # You need a Passphrase to protect your secret key. type 0 to continue then enter you passphrase twice # when done you should see somthing like: gpg: key D8FC66D2 marked as ultimately trusted public and secret key created and signed. pub 1024D/D8FC66D2 2005-09-08 Key fingerprint = 95BD 8377 2644 DD4F 28B5 2C37 0F6E 4CA6 D8FC 66D2 uid Dennis Kaarsemaker (Tutorial key) sub 2048g/389AA63E 2005-09-08 ```