### Install Unitree SDK2 to System Directory (Bash) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/README.md Installs the Unitree SDK2 to the system's default directories, making it available for system-wide use. Requires root privileges for the 'make install' command. ```bash mkdir build cd build cmake .. sudo make install ``` -------------------------------- ### Install Unitree SDK2 to Specified Directory (Bash) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/README.md Installs the Unitree SDK2 to a custom directory specified by CMAKE_INSTALL_PREFIX. This allows for isolated installations. Requires root privileges for the 'make install' command. ```bash mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=/opt/unitree_robotics sudo make install ``` -------------------------------- ### Install Dependencies for Unitree SDK2 (Bash) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/README.md Installs necessary packages for building the Unitree SDK2 on Ubuntu 20.04 LTS. Requires root privileges for apt-get update and install. ```bash apt-get update apt-get install -y cmake g++ build-essential libyaml-cpp-dev libeigen3-dev libboost-all-dev libspdlog-dev libfmt-dev ``` -------------------------------- ### Add Subscriber Executable and Link to unitree_sdk2 (C++) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/helloworld/CMakeLists.txt This snippet defines a subscriber executable target named 'test_subscriber' using C++ source files and links it against the 'unitree_sdk2' library. This is analogous to the publisher example, illustrating the setup for a subscriber node. ```cmake add_executable(test_subscriber \ subscriber.cpp \ HelloWorldData.cpp ) target_link_libraries(test_subscriber unitree_sdk2) ``` -------------------------------- ### Build Unitree SDK2 Examples (Bash) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/README.md Compiles the example projects included within the Unitree SDK2 repository. This process involves creating a build directory, configuring with CMake, and then building with Make. ```bash mkdir build cd build cmake .. make ``` -------------------------------- ### Add Executable for G1 Audio Client Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake configuration creates a build target for the G1 audio client example. It compiles the C++ source file and links it with the 'unitree_sdk2' library for audio functionalities. ```cmake add_executable(g1_audio_client_example audio/g1_audio_client_example.cpp) target_link_libraries(g1_audio_client_example unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 Ankle Swing Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake command defines an executable for the G1 ankle swing example, located in the 'low_level' directory. It links the executable to the 'unitree_sdk2' library. ```cmake add_executable(g1_ankle_swing_example low_level/g1_ankle_swing_example.cpp) target_link_libraries(g1_ankle_swing_example unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 Loco Client Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This snippet adds an executable target named 'g1_loco_client' and links it against the 'unitree_sdk2' library. It's designed to build a client example for G1 locomotion control. ```cmake add_executable(g1_loco_client high_level/g1_loco_client_example.cpp) target_link_libraries(g1_loco_client unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 DEX3 Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake snippet defines a build target for the G1 DEX3 example. It compiles the specified C++ source file and links it against the 'unitree_sdk2' library. ```cmake add_executable(g1_dex3_example dex3/g1_dex3_example.cpp) target_link_libraries(g1_dex3_example unitree_sdk2) ``` -------------------------------- ### Install SDK Targets (CMake) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/thirdparty/CMakeLists.txt This CMake snippet defines the installation rules for the Unitree SDK2. It installs all shared libraries found in the specified library directory and installs the include directory recursively. This ensures the SDK can be properly packaged and deployed. ```cmake ## Install targets file(GLOB DDS_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/*") install(FILES ${DDS_LIBRARIES} DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### Conditional Build for G1 Termination and Arm Action Examples with Boost Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake code conditionally builds 'g1_termination' and 'g1_arm_action_example' targets if the Boost.program_options library is found. Both executables are linked against 'unitree_sdk2' and 'Boost::program_options'. ```cmake find_package(Boost COMPONENTS program_options) if(Boost_FOUND) add_executable(g1_termination low_level/terminations.cpp) target_link_libraries(g1_termination unitree_sdk2 Boost::program_options) add_executable(g1_arm_action_example high_level/g1_arm_action_example.cpp) target_link_libraries(g1_arm_action_example unitree_sdk2 Boost::program_options) endif() ``` -------------------------------- ### Robot Camera Access with C++ Video Client Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Provides access to the robot's cameras to capture images. This example demonstrates how to initialize the video client, retrieve image data, and save it as a JPEG file with a timestamp. Requires the unitree/robot/go2/video/video_client.hpp header. ```cpp #include #include #include int main() { unitree::robot::ChannelFactory::Instance()->Init(0); unitree::robot::go2::VideoClient video_client; video_client.SetTimeout(1.0f); video_client.Init(); while (true) { std::vector image_data; int ret = video_client.GetImageSample(image_data); if (ret == 0 && !image_data.empty()) { // Generate timestamped filename time_t now; time(&now); struct tm* timeinfo = localtime(&now); char filename[80]; strftime(filename, sizeof(filename), "%Y%m%d_%H%M%S.jpg", timeinfo); // Save JPEG image std::ofstream file(filename, std::ios::binary); if (file.is_open()) { file.write(reinterpret_cast(image_data.data()), image_data.size()); file.close(); std::cout << "Saved: " << filename << " (" << image_data.size() << " bytes)" << std::endl; } } else { std::cerr << "Failed to get image, error: " << ret << std::endl; } sleep(3); // Capture every 3 seconds } return 0; } ``` -------------------------------- ### Install Unitree SDK2 and CMake Configuration Files Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/CMakeLists.txt Installs the Unitree SDK2 library, header files, and CMake configuration files (`.cmake`) to the appropriate locations. This enables other projects to find and use the SDK. ```cmake install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES ${UNITREE_SDK_LIB} DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES cmake/unitree_sdk2Targets.cmake DESTINATION lib/cmake/unitree_sdk2) include(CMakePackageConfigHelpers) write_basic_package_version_file( unitree_sdk2ConfigVersion.cmake VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}" COMPATIBILITY ExactVersion) configure_file(cmake/unitree_sdk2Config.cmake.in unitree_sdk2Config.cmake @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/unitree_sdk2Config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/unitree_sdk2ConfigVersion.cmake" DESTINATION lib/cmake/unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 AGV Client Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake command defines an executable target for the G1 AGV client example. It compiles the C++ source file and links it with the 'unitree_sdk2' library. ```cmake add_executable(g1_agv_client_example agv/g1_agv_client_example.cpp) target_link_libraries(g1_agv_client_example unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 Arm5 SDK DDS Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake configuration defines an executable for the G1 Arm5 SDK DDS example. It compiles the specified C++ source file and links it with the 'unitree_sdk2' library. ```cmake add_executable(g1_arm5_sdk_dds_example high_level/g1_arm5_sdk_dds_example.cpp) target_link_libraries(g1_arm5_sdk_dds_example unitree_sdk2) ``` -------------------------------- ### Add Executable for G1 Arm7 SDK DDS Example Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake snippet sets up a build target for the G1 Arm7 SDK DDS example. It compiles the C++ source file and links it against the 'unitree_sdk2' library, enabling DDS communication for the arm. ```cmake add_executable(g1_arm7_sdk_dds_example high_level/g1_arm7_sdk_dds_example.cpp) target_link_libraries(g1_arm7_sdk_dds_example unitree_sdk2) ``` -------------------------------- ### Add Executable and Link to unitree_sdk2 (C++) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/helloworld/CMakeLists.txt This snippet shows how to define an executable target named 'test_publisher' using C++ source files and link it against the 'unitree_sdk2' library. It's a common pattern for building ROS nodes or standalone applications that utilize the SDK. ```cmake add_executable(test_publisher \ publisher.cpp \ HelloWorldData.cpp ) target_link_libraries(test_publisher unitree_sdk2) ``` -------------------------------- ### Conditional Build for G1 Dual Arm Example with yaml-cpp Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/g1/CMakeLists.txt This CMake snippet conditionally builds the 'g1_dual_arm_example' if 'yaml-cpp' version 0.6 or greater is found. The executable is linked against 'unitree_sdk2' and 'yaml-cpp', and a compile definition for 'BLIB_DIR' is set. ```cmake find_package(yaml-cpp QUIET) if(yaml-cpp_FOUND) if (${yaml-cpp_VERSION} VERSION_GREATER_EQUAL "0.6") message(STATUS "Found yaml-cpp version ${yaml-cpp_VERSION}") add_executable(g1_dual_arm_example low_level/g1_dual_arm_example.cpp) target_link_libraries(g1_dual_arm_example PRIVATE unitree_sdk2 yaml-cpp) target_compile_definitions(g1_dual_arm_example PUBLIC BLIB_DIR="${CMAKE_CURRENT_SOURCE_DIR}/low_level/behavior_lib/") else() message(STATUS "yaml-cpp version ${yaml-cpp_VERSION} is too old, skipping build of g1_dual_arm_example.") endif() endif() ``` -------------------------------- ### Add Executable and Link to Unitree SDK2 (CMake) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/b2/CMakeLists.txt This snippet shows how to define an executable target and link it against the 'unitree_sdk2' library using CMake. It's a common pattern for integrating external libraries into C++ projects. ```cmake add_executable(b2_sport_client b2_sport_client.cpp) target_link_libraries(b2_sport_client unitree_sdk2) ``` ```cmake add_executable(b2_stand_example b2_stand_example.cpp) target_link_libraries(b2_stand_example unitree_sdk2) ``` -------------------------------- ### Periodic Control Loop with RecurrentThread (C++) Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt This example shows how to create a periodic control loop using the `RecurrentThread` utility from the Unitree SDK2. It's suitable for tasks requiring precise timing, such as low-level motor control or high-level behaviors. The snippet includes initialization of a `SportClient` and a demonstration of a sinusoidal velocity command executed at a specified frequency. ```cpp #include #include class RobotController { public: unitree::robot::go2::SportClient sport_client; float dt = 0.002; // 2ms = 500Hz control rate int count = 0; void Init() { sport_client.SetTimeout(10.0f); sport_client.Init(); } void ControlLoop() { count++; // Example: Sinusoidal velocity command float t = count * dt; float vx = 0.2 * sin(2.0 * M_PI * 0.5 * t); // 0.5 Hz oscillation sport_client.Move(vx, 0.0, 0.0); if (count % 500 == 0) { // Print every second std::cout << "Time: " << t << "s, vx: " << vx << std::endl; } } }; int main(int argc, char** argv) { unitree::robot::ChannelFactory::Instance()->Init(0, argv[1]); RobotController controller; controller.Init(); // Create recurrent thread: interval in microseconds uint64_t interval_us = controller.dt * 1000000; // 2000 us = 2ms unitree::common::ThreadPtr threadPtr = unitree::common::CreateRecurrentThread( interval_us, std::bind(&RobotController::ControlLoop, &controller) ); // Alternative with thread name and CPU affinity // ThreadPtr threadPtr = CreateRecurrentThreadEx("ctrl_loop", UT_CPU_ID_NONE, interval_us, // &RobotController::ControlLoop, &controller); while (true) { sleep(10); } return 0; } ``` -------------------------------- ### Import Shared Library ddscxx (CMake) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/thirdparty/CMakeLists.txt This snippet shows how to import a pre-built shared library named 'ddscxx' using CMake. It defines the library's location, links it with the Threads library, and configures include paths for build and installation. It also includes an additional include directory specific to 'ddscxx'. Dependencies include the Threads library. ```cmake message(STATUS "Importing: ${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/libddscxx.so") add_library(ddscxx SHARED IMPORTED GLOBAL) set_target_properties(ddscxx PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/libddscxx.so) set_target_properties(ddscxx PROPERTIES IMPORTED_NO_SONAME TRUE) target_link_libraries(ddscxx INTERFACE Threads::Threads) target_link_directories(ddscxx INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}) target_include_directories(ddscxx INTERFACE $ $ $ $) ``` -------------------------------- ### Import Shared Library ddsc (CMake) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/thirdparty/CMakeLists.txt This snippet demonstrates how to import a pre-built shared library named 'ddsc' using CMake. It specifies the library's location, links it with the Threads library, and sets up include directories for both build and installation time. Dependencies include the Threads library. ```cmake find_package(Threads REQUIRED) message(STATUS "Importing: ${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/libddsc.so") add_library(ddsc SHARED IMPORTED GLOBAL) set_target_properties(ddsc PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/libddsc.so) set_target_properties(ddsc PROPERTIES IMPORTED_NO_SONAME TRUE) target_link_libraries(ddsc INTERFACE Threads::Threads) target_link_directories(ddsc INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}) target_include_directories(ddsc INTERFACE $ $) ``` -------------------------------- ### Compile and Run H1_2 Ankle Tracking Experiment (Bash) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/h1/README.md This bash command compiles and runs the H1_2 ankle tracking experiment using the unitree_sdk2. It requires the robot to be suspended and takes the network interface as an argument. The experiment will reset the robot, swing its ankles, and print tracking data. ```bash h1_2_ankle_track network_interface ``` -------------------------------- ### Manage Robot Services with C++ RobotStateClient Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt This C++ snippet demonstrates how to use the RobotStateClient to manage robot services. It covers initializing the client, checking API version compatibility, configuring state reporting frequency, listing available services, and switching between them. Dependencies include the unitree robot SDK2 headers. ```cpp #include int main(int argc, char** argv) { unitree::robot::ChannelFactory::Instance()->Init(0, argv[1]); unitree::robot::go2::RobotStateClient rsc; rsc.SetTimeout(10.0f); rsc.Init(); // Verify API version compatibility std::string clientVersion = rsc.GetApiVersion(); std::string serverVersion = rsc.GetServerApiVersion(); if (clientVersion != serverVersion) { std::cerr << "API version mismatch!" << std::endl; } // Configure state reporting: SetReportFreq(interval_ms, duration_s) int32_t ret = rsc.SetReportFreq(3, 30); // Report every 3ms for 30 seconds // List all available services std::vector services; ret = rsc.ServiceList(services); for (const auto& svc : services) { std::cout << "Service: " << svc.name << ", Status: " << svc.status << ", Protected: " << svc.protect << std::endl; } // Available services: sport_mode, ai_sport, advanced_sport, wheeled_sport, etc. // Switch services: ServiceSwitch(name, enable, status) int32_t status; ret = rsc.ServiceSwitch("sport_mode", 0, status); // Disable sport_mode std::cout << "Disable sport_mode: " << (ret == 0 ? "OK" : "FAILED") << std::endl; ret = rsc.ServiceSwitch("sport_mode", 1, status); // Enable sport_mode std::cout << "Enable sport_mode: " << (ret == 0 ? "OK" : "FAILED") << std::endl; unitree::robot::ChannelFactory::Instance()->Release(); return 0; } ``` -------------------------------- ### Humanoid Robot Locomotion Control with LocoClient (C++) Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt This snippet demonstrates how to use the LocoClient to control humanoid robots like H1 and G1. It covers initialization, state querying, odometry, various motion commands (standing, walking, turning, damping), velocity control, target position navigation, gait parameter adjustments, and arm gestures. It requires the Unitree SDK2 library. ```cpp #include // For G1: #include int main(int argc, char** argv) { unitree::robot::ChannelFactory::Instance()->Init(0, "eth0"); unitree::robot::h1::LocoClient client; // For G1: unitree::robot::g1::LocoClient client; client.Init(); client.SetTimeout(10.0f); // State queries int fsm_id, fsm_mode, balance_mode; float swing_height, stand_height; client.GetFsmId(fsm_id); client.GetFsmMode(fsm_mode); client.GetBalanceMode(balance_mode); client.GetSwingHeight(swing_height); client.GetStandHeight(stand_height); // Odometry client.EnableOdom(); float x, y, yaw; client.GetOdom(x, y, yaw); // Get current position client.DisableOdom(); // Motion control client.StandUp(); // Stand from any position client.HighStand(); // Maximum standing height client.LowStand(); // Minimum standing height client.BalanceStand(); // Active balance mode client.Damp(); // Enter damping (safe) mode client.ZeroTorque(); // Zero all motor torques // Walking control: Move(vx, vy, vyaw) client.Move(0.3, 0.0, 0.0); // Walk forward at 0.3 m/s client.Move(0.0, 0.0, 0.5); // Turn in place at 0.5 rad/s client.StopMove(); // Stop movement // Velocity with duration: SetVelocity(vx, vy, omega, duration_seconds) client.SetVelocity(0.2, 0.0, 0.1, 5.0); // Walk for 5 seconds // Target position navigation (relative to current position) client.SetTargetPos(1.0, 0.5, 0.0, true); // Move 1m forward, 0.5m left // Gait parameters client.SetSwingHeight(0.1); // Set foot swing height client.SetStandHeight(0.9); // Set body standing height client.ContinuousGait(true); // Enable continuous walking mode // Arm gestures (H1/G1 humanoids) client.WaveHand(); // Wave hand gesture client.ShakeHand(0); // Start handshake sleep(10); client.ShakeHand(1); // End handshake return 0; } ``` -------------------------------- ### Go2 SportClient: High-Level Motion Control for Quadruped Robots Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Utilizes the SportClient to send high-level motion commands to Go2 quadruped robots. It abstracts complex movements like standing, walking, and special gestures into simple API calls. Requires ChannelFactory initialization and sets a request timeout. ```cpp #include int main(int argc, char** argv) { unitree::robot::ChannelFactory::Instance()->Init(0, argv[1]); unitree::robot::go2::SportClient sport_client; sport_client.SetTimeout(10.0f); // Set request timeout to 10 seconds sport_client.Init(); // Basic motion commands sport_client.StandUp(); // Stand up from any position sport_client.StandDown(); // Lower to ground sport_client.RecoveryStand(); // Recover from fallen state sport_client.BalanceStand(); // Active balance standing sport_client.Damp(); // Enter damping (safe) mode // Velocity-based movement: Move(vx, vy, vyaw) // vx: forward velocity (m/s), vy: lateral velocity (m/s), vyaw: angular velocity (rad/s) sport_client.Move(0.3, 0.0, 0.0); // Walk forward at 0.3 m/s sport_client.Move(0.0, 0.2, 0.0); // Strafe left at 0.2 m/s sport_client.Move(0.0, 0.0, 0.5); // Rotate in place at 0.5 rad/s sport_client.StopMove(); // Stop all movement // Special motions sport_client.Sit(); // Sit down sport_client.RiseSit(); // Rise from sitting sport_client.Hello(); // Wave hello gesture sport_client.Stretch(); // Stretch motion sport_client.FrontFlip(); // Perform front flip sport_client.Dance1(); // Dance routine 1 // Body orientation control: Euler(roll, pitch, yaw) in radians sport_client.Euler(0.1, 0.2, 0.0); return 0; } ``` -------------------------------- ### G1 Audio Client: TTS, Audio Playback, and Control (C++) Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt This C++ code snippet demonstrates the usage of the G1 AudioClient for text-to-speech synthesis, audio playback, volume control, LED manipulation, and subscribing to speech recognition results. It requires the Unitree SDK2 library and ROS2 DDS message types. ```cpp #include #include #include #define ASR_TOPIC "rt/audio_msg" // Speech recognition results topic void AsrHandler(const void* msg) { auto* result = (std_msgs::msg::dds_::String_*)msg; std::cout << "Speech recognized: " << result->data() << std::endl; } int main(int argc, char** argv) { unitree::robot::ChannelFactory::Instance()->Init(0, argv[1]); unitree::robot::g1::AudioClient audio; audio.Init(); audio.SetTimeout(10.0f); // Subscribe to speech recognition results unitree::robot::ChannelSubscriber asr_sub(ASR_TOPIC); asr_sub.InitChannel(AsrHandler); // Volume control uint8_t volume; audio.GetVolume(volume); std::cout << "Current volume: " << (int)volume << "%" << std::endl; audio.SetVolume(100); // Set volume to 100% // Text-to-Speech: TtsMaker(text, language) // language: 0 = Chinese (auto), 1 = English audio.TtsMaker("Hello, I am a Unitree robot.", 1); sleep(5); // Wait for speech to complete audio.TtsMaker("你好,我是宇树机器人。", 0); // Chinese TTS sleep(5); // LED control: LedControl(red, green, blue) - values 0-255 audio.LedControl(255, 0, 0); // Red sleep(1); audio.LedControl(0, 255, 0); // Green sleep(1); audio.LedControl(0, 0, 255); // Blue sleep(1); audio.LedControl(0, 0, 0); // Off // Audio streaming playback (16kHz mono PCM) std::vector pcm_data; // Load your PCM audio data here std::string stream_id = "my_stream_001"; size_t chunk_size = 96000; // 3 seconds at 16kHz stereo for (size_t offset = 0; offset < pcm_data.size(); offset += chunk_size) { size_t len = std::min(chunk_size, pcm_data.size() - offset); std::vector chunk(pcm_data.begin() + offset, pcm_data.begin() + offset + len); audio.PlayStream("my_audio", stream_id, chunk); sleep(1); } audio.PlayStop(stream_id); // Stop playback // Keep running to receive ASR messages while (true) sleep(1); return 0; } ``` -------------------------------- ### Set Output Directories for Binaries and Libraries Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/CMakeLists.txt Configures CMake to place binary files in the '/bin' directory and libraries in the '/lib' directory relative to the project's binary directory, using GNUInstallDirs for platform compatibility. ```cmake include(GNUInstallDirs) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) ``` -------------------------------- ### Subscribe to Wireless Controller Input with C++ Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt This C++ snippet shows how to subscribe to the wireless controller topic to receive joystick and button inputs. It utilizes a callback function to process incoming messages, extracting joystick axis values and button states. Dependencies include unitree robot SDK2 channel and IDL headers, and a mutex for thread-safe access. ```cpp #include #include #include #define TOPIC_JOYSTICK "rt/wirelesscontroller" class JoystickHandler { public: std::mutex mtx; float lx, ly, rx, ry; // Joystick axes: -1.0 to 1.0 uint32_t keys; // Button bitmask void Callback(const void* message) { std::lock_guard lock(mtx); auto* msg = (unitree_go::msg::dds_::WirelessController_*)message; lx = msg->lx(); // Left stick X ly = msg->ly(); // Left stick Y rx = msg->rx(); // Right stick X ry = msg->ry(); // Right stick Y keys = msg->keys(); // Button states // Button bitmask decoding (example values, check documentation) bool A_pressed = keys & 0x01; bool B_pressed = keys & 0x02; bool X_pressed = keys & 0x04; bool Y_pressed = keys & 0x08; std::cout << "Joystick: lx=" << lx << " ly=" << ly << " rx=" << rx << " ry=" << ry << " keys=" << keys << std::endl; } }; int main() { unitree::robot::ChannelFactory::Instance()->Init(0); JoystickHandler handler; unitree::robot::ChannelSubscriber sub(TOPIC_JOYSTICK); sub.InitChannel(std::bind(&JoystickHandler::Callback, &handler, std::placeholders::_1), 1); while (true) { usleep(20000); // 50Hz polling } return 0; } ``` -------------------------------- ### C++ Channel Subscriber for Robot State Data Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Demonstrates subscribing to the 'rt/sportmodestate' DDS topic to receive and process robot state information. It includes a callback handler to access position, IMU, and velocity data. Requires the unitree_robot_sdk2 library. ```cpp #include #include #include #define TOPIC_HIGHSTATE "rt/sportmodestate" class RobotStateMonitor { public: unitree_go::msg::dds_::SportModeState_ state; void StateHandler(const void* message) { state = *(unitree_go::msg::dds_::SportModeState_*)message; // Access robot state data std::cout << "Position: x=" << state.position()[0] << " y=" << state.position()[1] << " z=" << state.position()[2] << std::endl; std::cout << "IMU RPY: roll=" << state.imu_state().rpy()[0] << " pitch=" << state.imu_state().rpy()[1] << " yaw=" << state.imu_state().rpy()[2] << std::endl; std::cout << "Velocity: vx=" << state.velocity()[0] << " vy=" << state.velocity()[1] << std::endl; } }; int main() { unitree::robot::ChannelFactory::Instance()->Init(0, "eth0"); RobotStateMonitor monitor; // Create subscriber with callback handler unitree::robot::ChannelSubscriber subscriber(TOPIC_HIGHSTATE); subscriber.InitChannel(std::bind(&RobotStateMonitor::StateHandler, &monitor, std::placeholders::_1), 1); // Run for 10 seconds receiving messages sleep(10); subscriber.CloseChannel(); return 0; } ``` -------------------------------- ### Robot Trajectory Following with C++ Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Enables the robot to follow a series of waypoints with specified positions and velocities. It generates a sinusoidal path and sends it to the robot for execution. Requires the unitree/robot/go2/sport/sport_client.hpp header. ```cpp #include #include #include class TrajectoryController { public: unitree::robot::go2::SportClient tc; float dt = 0.002; // 500Hz control rate float count = 0; void Control() { count += dt; float vx = 0.3; float delta = 0.06; // Time step between waypoints // Generate sinusoidal path with 30 waypoints std::vector path; for (int i = 0; i < 30; i++) { unitree::robot::go2::PathPoint p; float t = count + i * delta; p.timeFromStart = i * delta; p.x = vx * t; // X position p.y = 0.6 * sin(M_PI * vx * t); // Y position (sinusoidal) p.yaw = 2 * 0.6 * vx * M_PI * cos(M_PI * vx * t); // Heading p.vx = vx; // X velocity p.vy = M_PI * vx * 0.6 * cos(M_PI * vx * t); // Y velocity p.vyaw = -M_PI * vx * 2 * 0.6 * vx * M_PI * sin(M_PI * vx * t); // Angular velocity path.push_back(p); } int32_t ret = tc.TrajectoryFollow(path); if (ret != 0) { std::cerr << "TrajectoryFollow error: " << ret << std::endl; } } }; int main() { unitree::robot::ChannelFactory::Instance()->Init(0); TrajectoryController ctrl; ctrl.tc.SetTimeout(10.0f); ctrl.tc.Init(); auto thread = unitree::common::CreateRecurrentThread( ctrl.dt * 1000000, std::bind(&TrajectoryController::Control, &ctrl) ); while (true) sleep(10); return 0; } ``` -------------------------------- ### Initialize ChannelFactory for DDS Communication Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Initializes the DDS communication layer using ChannelFactory. This singleton must be called before any other DDS operations. It requires a domain ID and optionally a network interface for configuration. ```cpp #include int main(int argc, char** argv) { // Initialize with domain ID 0 and network interface (e.g., "eth0", "enp2s0") unitree::robot::ChannelFactory::Instance()->Init(0, "eth0"); // Alternative: Initialize with domain ID only (uses default interface) // unitree::robot::ChannelFactory::Instance()->Init(0); // Your robot control code here... // Clean up when done unitree::robot::ChannelFactory::Instance()->Release(); return 0; } ``` -------------------------------- ### Import Unitree SDK2 Library Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/CMakeLists.txt Locates and imports the Unitree SDK2 static library based on the system architecture. It checks for the library's existence and sets up target properties for linking and include directories. ```cmake set(UNITREE_SDK_PATH ${CMAKE_CURRENT_LIST_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}) find_library(UNITREE_SDK_LIB unitree_sdk2 PATHS ${UNITREE_SDK_PATH} NO_DEFAULT_PATH) if (NOT UNITREE_SDK_LIB) message(FATAL_ERROR "Unitree SDK library for the architecture is not found") else () message(STATUS "Unitree SDK library found at: ${UNITREE_SDK_LIB}") endif () message(STATUS "Importing: ${UNITREE_SDK_LIB}") find_package(Threads REQUIRED) add_library(unitree_sdk2 STATIC IMPORTED GLOBAL) set_target_properties(unitree_sdk2 PROPERTIES IMPORTED_LOCATION ${UNITREE_SDK_LIB}) target_link_libraries(unitree_sdk2 INTERFACE ddsc ddscxx Threads::Threads) target_include_directories(unitree_sdk2 INTERFACE $ $) ``` -------------------------------- ### Configure C++ Standard and Build Type Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/CMakeLists.txt Sets the C++ standard to C++17 and configures the default build type to 'Release' if not specified. This ensures modern C++ features are available and optimizes for release builds. ```cmake set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(default_build_type "Release") if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${default_build_type}' as none was specified.") set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif () ``` -------------------------------- ### Channel Publisher: Publishing Custom DDS Messages Source: https://context7.com/unitreerobotics/unitree_sdk2/llms.txt Enables publishing custom messages over DDS topics using the ChannelPublisher template. This is used for sending commands or sensor data to subscribers. Requires ChannelFactory initialization and defines a specific topic. ```cpp #include #include #include #define TOPIC_LOWCMD "rt/lowcmd" int main() { unitree::robot::ChannelFactory::Instance()->Init(0); // Create a publisher for low-level motor commands unitree::robot::ChannelPublisher publisher(TOPIC_LOWCMD); publisher.InitChannel(); // Create and populate command message unitree_go::msg::dds_::LowCmd_ cmd{}; cmd.head()[0] = 0xFE; cmd.head()[1] = 0xEF; cmd.level_flag() = 0xFF; // Configure motor 0 command cmd.motor_cmd()[0].mode() = 0x01; // Servo mode cmd.motor_cmd()[0].q() = 0.5; // Target position (rad) cmd.motor_cmd()[0].dq() = 0.0; // Target velocity (rad/s) cmd.motor_cmd()[0].kp() = 50.0; // Position gain cmd.motor_cmd()[0].kd() = 3.0; // Velocity gain cmd.motor_cmd()[0].tau() = 0.0; // Feedforward torque // Publish message (optional: specify wait time in microseconds) bool success = publisher.Write(cmd, 0); publisher.CloseChannel(); return 0; } ``` -------------------------------- ### Enable PR Mode and Generate Sinusoidal Trajectory (C++) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/h1/README_zh.md This C++ code snippet demonstrates how to enable the 'PR mode' for ankle control and generate sinusoidal trajectories for the Pitch and Roll joints of both the left and right feet. It defines maximum angles and uses cosine and sine functions to create desired positions over time. This is a core part of the ankle tracking experiment. ```c++ // [Stage 2]: swing ankle's PR mode_ = PR; // Enable PR mode // generate sin/cos trajectory double max_P = 0.25; // [rad] double max_R = 0.25; // [rad] double t = time_ - duration_; double L_P_des = max_P * std::cos(2.0 * M_PI * t); double L_R_des = max_R * std::sin(2.0 * M_PI * t); double R_P_des = max_P * std::cos(2.0 * M_PI * t); double R_R_des = -max_R * std::sin(2.0 * M_PI * t); ``` -------------------------------- ### Set Ankle Joint Commands in PR Mode (C++) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/h1/README_zh.md This C++ code configures the low-level command structure for the Unitree H1_2 robot's ankle joints when operating in PR mode. It sets the target positions (q), velocities (dq), stiffness (kp), damping (kd), and feedforward torque (tau) for the LeftAnklePitch, LeftAnkleRoll, RightAnklePitch, and RightAnkleRoll joints. This code is crucial for executing the desired joint movements during the tracking experiment. ```c++ // update ankle joint position targets float Kp_Pitch = 80; float Kd_Pitch = 1; float Kp_Roll = 80; float Kd_Roll = 1; dds_low_command.motor_cmd().at(4).q() = L_P_des; // 4: LeftAnklePitch dds_low_command.motor_cmd().at(4).dq() = 0; dds_low_command.motor_cmd().at(4).kp() = Kp_Pitch; dds_low_command.motor_cmd().at(4).kd() = Kd_Pitch; dds_low_command.motor_cmd().at(4).tau() = 0; dds_low_command.motor_cmd().at(5).q() = L_R_des; // 5: LeftAnkleRoll dds_low_command.motor_cmd().at(5).dq() = 0; dds_low_command.motor_cmd().at(5).kp() = Kp_Roll; dds_low_command.motor_cmd().at(5).kd() = Kd_Roll; dds_low_command.motor_cmd().at(5).tau() = 0; dds_low_command.motor_cmd().at(10).q() = R_P_des; // 10: RightAnklePitch dds_low_command.motor_cmd().at(10).dq() = 0; dds_low_command.motor_cmd().at(10).kp() = Kp_Pitch; dds_low_command.motor_cmd().at(10).kd() = Kd_Pitch; dds_low_command.motor_cmd().at(10).tau() = 0; dds_low_command.motor_cmd().at(11).q() = R_R_des; // 11: RightAnkleRoll dds_low_command.motor_cmd().at(11).dq() = 0; dds_low_command.motor_cmd().at(11).kp() = Kp_Roll; dds_low_command.motor_cmd().at(11).kd() = Kd_Roll; dds_low_command.motor_cmd().at(11).tau() = 0; ``` -------------------------------- ### Print Desired and Measured Joint Values (C++) Source: https://github.com/unitreerobotics/unitree_sdk2/blob/main/example/h1/README_zh.md This C++ code snippet retrieves and prints the desired (des) and measured (m) values for the Pitch and Roll joints of both the left and right ankles. It reads the current state of motors 4, 5, 10, and 11, which correspond to LeftAnklePitch, LeftAnkleRoll, RightAnklePitch, and RightAnkleRoll respectively. This output is used to evaluate the tracking performance of the PR mode control. ```c++ float L_P_m = low_state_.motor_state().at(4).q(); float L_R_m = low_state_.motor_state().at(5).q(); float R_P_m = low_state_.motor_state().at(10).q(); float R_R_m = low_state_.motor_state().at(11).q(); printf("%f,%f,%f,%f,%f,%f,%f,%f\n", L_P_des, L_P_m, L_R_des, L_R_m, R_P_des, R_P_m, R_R_des, R_R_m); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.