# Table of Contents - [Home | Berkeley Humanoid Lite Docs](#home-berkeley-humanoid-lite-docs) - [Preparing the Tools | Berkeley Humanoid Lite Docs](#preparing-the-tools-berkeley-humanoid-lite-docs) - [Releases | Berkeley Humanoid Lite Docs](#releases-berkeley-humanoid-lite-docs) - [Getting Started with Hardware | Berkeley Humanoid Lite Docs](#getting-started-with-hardware-berkeley-humanoid-lite-docs) - [Materials and Parts (BOM) | Berkeley Humanoid Lite Docs](#materials-and-parts-bom-berkeley-humanoid-lite-docs) - [Building the Actuator | Berkeley Humanoid Lite Docs](#building-the-actuator-berkeley-humanoid-lite-docs) - [3D Printing Instructions | Berkeley Humanoid Lite Docs](#3d-printing-instructions-berkeley-humanoid-lite-docs) - [Getting Started with Software | Berkeley Humanoid Lite Docs](#getting-started-with-software-berkeley-humanoid-lite-docs) - [Software Development Environment Overview | Berkeley Humanoid Lite Docs](#software-development-environment-overview-berkeley-humanoid-lite-docs) - [lerobot Integration | Berkeley Humanoid Lite Docs](#lerobot-integration-berkeley-humanoid-lite-docs) - [Flashing the Motor Controllers | Berkeley Humanoid Lite Docs](#flashing-the-motor-controllers-berkeley-humanoid-lite-docs) - [Building the Robot | Berkeley Humanoid Lite Docs](#building-the-robot-berkeley-humanoid-lite-docs) - [In-depth Contents | Berkeley Humanoid Lite Docs](#in-depth-contents-berkeley-humanoid-lite-docs) - [Sim2sim Validation | Berkeley Humanoid Lite Docs](#sim2sim-validation-berkeley-humanoid-lite-docs) - [Training Environment | Berkeley Humanoid Lite Docs](#training-environment-berkeley-humanoid-lite-docs) - [Motion Capture System | Berkeley Humanoid Lite Docs](#motion-capture-system-berkeley-humanoid-lite-docs) - [The On-board Computer | Berkeley Humanoid Lite Docs](#the-on-board-computer-berkeley-humanoid-lite-docs) - [Motor Controller Firmware Execution Timing Information | Berkeley Humanoid Lite Docs](#motor-controller-firmware-execution-timing-information-berkeley-humanoid-lite-docs) - [Syncing Files From Training Server | Berkeley Humanoid Lite Docs](#syncing-files-from-training-server-berkeley-humanoid-lite-docs) - [IMU Comparision | Berkeley Humanoid Lite Docs](#imu-comparision-berkeley-humanoid-lite-docs) - [Joint ID Mapping | Berkeley Humanoid Lite Docs](#joint-id-mapping-berkeley-humanoid-lite-docs) - [CAN Communication | Berkeley Humanoid Lite Docs](#can-communication-berkeley-humanoid-lite-docs) - [Exporting Robot Description Files from Onshape | Berkeley Humanoid Lite Docs](#exporting-robot-description-files-from-onshape-berkeley-humanoid-lite-docs) - [Training Environment Coding Convention | Berkeley Humanoid Lite Docs](#training-environment-coding-convention-berkeley-humanoid-lite-docs) - [Contribute | Berkeley Humanoid Lite Docs](#contribute-berkeley-humanoid-lite-docs) - [Motor Characterization | Berkeley Humanoid Lite Docs](#motor-characterization-berkeley-humanoid-lite-docs) - [Field Oriented Control (FOC) Operation | Berkeley Humanoid Lite Docs](#field-oriented-control-foc-operation-berkeley-humanoid-lite-docs) --- # Home | Berkeley Humanoid Lite Docs [**Website**](https://lite.berkeley-humanoid.org/) | [**arXiv**](https://arxiv.org/abs/2504.17249) | [**Paper**](https://lite.berkeley-humanoid.org/static/paper/demonstrating-berkeley-humanoid-lite.pdf) | [**Video**](https://youtu.be/5qgEJpEf3pQ) | [**Documentation**](https://berkeley-humanoid-lite.gitbook.io/docs) | [**Code**](https://github.com/HybridRobotics/Berkeley-Humanoid-Lite) **Berkeley Humanoid Lite** is an open-source, sub-$5,000 humanoid robot featuring modular 3D-printed gearboxes and widely available components, designed to democratize and advance humanoid robotics research. This website contains documentation on helping you build your own version of the robot and setting up the corresponding software environment to perform locomotion and teleoperated manipulation on the robot. During the development of the robot, we encountered numerous bugs and challenges. In the _In-depth Contents_ section, we document our effort of understanding the system and the steps we took to resolve these problems. We hope this serves as a valuable resource for the community. If you have any questions or comments, please reach out to us by either [creating a Github Issue](https://github.com/HybridRobotics/Berkeley-Humanoid-Lite/issues/new) or joining our community! [](https://berkeley-humanoid-lite.gitbook.io/docs#warning) ⚠ **WARNING** ----------------------------------------------------------------------------- This is not just a software project. It includes designs for high power electronics. It has not yet burned down any UC Berkeley labs or anyone's houses, but there are no guarantees : ) Please follow all steps with extra caution. [NextReleases](https://berkeley-humanoid-lite.gitbook.io/docs/releases) Last updated 1 month ago This site uses cookies to deliver its service and to analyze traffic. By browsing this site, you accept the [privacy policy](https://policies.gitbook.com/privacy/cookies) . AcceptReject --- # Preparing the Tools | Berkeley Humanoid Lite Docs Berkeley Humanoid Lite is designed for ease of build and ease of use. You only need a desktop-level 3D printer and a few common workshop tools to get started. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools#id-3d-printer) 3D Printer You can print Berkeley Humanoid Lite on any desktop 3D printer with a build volume of at least 200 x 200 x 200 mm. We recommend the [Bambu Lab X1C Carbon](https://us.store.bambulab.com/products/x1-carbon) for its reliability and performance. Alternatively, the [Creality Ender-3 V3 SE](https://www.creality.com/products/creality-ender-3-v3-se) has also been successfully tested and used. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools#soldering-iron) Soldering Iron A soldering iron is required to connect the electronic components. We found the [SUGON A9 210](https://www.amazon.com/dp/B09QG887ZD) to be a reliable and affordable choice. Additionally, when installing heat inserts into your 3D-printed parts, a heat insert stand such as [this model](https://www.amazon.com/dp/B09SCRYWLR) is highly recommended to ensure a precise, vertical insertion. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools#heated-glue-gun) Heated Glue Gun A heat glue gun will be used to mount the magnet onto the motor shaft. Any standard heat glue gun will work, so you can use the one that is most convenient for you. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools#hex-tool-set) Hex Tool Set The robot primarily uses M3 machine screws with hex heads as the fastener. A hex wrench set that includes sizes M2, M2.5, M3, M4, and M6 will meet most of your assembly needs. For certain electrical components, you will also require a Phillips (+) and a flat-head (-) screwdriver. Often, these screwdrivers are included with the purchased components listed in the next section. [PreviousMaterials and Parts (BOM)](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom) [Next3D Printing Instructions](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions) Last updated 5 months ago --- # Releases | Berkeley Humanoid Lite Docs Last update: 2025-08-23 ### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#bill-of-materials-bom) Bill Of Materials (BOM) [Materials and Parts (BOM)](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#cad-models) CAD Models Berkeley Humanoid Lite [Onshape Link](https://cad.onshape.com/documents/fc6443b1d89dcba950e85b60/w/94a26479973a4098a5884426/e/be3fe37849edbeadc95b9bf8?configuration=default&renderMode=0&uiState=67d7e630bb752737e88992d7) 6512 Actuator [Onshape Link](https://cad.onshape.com/documents/55ab471d620553f44eac2d08/w/ae94825f64e460a99fce5bb9/e/087203429f83a08c02d31a2b?configuration=List_V0PVm1ztiuoOfK%3DDefault&renderMode=0&uiState=67d7e6a395a3c112cb3ba826) 5010 Actuator [Onshape Link](https://cad.onshape.com/documents/192ab9c484f00d0dd33b8f01/w/69525ef69bcb5d7c0991e587/e/cc160d2ca1454a9219f579b3?renderMode=0&uiState=67d7e5a3bb752737e8899291) USB-CAN Adapter Case [Onshape Link](https://cad.onshape.com/documents/dc5bf30cc5a66c2be4659344/w/30c67813e1458487202ea2b9/e/4f46e96306414e60771b645a?renderMode=0&uiState=6860dc70ad1e0048620ab677) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#id-3d-printing-project-files) 3D Printing Project Files Berkeley Humanoid Lite [Bambu Lab MakerWorld Link](https://makerworld.com/en/models/1327260-berkeley-humanoid-lite#profileId-1364871) 6512 Actuator [Bambu Lab MakerWorld Link](https://makerworld.com/en/models/1220823-6512-cycloidal-gear-actuator#profileId-1364989) 5010 Actuator [Bambu Lab MakerWorld Link](https://makerworld.com/en/models/1279205-5010-cycloidal-gear-actuator#profileId-1364911) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#software-repositories) Software Repositories #### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#main-project-repository) Main Project Repository [https://github.com/HybridRobotics/Berkeley-Humanoid-Litegithub.com](https://github.com/HybridRobotics/Berkeley-Humanoid-Lite) #### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#robot-description-assets-urdf-mjcf-usd) Robot Description Assets (URDF, MJCF, USD) [https://github.com/HybridRobotics/Berkeley-Humanoid-Lite-Assetsgithub.com](https://github.com/HybridRobotics/Berkeley-Humanoid-Lite-Assets) #### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#low-level-control-code) Low-level Control Code [https://github.com/HybridRobotics/Berkeley-Humanoid-Lite-Lowlevelgithub.com](https://github.com/HybridRobotics/Berkeley-Humanoid-Lite-Lowlevel) #### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#firmware) Firmware [![Logo](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2Fgithub.com%2Ffluidicon.png&width=20&dpr=4&quality=100&sign=b28aa768&sv=2)GitHub - T-K-233/Recoil-Motor-Controller-BESCGitHub](https://github.com/T-K-233/Recoil-Motor-Controller-BESC) #### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#windows-steamvr-code-for-teleoperation) Windows SteamVR Code for Teleoperation [![Logo](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2Fgithub.com%2Ffluidicon.png&width=20&dpr=4&quality=100&sign=b28aa768&sv=2)GitHub - ucb-bar/SteamVR-BridgeGitHub](https://github.com/ucb-bar/SteamVR-Bridge) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/releases#release-log) Release Log **2025-08-23** Fix 3D print file on MakeWorld, replacing the wrong 5010-5010 housing part and add the missing limit stopper part; add instruction on mounting the magnet on motor shaft; update instruction for 3D printing. **2025-07-07** Fix motor calibration procedure description, add note for rotation direction. **2025-07-05** Add video instruction on ESC firmware configuration, motor calibration, and a demo code driving a single motor. **2025-06-28** Add more wiring instructions, IMU upgrade, and teleoperation instructions; add USB-CAN Adapter Onshape link. **2025-06-26** Add teleoperation code. **2025-06-13** Add instructions to set up environment with uv. **2025-06-09** Add robot wiring diagram, add instructions on connecting cables. **2025-05-29** Add missing 6803 bearing and M2 insert in the humanoid tab in BOM, update M4 hex standoff links. **2025-05-23** Fix incorrect bearing description in BOM (swapped MR106-2RS and 6701-2RS). **2025-05-21** Fix MakerWorld .3mf files of the 6512 actuator. **2025-04-28** Initial release. [PreviousHome](https://berkeley-humanoid-lite.gitbook.io/docs) [NextGetting Started with Hardware](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware) Last updated 8 days ago --- # Getting Started with Hardware | Berkeley Humanoid Lite Docs This tutorial section will introduce the hardware aspect of Berkeley Humanoid Lite. The **Materials and Parts** page lists the bill-of-material (BOM) of the robot. Example prices and purchasing links from online vendors are also included as a reference. [Materials and Parts (BOM)](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom) **Preparing the Tools** page walks you through the necessary tools to build your own robot. We provide our selection of tools we used during the building process for your convenience. [Preparing the Tools](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools) The **3D Printing Instructions** page documents the 3D printer settings to build reliable structural components. [3D Printing Instructions](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions) Lastly, we provide a detailed **Step-by-step Assembly Instructions** to guide you build actuators and integrates the actuators into a working robot. [Building the Actuator](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator) [PreviousReleases](https://berkeley-humanoid-lite.gitbook.io/docs/releases) [NextMaterials and Parts (BOM)](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom) Last updated 5 months ago --- # Materials and Parts (BOM) | Berkeley Humanoid Lite Docs [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom#stock-components) Stock Components ----------------------------------------------------------------------------------------------------------------------------------------------- We summarized the components used to build the actuator and the entire robot in the Google sheet shown below. For your convenience, we have provided purchase links from Amazon and Taobao. However, feel free to source components from any vendors that best suit your location and preferences. The original document can be accessed with [this link](https://docs.google.com/spreadsheets/d/1AQEHcH_nPkXYfor2-h7bwNIUMmsePtAm53epnsWgZXc/edit?usp=sharing) . ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/materials-and-parts-bom#pla-filament) PLA filament The Berkeley Humanoid Lite robot is designed to be printed using standard PLA filament. Two recommended options are: * [Bambu Lab PLA Basic Filament](https://us.store.bambulab.com/products/pla-basic-filament) * [Hatchbox PLA Filament](https://www.amazon.com/dp/B00J0GMMP6) [PreviousGetting Started with Hardware](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware) [NextPreparing the Tools](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools) Last updated 4 months ago --- # Building the Actuator | Berkeley Humanoid Lite Docs Now that we have gathered all the necessary tools and parts, we are ready to begin the assembly process. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#preparing-the-magnetic-encoder) Preparing the magnetic encoder ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- We need to change the configuration of the AS5600 magnetic encoder by swapping out a few resistors on the board. Please follow [this tutorial](https://notes.tk233.xyz/electrical/as5600-modification) or the video below to perform the modification. After moving the resistors, also solder the VCC, GND, SDA, and SCL wires on the corresponding pads. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FhJAPRb6HDovzzyY08Dzo%252FWeixin%2520Image_20250421131455.jpg%3Falt%3Dmedia%26token%3D7e4c87b5-f867-41c5-9422-6b9c6ba9e4bc&width=768&dpr=4&quality=100&sign=b6273076&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FvjD2iiktkykhIifWByKe%252FWeixin%2520Image_20250421131449.jpg%3Falt%3Dmedia%26token%3D303abb11-c457-477d-a483-bccaaa85538a&width=768&dpr=4&quality=100&sign=506f082f&sv=2) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#preparing-the-motor) Preparing the motor --------------------------------------------------------------------------------------------------------------------------------------------------- Use some hot glue to stick the magnet to the shaft of the motor rotor. The image below shows an example for the 5010 motor. For M6C12 motor, instead of the clip, it uses a screw at the end of the shaft to hold everything together, but the procedure to mount the magnet is the same. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#note) Note --------------------------------------------------------------------------------------------------------------------- Be sure to use the magnet that comes with the encoder. These magnet are magnetically charged along the radial axis, while normal round magnets are charged along the cylinder axis and does not work with the encoder. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FsvWkpxzukaJTy8lQRqhD%252FIMG_0198.jpg%3Falt%3Dmedia%26token%3D7846f6f3-717d-4431-a1c5-670f005e14f1&width=768&dpr=4&quality=100&sign=a20f2c6e&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FM1qLqPRuttnW2ia4IISe%252FIMG_0199.jpg%3Falt%3Dmedia%26token%3D80b2a74a-208e-477c-8458-243212cf612b&width=768&dpr=4&quality=100&sign=d0496400&sv=2) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#assembling-the-actuator) Assembling the actuator ----------------------------------------------------------------------------------------------------------------------------------------------------------- Please follow this video tutorial to assemble the actuator. [https://youtu.be/CHPVXL-SsSoyoutu.be](https://youtu.be/CHPVXL-SsSo) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#soldering) Soldering ------------------------------------------------------------------------------------------------------------------------------- Connect the encoder, motor, and the motor controller together according to the following wiring diagram. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252F9GlAsf2bQZYjzWaxDpmB%252Fimage.png%3Falt%3Dmedia%26token%3Df26695cc-e33d-4aff-9fdd-24c4a8900771&width=768&dpr=4&quality=100&sign=74be794&sv=2) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#warning) Warning --------------------------------------------------------------------------------------------------------------------------- The CAN port solder pads on the ECS are _very fragile_ and very susceptible to breaking off the FR4 base layer. Please be extra cautious when soldering and handling it. Do not apply excessive force on the cables and the pads. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#hint) Hint The solder pads of the encoder and CAN are tricky to work with. It requires some degrees of familarity of soldering. Our suggestion is that adding more flux makes it easier to have a more solid solder joint. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#cable-selection) Cable selection ------------------------------------------------------------------------------------------------------------------------------------------- For power cables, we are using **14 AWG** (14 Gauge) stranded silicone wire. The color coding convension is white/red for positive, and black for ground. For CAN cables, we are using **30 AWG** (30 Gauge) stranded silicone wire. The color coding convension is yellow for CAN-H and SDA, green for CAN-L and SCL. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator#results) Results --------------------------------------------------------------------------------------------------------------------------- Here are some photos of the finished motor controller for your reference: ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FCpICav50nglnuySrgefg%252F1000008386.jpg%3Falt%3Dmedia%26token%3D070f5426-f505-441e-96c4-55c32f4dc997&width=768&dpr=4&quality=100&sign=becf69b7&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FIv46wcUmYJJrOJv4cHun%252F1000008385.jpg%3Falt%3Dmedia%26token%3D31ed84b9-c8ec-47ea-8021-a37035dfd57f&width=768&dpr=4&quality=100&sign=a1ecaa8d&sv=2) [Previous3D Printing Instructions](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions) [NextFlashing the Motor Controllers](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers) Last updated 8 days ago --- # 3D Printing Instructions | Berkeley Humanoid Lite Docs [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#files) Files -------------------------------------------------------------------------------------------------------------------------- Please refer to the Releases page for the latest release of CAD model and 3D printing project files. [Releases](https://berkeley-humanoid-lite.gitbook.io/docs/releases) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#print-settings) Print settings -------------------------------------------------------------------------------------------------------------------------------------------- The following parameters are tuned for the Bambu Lab X1C 3D Printer. Additional modifications might be required to fit your own printer's characteristics. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#printing-the-actuator) Printing the actuator ---------------------------------------------------------------------------------------------------------------------------------------------------------- ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#actuator-housing-profile) Actuator Housing Profile For the housing, output shaft, and the motor shell, the Actuator Housing Profile should be used. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FvusXhoveJjpvNLk1ZGrU%252Fimage.png%3Falt%3Dmedia%26token%3D69beef5c-4236-4c25-b58d-cb5e88929a30&width=768&dpr=4&quality=100&sign=7f62dda6&sv=2) Quality [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-quality) Strength [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-strength) Speed [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-speed) Support [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-support) Others [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-others) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fs33GZrOJTQJUFByxtEpT%252Fimage.png%3Falt%3Dmedia%26token%3Dd9ca1840-221a-4f8d-848d-153820a41019&width=768&dpr=4&quality=100&sign=763985be&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fz2QULcU68FMGHI99sE2b%252Fimage.png%3Falt%3Dmedia%26token%3D162702b2-e973-407a-aa36-757f50d31355&width=768&dpr=4&quality=100&sign=8f214af9&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FIaut5ZnDsdCB39X5IpQI%252Fimage.png%3Falt%3Dmedia%26token%3D3a379021-0e88-426d-811d-715aca3f5109&width=768&dpr=4&quality=100&sign=157b8de3&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FCQkELasL5HBslGIsWBji%252Fimage.png%3Falt%3Dmedia%26token%3D769e06ed-bc72-4ab4-b26a-d602d1749208&width=768&dpr=4&quality=100&sign=7136618&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FpljBVV4OZ34eKUAGl1an%252Fimage.png%3Falt%3Dmedia%26token%3D47af75e2-dc25-4bfb-9445-358e1dd9f72c&width=768&dpr=4&quality=100&sign=a3145bb3&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#actuator-shaft-profile) Actuator Shaft Profile For the cycloidal disk, input shaft, motor shaft, and the spacers, the Actuator Shaft Profile should be used. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FqrhJphIzQWiD3ukbLYFk%252Fimage.png%3Falt%3Dmedia%26token%3D2c593696-8549-414a-bf8e-62b2023a6f9e&width=768&dpr=4&quality=100&sign=10c5c5a2&sv=2) Quality [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-quality-1) Strength [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-strength-1) Speed [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-speed-1) Support [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-support-1) Others [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#tab-others-1) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fr8gKzwCvQ3Lz7w6OzhQN%252Fimage.png%3Falt%3Dmedia%26token%3D150d6b3c-4b89-457d-bb56-a57f51d525ae&width=768&dpr=4&quality=100&sign=619f12bb&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FXl6UdPfZJW0oVj7b9caZ%252Fimage.png%3Falt%3Dmedia%26token%3D93ae7c9a-e25c-42dd-baef-bce30cfab250&width=768&dpr=4&quality=100&sign=b44a0a74&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FAwnOdgiM4l6YppFZ68QF%252Fimage.png%3Falt%3Dmedia%26token%3Dbd3ad8d1-4aa6-416b-a389-42dd52f4a14b&width=768&dpr=4&quality=100&sign=6270c00e&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FTSUOzuo4OfvfbV8mMoyV%252Fimage.png%3Falt%3Dmedia%26token%3D71b53a18-2263-4ca9-a96c-ae38622d0ada&width=768&dpr=4&quality=100&sign=d7c7dfaa&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FPr9EWZcZYJb4ZOg7dQEG%252Fimage.png%3Falt%3Dmedia%26token%3D14a50c8a-ce20-4a4b-944e-163cec92c10e&width=768&dpr=4&quality=100&sign=4af1502&sv=2) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/3d-printing-instructions#printing-the-rest-of-the-robot) Printing the rest of the robot ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Similar principle applies to the rest of the robot. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252F4q10X70BN5rvtf9U4kND%252Fimage.png%3Falt%3Dmedia%26token%3D53c48d00-bbae-4943-bbe5-83e9c61f9b37&width=768&dpr=4&quality=100&sign=c102e30a&sv=2) Parts on the Upper Body and Lower Body plates need to be printed twice in mirrored setting to assemble the two arms and two legs. This can be achieved by right-clicking the part and selet "mirror along X axis". The structural parts does not require the high precision as the actuator modules, so they can be printed at a faster speed setting. [PreviousPreparing the Tools](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/preparing-the-tools) [NextBuilding the Actuator](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator) Last updated 8 days ago --- # Getting Started with Software | Berkeley Humanoid Lite Docs This tutorial section will introduce the software aspect of Berkeley Humanoid Lite. In the **Software Development Environment Overview** page, we give an overview of the components of the software development environment. [Software Development Environment Overview](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/software-development-environment-overview) Then, we introduce the procedure to set up the Isaac Lab and our Berkeley Humanoid Robot Extension Python module in the **Training Environment** page. [Training Environment](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment) In the **Sim2sim Validation** page, we show the steps to test and validate a trained policy in the MuJoCo simulator. [Sim2sim Validation](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation) For policy deployment onto real-world robot, we will need to set up the deployment environment on the on-board computer. The instructions are covered in **The On-board Computer** page. [The On-board Computer](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer) The **Motion Capture System** page introduces the steps to set up the SteamVR motion tracking system we used for teleoperated manipulation tasks. [Motion Capture System](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system) [PreviousBuilding the Robot](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot) [NextSoftware Development Environment Overview](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/software-development-environment-overview) Last updated 5 months ago --- # Software Development Environment Overview | Berkeley Humanoid Lite Docs [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/software-development-environment-overview#directory-walkthrough) Directory walkthrough --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The [HybridRobotics/Berkeley-Humanoid-Lite](https://github.com/hybridrobotics/berkeley-humanoid-lite) repository will be our working directory for everything. Inside the directory, there are three packages: `source/berkeley_humanoid_lite/` contains the IsaacLab environment and task definitions. `source/berkeley_humanoid_lite_assets/` contains robot descriptions (URDF, MJCF, and USD) and the script to export these description files from Onshape project. `source/berkeley_humanoid_lite_lowlevel/` contains the lowlevel code running on the real robot. Only contents inside this folder is required to copy to the robot. We will cover that part in a later section. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/software-development-environment-overview#code-editor) Code Editor ------------------------------------------------------------------------------------------------------------------------------------------------------- We recommend using [Cursor](https://www.cursor.com/en) / [VisualStudio Code](https://code.visualstudio.com/) as the editor. [PreviousGetting Started with Software](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software) [NextTraining Environment](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment) Last updated 4 months ago --- # lerobot Integration | Berkeley Humanoid Lite Docs \[Coming soon~\] [PreviousMotion Capture System](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system) [NextIn-depth Contents](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents) Last updated 4 months ago --- # Flashing the Motor Controllers | Berkeley Humanoid Lite Docs We are going to use [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html) to flash the motor controllers. [![Logo](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2Fwww.st.com%2Fetc%2Fclientlibs%2Fst-site%2Fmedia%2Fapp%2Fimages%2Ffavicon-32.png&width=20&dpr=4&quality=100&sign=c257b477&sv=2)STM32CubeIDE - STMicroelectronicsSTMicroelectronics](https://www.st.com/en/development-tools/stm32cubeide.html) After setting up STM32CubeIDE, download the firmware codebase from the [repository](https://github.com/T-K-233/Recoil-Motor-Controller-BESC) . Copy git clone https://github.com/T-K-233/Recoil-Motor-Controller-BESC.git [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#initial-flash-configuration) Initial flash configuration ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Because we are using the internal Flash of STM32 to store our motor configuration parameters, we need to configure the Flash protection to allow us to read and write to the pages. Go to `Core/Inc/motor_controller_conf.h` and set the `FIRST_TIME_BOOTUP` flag to be 1. Copy /** * First Time Bootup Flag: * If this is the first time the device is programmed, set this flag to 1 to configure Flash option byte. */ - #define FIRST_TIME_BOOTUP 0 // Set to 1 for the first-time bootup routine, 0 for normal operation + #define FIRST_TIME_BOOTUP 1 // Set to 1 for the first-time bootup routine, 0 for normal operation Connect the motor controller to the computer via the Micro USB port on the controller board. STM32CubeIDE should automatically detect the new device. Then, click the "Run" button. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Frh9nXPnbeLx6h13pKJaO%252Fimage.png%3Falt%3Dmedia%26token%3Db6374ae4-fd69-4de7-8a89-76916dc07f90&width=768&dpr=4&quality=100&sign=7dc7a398&sv=2) For brand new boards, it will prompt a ST-LINK debugger firmware update. Click accept and perform firmware upgrade according to its instructions. After that, click "Run" again. After flashing with the initial configuration program, power-cycle the board by unplug and plug in again the USB cable. Then, change the `FIRST_TIME_BOOTUP` flag back to 0. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#configuring-actuator-parameters) Configuring actuator parameters ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Now we need to load the correct actuator parameters into the Flash. The fields that needs to be configured is also in this header file. First, configure the CAN ID according to the [Joint ID Mapping](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/joint-id-mapping) . Then, scroll down and uncomment the corresponding motor type. Set `LOAD_ID_FROM_FLASH` and `LOAD_CONFIG_FROM_FLASH` flags to 0 so that our program can override the default random values in the Flash. Copy /** * Device CAN ID: * This macro defines the CAN (Controller Area Network) ID of the device. * The CAN ID is a unique identifier for the device on the CAN bus. * The value should be set in range [1, 63]. */ - #define DEVICE_CAN_ID 1 + #define DEVICE_CAN_ID /** * First Time Bootup Flag: * If this is the first time the device is programmed, set this flag to 1 to configure Flash option byte. */ #define FIRST_TIME_BOOTUP 0 // Set to 1 for the first-time bootup routine, 0 for normal operation /** * Load ID from Flash Flag: * This flag specifies whether the device should load the ID configuration from Flash memory. */ - #define LOAD_ID_FROM_FLASH 1 // Set to 1 to load ID config from Flash, 0 to load default values + #define LOAD_ID_FROM_FLASH 0 // Set to 1 to load ID config from Flash, 0 to load default values /** * Load Config from Flash Flag: * This flag specifies whether the device should load the configuration settings from Flash memory. * It excludes loading motor flux offset and CAN ID. */ - #define LOAD_CONFIG_FROM_FLASH 1 // Set to 1 to load config settings (everything except + #define LOAD_CONFIG_FROM_FLASH 0 // Set to 1 to load config settings (everything except // motor flux offset and can id) from Flash, 0 to load default values /** * Load Calibration from Flash Flag: * This flag indicates whether the device should load the encoder flux offset settings from Flash memory. */ #define LOAD_CALIBRATION_FROM_FLASH 1 // Set to 1 to load calibration settings, 0 to load default values /** ======== Motor Selection ======== **/ // uncomment the motor that you are using //#define MOTORPROFILE_MAD_M6C12_150KV //#define MOTORPROFILE_MAD_5010_110KV //#define MOTORPROFILE_MAD_5010_310KV //#define MOTORPROFILE_MAD_5010_370KV Load the program into the motor controller by clicking "Run" button. To be extra safe, after this second flashing, do the unplug and plug again to make sure that flash option is successfully loaded. The LED should blink at around 1 Hz, indicating that our program is loaded and executing correctly. Finally, change the configuration flags back to 1 and click "Run" to flash one last time. At this point, the "Run" button should be clicked four times, and both the firmware and configuration parameters should be loaded to the motor controller. Here is a video walkthrough of the procedure: [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#calibrate-the-actuator) Calibrate the actuator ------------------------------------------------------------------------------------------------------------------------------------------------------------------ The easiest way to do this is to directly use the on-board computer on the robot after finishing [The On-board Computer](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer) section. Connect the CAN bus of the actuator to the computer through the USB-CAN adapter. Then, power on the actuator. Before running the python script, you need to run this script to start the socket CAN transport on the computer: Copy sudo ip link set can0 up type can bitrate 1000000 Then, check the connection to the actuator by running Copy uv run ./source/berkeley_humanoid_lite_lowlevel/scripts/motor/ping.py -c can0 -i 1 The `-c` argument specifies which CAN transport to use (here we are using `can0`, the number increases as we connect more USB-CAN adapter devices), and the `-i` argument specifies the device's CAN ID. If everthing goes well, the script should print "Motor is online": ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fh1LjJp45umuzpMyod7bd%252Fimage.png%3Falt%3Dmedia%26token%3De83c2b9d-9077-4eb3-af9a-86178012f719&width=768&dpr=4&quality=100&sign=672a215f&sv=2) If the script prints "Motor is offline", double check your signal cable connection, power, and CAN ID settings. Now, we can run this program to calibrate the electrical position offset. Make sure nothing is attached to the actuator and it is free to spin. Copy uv run ./source/berkeley_humanoid_lite_lowlevel/scripts/motor/calibrate_electrical_offset.py -c can0 -i 1 [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#warning) WARNING ------------------------------------------------------------------------------------------------------------------------------------ The motor will spin and draw quite amount of current (~ 1 A from power supply). Make sure the power cables are connected properly and the actuator is free to spin. The motor will slowly increase the holding torque until the phase current reaches the target value, then rotate counter-clockwise (CCW) for one full mechanical rotation, and finally rotate back clockwise (CW) for one rotation. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#note) Note ------------------------------------------------------------------------------------------------------------------------------ If the rotation direction is flipped (first rotate CW, and then CCW), you can do one of the following to correct this: 1) swap any two of the three motor phase wires; or 2) change the [MOTOR\_PHASE\_ORDER](https://github.com/T-K-233/Recoil-Motor-Controller-BESC/blob/main/Recoil-Motor-Controller-B-G431B-ESC1/Core/Inc/motor_controller_conf.h#L77) in the firmware to `-1`. Here is a video showcasing the calibration procedure: [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#moving-the-actuator) Moving the actuator ------------------------------------------------------------------------------------------------------------------------------------------------------------ We also provided a simple script to command the actuator to rotate, following a sinosoidal position curve. Use this command to run it: Copy uv run ./source/berkeley_humanoid_lite_lowlevel/scripts/motor/move_actuator.py -c can0 -i 1 [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers#caution) CAUTION ------------------------------------------------------------------------------------------------------------------------------------ The motor will spin. Start with a small kP, kD, and torque limit value to gain confidence on how the actuator will behave. If anything unexpected happens, press Ctrl+C to kill the program to stop the actuator. This video demonstrate how it looks: [PreviousBuilding the Actuator](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-actuator) [NextBuilding the Robot](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot) Last updated 1 month ago --- # Building the Robot | Berkeley Humanoid Lite Docs Please follow these video tutorials to assemble the robot. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#arm) Arm ---------------------------------------------------------------------------------------------------------------- [https://youtu.be/zsb3M3H1sr4youtu.be](https://youtu.be/zsb3M3H1sr4) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#leg) Leg ---------------------------------------------------------------------------------------------------------------- [https://youtu.be/aRtWpbteiNAyoutu.be](https://youtu.be/aRtWpbteiNA) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#entire-robot) Entire robot ---------------------------------------------------------------------------------------------------------------------------------- [https://youtu.be/SIGD8I-hwG8youtu.be](https://youtu.be/SIGD8I-hwG8) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#wiring) Wiring ---------------------------------------------------------------------------------------------------------------------- After building the mechanical structure of the robot, connect the electrical components following this wiring diagram: ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fr8xkUZh0T5OkQwgYbeAf%252Fimage.png%3Falt%3Dmedia%26token%3Dda06135f-f9a3-4b37-9b35-b9700deaeca6&width=768&dpr=4&quality=100&sign=327b5f64&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#connecting-can-bus-to-the-usb-can-adapter) Connecting CAN bus to the USB-CAN Adapter The cables can be directly attache to the screw terminal on the USB-CAN adapter board. The ordering is CAN-L, CAN-H, GND. The signal names are also labeled at the back side of the PCB. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FK9u26svmXTtBuGJmr7yq%252F1000008391.jpg%3Falt%3Dmedia%26token%3D9fd5bc4d-a987-4c26-8359-bc7957646b71&width=768&dpr=4&quality=100&sign=20ad5a4d&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FFHMAMzHRXDpGE8D8UEK8%252F1000008392.jpg%3Falt%3Dmedia%26token%3D37219e61-4773-49f3-a33d-e4155e6f3335&width=768&dpr=4&quality=100&sign=c0dc8579&sv=2) Photo of the connection without the 3D printed case for better clarity ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#joining-the-cables-together) Joining the cables together There are multiple ways to join the signal and power cables together. We provide our recommended ways for you reference. For signal cables, we recommend directly solder them together and protect the solder joints with heat shrink tubes. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FIDB8mdVoYMNtbP2bcusG%252F1000008030.jpg%3Falt%3Dmedia%26token%3D53060430-3b84-4088-a0ef-6318d8d2dcf7&width=768&dpr=4&quality=100&sign=92889dd8&sv=2) When first connecting power cables together, for easier debugging, the WAGO connectors can be used to quickly joining and detaching each actuators to the main power bus without soldering. They are available in multiple types, and we use both the two, three, and five ports on the robot. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FdDkQnlM0EDi4nBBRfsTu%252F1000008032.jpg%3Falt%3Dmedia%26token%3D6a6dd1ef-f5d5-4296-b010-083caf7fac1d&width=768&dpr=4&quality=100&sign=e85a4e66&sv=2) For a more permanant build, we recommend to solder the cables together directly. [This video](https://youtu.be/4xUBRMgcVhc?t=437&si=RwDLI2K0Sdax4TTa) by Will Donaldson provides a good guide on how to solder these thicker cables. Between the actuators, the cables can be connected with XT30 and XT60 connectors. We use XT60 to connect the main cable together, with each actuator connected to this main power bus using XT30 connectors. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FC8ynFZL5eJhuQ2mzY2ZX%252F1000008031.jpg%3Falt%3Dmedia%26token%3D31cc0a51-3a30-432a-80cf-8ee8a7b259e0&width=768&dpr=4&quality=100&sign=3195c5cc&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/building-the-robot#imu-connection) IMU Connection For the original version, we use an Arduino Nano to connect the IMU to the computer. Here are some photos of the connection for your reference. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252F68hu4tcY0FHNR7v25xgt%252F1000008383.jpg%3Falt%3Dmedia%26token%3D862e7d97-a053-4aad-a6a2-986990fdd887&width=768&dpr=4&quality=100&sign=48acca47&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FzrqZfzRqiof3hKkXnK72%252F1000008382.jpg%3Falt%3Dmedia%26token%3De726abdf-0347-46ab-aebd-dbd6c7ad7685&width=768&dpr=4&quality=100&sign=3308f8b5&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FdqQBQhB4k3qm9UF8SK6g%252F1000008384.jpg%3Falt%3Dmedia%26token%3D2f0986e5-04ff-4bc5-8dea-a5a540850eab&width=768&dpr=4&quality=100&sign=89c4c6e5&sv=2) We later found out this [IM10A IMU](https://www.hiwonder.com/products/imu-module?variant=40375875338327) that directly supports USB connection. Hence, we strongly recommend to use this IMU to avoid manually soldering the signal wires. The BOM is also updated to include this component. A detailed performance comparision between these two IMUs is available here: [IMU Comparision](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/imu-comparision) [PreviousFlashing the Motor Controllers](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-hardware/flashing-the-motor-controllers) [NextGetting Started with Software](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software) Last updated 2 months ago --- # In-depth Contents | Berkeley Humanoid Lite Docs During our four-year journey of building the Berkeley Humanoid Robot, we’ve encountered countless challenges—frustrating bugs, unexpected setbacks, and moments of doubt. While many great resources already exist, we felt compelled to document our learnings and discoveries here, hoping they might serve as a meaningful contribution to the robot DIY community. We sincerely wish you never have to battle the same stubborn issues we faced, while working on Berkeley Humanoid Lite and other projects. But if you do, may this guide save you time, ease your frustrations, and remind you that every challenge conquered brings you one step closer to creating something extraordinary. [Previouslerobot Integration](https://berkeley-humanoid-lite.gitbook.io/docs/lerobot-integration) [NextField Oriented Control (FOC) Operation](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation) Last updated 5 months ago --- # Sim2sim Validation | Berkeley Humanoid Lite Docs After finish training the policy, we can first put it into a different physics simulator to validate the policy. This procedure is typically called sim2sim validation. Here, we use [MuJoCo](https://mujoco.org/) as the sim2sim physics engine. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation#controller) Controller ------------------------------------------------------------------------------------------------------------------------------ The sim2sim will read user commands from a gamepad controller, just like what the real robot would do. Plug the joystick controller in the host computer before running the sim2sim script. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation#note) Note ------------------------------------------------------------------------------------------------------------------ Getting USB gamepad controller working in Linux might be tricky. Here are some resources that might be helpful if you run into troubles reading from the joystick: * [https://notes.tk233.xyz/tools/ubuntu/solving-gamepad-not-detected-on-ubuntu-22.04](https://notes.tk233.xyz/tools/ubuntu/solving-gamepad-not-detected-on-ubuntu-22.04) * [https://unix.stackexchange.com/questions/559652/udev-rule-doesnt-trigger-when-usb-gamepad-connected](https://unix.stackexchange.com/questions/559652/udev-rule-doesnt-trigger-when-usb-gamepad-connected) * [https://www.xmodulo.com/change-usb-device-permission-linux.html](https://www.xmodulo.com/change-usb-device-permission-linux.html) * [https://hackaday.com/2009/09/18/how-to-write-udev-rules/](https://hackaday.com/2009/09/18/how-to-write-udev-rules/) [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation#launching-the-mujoco-environment) Launching the MuJoCo environment -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- After everything is set up, we can now test our newly trained policy in MuJoCo! Run this script to launch the sim2sim environment. The Python script creates threads to handle joystick and policy inference. These threads communicate with the main physics simulation thread via UDP, mimicing the real-world deployment scenario. uv [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation#tab-uv) conda [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation#tab-conda) Copy uv run ./scripts/sim2sim/play_mujoco.py --config ./configs/policy_latest.yaml Copy python ./scripts/sim2sim/play_mujoco.py --config ./configs/policy_latest.yaml Replace the file argument after `--config` to test different policies. By default, the policy is trained to follow user command of linear velocity on X (forward-backward) and Y (sideways) axes, and angular velocity on Z (turning). ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FgOwnSk7wmOlQ1aO1nJ3W%252Fimage.png%3Falt%3Dmedia%26token%3D819f2488-487e-4909-a3e0-57b37b33fba6&width=768&dpr=4&quality=100&sign=27bbe50c&sv=2) [PreviousTraining Environment](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment) [NextThe On-board Computer](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer) Last updated 1 month ago --- # Training Environment | Berkeley Humanoid Lite Docs For policy training, we use NVIDIA [Isaac Sim](https://developer.nvidia.com/isaac/sim) and [Isaac Lab](https://developer.nvidia.com/isaac/lab) . The code containing Berkeley Humanoid Lite training environment can be installed as an extension to the Isaac Lab. Some system packages are required by Isaac Lab. We shall install these first. Copy sudo apt install cmake build-essential For managing the Python environment, we support using either uv or conda. uv is recommended for its faster speed, modern dependency resolution, and strict reproducibility. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#setting-up-environment-with-uv) Setting up environment with uv ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ [uv](https://docs.astral.sh/uv/) is an extremely fast Python package and project manager. To set up uv, run this command: Copy wget -qO- https://astral.sh/uv/install.sh | sh Then, simply run this command to install everything Copy uv sync Finally, to activate the environment, do Copy source ./.venv/bin/activate [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#setting-up-environment-with-conda) Setting up environment with conda ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Alternatively, [conda](https://anaconda.org/anaconda/conda) can be used to manage Python packages. First, create a conda environment to contain all the Python packages. Copy conda create -yn berkeley-humanoid-lite python=3.10 conda activate berkeley-humanoid-lite ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#installing-isaac-sim-and-isaac-lab) Installing Isaac Sim and Isaac Lab Please refer to [Issac Lab Documentation](https://isaac-sim.github.io/IsaacLab/main/source/setup/installation/pip_installation.html) for more detailed guidance on installing Isaac Sim and Isaac Lab. Here, we provide the procedure we followed to install on our machines. We have verified this flow on a fresh install of Ubuntu 24.04. Use this command to install Isaac Sim 4.5.0 and Isaac Lab 2.1.0. Copy pip install torch==2.5.1 torchvision==0.20.1 --index-url https://download.pytorch.org/whl/cu121 pip install isaacsim[all,extscache]==4.5.0 --extra-index-url https://pypi.nvidia.com pip install isaaclab[isaacsim,all]==2.1.0 --extra-index-url https://pypi.nvidia.com ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#setting-up-berkeley-humanoid-lite-extension) Setting up Berkeley-Humanoid-Lite extension After installing the Isaac Lab environment, we can proceed to install the Berkeley Humanoid Lite Extension. We start by cloning the project repository. Copy git clone https://github.com/HybridRobotics/Berkeley-Humanoid-Lite.git The project repository contains submodules for robot description and low-level code. The submodules can be initialize with this command. Copy cd Berkeley-Humanoid-Lite git submodule update --init Then, install the modules to IsaacLab environment. Copy pip install -e ./source/berkeley_humanoid_lite/ pip install -e ./source/berkeley_humanoid_lite_assets/ pip install -e ./source/berkeley_humanoid_lite_lowlevel/ There are some additional packages required by our project. Run the following script to install them. Copy pip install -r requirements.txt [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#training-the-policy) Training the policy -------------------------------------------------------------------------------------------------------------------------------------------------- Two tasks are defined in the codebase. `Velocity-Berkeley-Humanoid-Lite-v0` trains a policy that actuates all 22 degrees of freedom on the robot, and `Velocity-Berkeley-Humanoid-Lite-Biped-v0` trains a policy that only controls the 12 degrees of freedom on the leg. To train the policy, run this following command. By default, we train for 6000 iterations, which should take around two hours. uv [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#tab-uv) conda [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#tab-conda) Copy uv run ./scripts/rsl_rl/train.py --task Velocity-Berkeley-Humanoid-Lite-v0 --headless Copy python ./scripts/rsl_rl/train.py --task Velocity-Berkeley-Humanoid-Lite-v0 --headless To view the trained result, run the following command. uv [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#tab-uv-1) conda [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/training-environment#tab-conda-1) Copy uv run ./scripts/rsl_rl/play.py --task Velocity-Berkeley-Humanoid-Lite-v0 --num_envs 16 Copy python ./scripts/rsl_rl/play.py --task Velocity-Berkeley-Humanoid-Lite-v0 --num_envs 16 In addition to get a visualization of the policy, the `play.py` script will also export the trained policy into an ONNX file for deployment. It will also create or update the `configs/policy_latest.yaml` configuration file, which records the parameters that will be used during sim2sim and sim2real deployment. We will see how to use this exported model checkpoint and configuration file in the next section. [PreviousSoftware Development Environment Overview](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/software-development-environment-overview) [NextSim2sim Validation](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation) Last updated 2 months ago --- # Motion Capture System | Berkeley Humanoid Lite Docs To perform teleoperation control, we use the [SteamVR](https://partner.steamgames.com/vrlicensing) motion capture system to detect the user motion. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#note) Note Although it should be supported, we couldn't get the SteamVR working on Ubuntu. Here, we will be using another PC computer running Windows to drive the SteamVR setup. The motion capture data will be then streamed to the robot control system via UDP. Please reach out if you have figured out how to set up the system entirely on Linux systems! [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#setting-up-the-steamvr-tracking-system) Setting up the SteamVR tracking system ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Please refer to the resource on [VIVE resources website](https://www.vive.com/us/support/vive-pro/) for detailed instructions on setting up the SteamVR tracking system. During room calibration, make sure that the calibration arrow is pointed towards the +Y axis of your world coordinate frame. This ensures that the VR world coordinate aligns with our robot's coordinate frame. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#setting-up-the-motion-capture-codebase) Setting up the motion capture codebase ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- On the SteamVR Windows computer, clone the SteamVR-Bridge repository: Copy git clone https://github.com/ucb-bar/SteamVR-Bridge.git We use uv for Python environment management. To install it on Windows, run the following command: Copy powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" Then, create a new Python environment and install the required dependencies. Copy uv venv --python 3.10 uv pip install -r requirements.txt The VR Bridge will read the pose and button input information from the two Vive controllers, and stream the data to the Ubuntu robot computer via UDP communication. Lastly, to establish the communication between the two computers, connect them together with a Ethernet cable, and set the IP address of the two computers with the following configuration: Computer IP Address Windows that connects to the SteamVR stuff 172.28.0.8 Ubuntu that connects to the robot 172.28.0.5 [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#running-the-vr-bridge) Running the VR Bridge ------------------------------------------------------------------------------------------------------------------------------------------------------- To start the VR bridge program, simply run Copy uv run .\run_vr_bridge.py ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#note-1) Note When running the script for the first time, it will automatically launch the SteamVR application. However, SteamVR will need to spend some time to detect and connect to the controllers. This might leads to the Python code unable to retrieve the controller. If this happens, re-run the Python code after SteamVR application is ready. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system#running-the-teleoperation-program) Running the teleoperation program ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To run the teleoperation program, run this command on the Ubuntu computer Copy uv run ./scripts/teleop/run_teleop.py It will launch a MeshCat window that display coordination frame of: * received VR controller pose * robot end effector target pose * current robot end effector pose [PreviousThe On-board Computer](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer) [Nextlerobot Integration](https://berkeley-humanoid-lite.gitbook.io/docs/lerobot-integration) Last updated 2 months ago --- # The On-board Computer | Berkeley Humanoid Lite Docs We are almost done! The last step before running policy on the real robot is to set up the environment on the on-board NUC computer. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#install-ubuntu-22.04) Install Ubuntu 22.04 ----------------------------------------------------------------------------------------------------------------------------------------------------- We find that Ubuntu 22.04 works well with our software and hardware stack on the robot. Follow [Ubuntu tutorial](https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview) to install Ubuntu 22.04 on the NUC computer. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#note) Note --------------------------------------------------------------------------------------------------------------------- To enter BIOS on the BeeLink N95 NUC computer, press XXXX during bootup. [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#install-dependencies) Install Dependencies ----------------------------------------------------------------------------------------------------------------------------------------------------- Copy sudo apt install build-essential cmake net-tools can-utils python3-pip [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#test-connection-with-joint-actuators) Test connection with joint actuators ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- As the first step, we need to initialize the CAN transport on the Linux side. To do this, we have prepared a script: Copy source ./scripts/start_can_transports.sh #### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#note-1) Note Naturally, to stop the transports, you can do: Copy source ./scripts/stop_can_transports.sh To test connection to individual actuator, run this command. Copy python ./berkeley_humanoid_lite_lowlevel/motor/ping.py --port can0 --id 1 `--port` corresponds to the port of the CAN device on linux. With the two arms and legs all connected, it should be `can[0,1,2,3]` `--id` corresponds to the CAN ID of the device. It should be in range `[1..14]`. Alternatively, to test connection to all the motors, run this script. Copy python ./berkeley_humanoid_lite_lowlevel/robot/anyonehere.py [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#test-connection-with-imu) Test connection with IMU ------------------------------------------------------------------------------------------------------------------------------------------------------------- To test connection to the IMU, run this command. Copy python ./berkeley_humanoid_lite_lowlevel/robot/test_imu.py [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#test-connection-with-joystick) Test connection with Joystick ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Run this script to launch the Python program that reads the joystick and broadcast the reading on UDP port. Copy python ./berkeley_humanoid_lite_lowlevel/policy/udp_joystick.py [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#run-everything-together) Run everything together ----------------------------------------------------------------------------------------------------------------------------------------------------------- There are two ways to run the lowlevel code: C codebase and Python codebase. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#c-codebase) C codebase For locomotion tasks, we recommend to use the C codebase for better realtime gaurantee. The C codebase is under `./csrc/` directory. On the on-board computer, do the following: Copy make ./build/real_humanoid [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#real-time-kernel-performance) Real-time kernel performance --------------------------------------------------------------------------------------------------------------------------------------------------------------------- If running into performance issues where the USB-CAN adapter cannot maintain the required communication frequency, we can use the [https://xanmod.org/](https://xanmod.org/) real-time kernel instead. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/the-on-board-computer#python-codebase) Python codebase \[Coming soon\] [PreviousSim2sim Validation](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/sim2sim-validation) [NextMotion Capture System](https://berkeley-humanoid-lite.gitbook.io/docs/getting-started-with-software/motion-capture-system) Last updated 4 months ago --- # Motor Controller Firmware Execution Timing Information | Berkeley Humanoid Lite Docs The high dynamic nature of the motor drive circuit imposes a strict requirement on the realtimeness of the firmware. We must ensure that we can run everything within a single FOC commutation loop. We performed several measurements on the Recoil firmware code running on the motor controller to profile the execution time. The timing information is measured with a Siglent SDS 1202X-E oscilloscope via a GPIO header on the motor controller board. The system clock is configured as 160 MHz. The compiler optimization is set to `-O2`. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#current-control) Current Control ---------------------------------------------------------------------------------------------------------------------------------------------------------------- Entire loop ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#encoder-reading) Encoder reading ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FzI3zqdesBuBPrEc1LOiO%252Fi2c_encoder.png%3Falt%3Dmedia%26token%3De8f78038-0cd9-4d95-9792-73992b1e1f39&width=768&dpr=4&quality=100&sign=b92f7a6d&sv=2) The delta time between issuing **HAL\_I2C\_Master\_Receive\_IT** and receiving the interrupt is 78 us. Hence, the maximum frequency it can run at is 12 kHz. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#clarke-transform) Clarke transform ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FUaS0W0z7rZGMlXO4i706%252FFOC_clarkTransform.png%3Falt%3Dmedia%26token%3Dc0e0f4a8-1260-4334-9bc4-dc4c68381b5b&width=768&dpr=4&quality=100&sign=9a48183a&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#park-transform) Park transform ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FKHRgIYi0NW5RHpkeX8WL%252FFOC_clarkTransform.png%3Falt%3Dmedia%26token%3Dcafd56f5-34ca-40ae-a3ad-668937b883e0&width=768&dpr=4&quality=100&sign=7ebf4c08&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#v_d-v_q-target-calculation) V\_D V\_Q target calculation ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252F4lLh1Cy0KeVjcPuR3WE1%252Fv_dq_target.png%3Falt%3Dmedia%26token%3D31cb2faa-addc-4411-8223-9a6446f21dd8&width=768&dpr=4&quality=100&sign=5a45cad1&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#overmodulation) Overmodulation ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FgS49ndkdnrbUwpLXRC7a%252Fovermodulation.png%3Falt%3Dmedia%26token%3Dd3058276-63a2-4d8f-9493-8734d83c4a6a&width=768&dpr=4&quality=100&sign=a4fe9fea&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#inverse-park-transformation) Inverse park transformation ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FLyMk2Pe6DM1LilC4upj6%252FinvPark.png%3Falt%3Dmedia%26token%3Df20726a1-8ed5-4636-944e-1c41e42971d0&width=768&dpr=4&quality=100&sign=1f987908&sv=2) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information#svpwm) SVPWM ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FFM1LMJeaCoWuJHYWBofL%252Fsvpwm.png%3Falt%3Dmedia%26token%3D8d82c6ef-1643-4035-a8ad-e1d70596e746&width=768&dpr=4&quality=100&sign=56626291&sv=2) [PreviousField Oriented Control (FOC) Operation](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation) [NextMotor Characterization](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization) Last updated 5 months ago --- # Syncing Files From Training Server | Berkeley Humanoid Lite Docs For larger training runs, we typically would use a dedicated remote training server to run. This short document notes down a way to easily synchronize training checkpoints from the server down to local workspace. To do this, we will use this VSCode extension: [![Logo](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2Fgithub.com%2Ffluidicon.png&width=20&dpr=4&quality=100&sign=b28aa768&sv=2)GitHub - Natizyskunk/vscode-sftp: Super fast sftp/ftp extension for VS CodeGitHub](https://github.com/Natizyskunk/vscode-sftp) After download, create a `sftp.json` configuration under the `.vscode/` directory and add these configurations: Copy { "name": "Your Remote Training Server", "host": "server.ip.address", "port": 22, "protocol": "sftp", "context": "./logs", "remotePath": "/PATH/TO/THE/WORKSPACE/logs", "username": "YOUR-USERNAME", "ignore": [], "uploadOnSave": false, "useTempFile": false, "openSsh": false, "privateKeyPath": "~/.ssh/id_ed25519" } Now, you can run "> SFTP: Sync Remote -> Local" command to fetch all the training logs and checkpoints. [PreviousTraining Environment Coding Convention](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention) [NextContribute](https://berkeley-humanoid-lite.gitbook.io/docs/contribute) Last updated 1 month ago --- # IMU Comparision | Berkeley Humanoid Lite Docs In this page we list the performance characteristics of the BNO085 IMU, which we originally used, and the IM10A IMU, which is the upgraded one that already provides USB interface. Parameter Unit BNO085 IM10A **Accelerometer** Range g ±16 ± 16 Resolution mg / LSB 1 0.5 RMS Noise mg 0.16 0.75 ~ 1 Static Zero Drift mg ± 150 ± 20 ~ 40 Bandwidth Hz 8 ~ 1000 5 ~ 256 **Gyroscope** Range °/s ± 2000 ± 2000 Resolution (°/s) / (LSB) 0.0625 0.061 RMS Noise °/s 0.014 0.028 ~ 0.07 Static Zero Drift °/s ± 1 ± 0.5 ~ 1 Bandwidth Hz 12 ~ 523 5 ~ 256 **Magnetometer** Range Gauss ± 13 ± 2 Resolution Gauss / LSB 0.003 0.0667 [PreviousMotor Characterization](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization) [NextCAN Communication](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication) Last updated 2 months ago --- # Joint ID Mapping | Berkeley Humanoid Lite Docs Joint ID Name CAN ID Range Description Left Arm 0 upperarm\_x\_l 1 \[-90, 45\] controls the flexion/extension (pitch) motion of the left upper arm. Positive is flexion 1 upperarm\_y\_l 3 \[-90, 0\] controls the abduction/adduction (yaw) motion of the left upper arm. Positive is adduction 2 upperarm\_z\_l 5 \[-45, 45\] controls the rotation (roll) motion of the left upper arm. Positive is lateral rotation 3 lowerarm\_x\_l 7 \[-90, 0\] controls the flexion/extension (pitch) motion of the left forearm. Positive is extension 4 lowerarm\_z\_l 9 \[-45, 45\] controls the rotation (roll) motion of the left forearm. Positive is lateral rotation Right Arm 5 upperarm\_x\_r 2 \[-45, 90\] controls the flexion/extension (pitch) motion of the right upper arm. Positive is extension 6 upperarm\_y\_r 4 \[0, 90\] controls the abduction/adduction (yaw) motion of the right upper arm. Positive is abduction 7 upperarm\_z\_r 6 \[-45, 45\] controls the rotation (roll) motion of the right upper arm. Positive is medial rotation 8 lowerarm\_x\_r 8 \[0, 90\] controls the flexion/extension (pitch) motion of the right forearm. Positive is flexion 9 lowerarm\_z\_r 10 \[-45, 45\] controls the rotation (roll) motion of the right forearm. Positive is medial rotation Left Leg 10 upperleg\_y\_l 1 \[-90, 10\] controls the flexion/extension (pitch) motion of the left thigh. Positive is flexion 11 upperleg\_z\_l 3 \[-45, 45\] controls the abduction/adduction (yaw) motion of the left thigh. Positive is adduction 12 upperleg\_x\_l 5 \[-110, 45\] controls the rotation (roll) motion of the left thigh. Positive is lateral rotation 13 lowerleg\_x\_l 7 \[0, 135\] controls the flexion/extension (pitch) motion of the left shin. Positive is extension 15 foot\_x\_l 11 \[-10, 45\] controls the dorsiflexion / plantar flexion (pitch) motion of the left foot. Positive is dorsiflexion 16 foot\_y\_l 13 \[-45, 45\] controls the inversion / eversion (roll) motion of the left foot. Positive is eversion Right Leg 17 upperleg\_y\_r 2 \[0, 90\] controls the flexion/extension (pitch) motion of the right thigh. Positive is extension 18 upperleg\_z\_r 4 \[-45, 45\] controls the abduction/adduction (yaw) motion of the right thigh. Positive is abduction 19 upperleg\_x\_r 6 \[-45, 110\] controls the rotation (roll) motion of the right thigh. Positive is medial rotation 20 lowerleg\_x\_r 8 \[-135, 0\] controls the flexion/extension (pitch) motion of the right shin. Positive is flexion 22 foot\_x\_r 12 \[-45, 10\] controls the dorsiflexion / plantar flexion (pitch) motion of the right foot. Positive is plantar flexion 23 foot\_y\_r 14 \[-45, 45\] controls the inversion / eversion (roll) motion of the right foot. Positive is inversion [PreviousCAN Communication](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication) [NextExporting Robot Description Files from Onshape](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/exporting-robot-description-files-from-onshape) Last updated 1 month ago --- # CAN Communication | Berkeley Humanoid Lite Docs The CAN frame is designed to mimic CANOpen communication protocol. The CAN ID field is divided into two fields, a 4-bit function code and a 7-bit node ID. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FyMPCqQfOp9hwFjJblyEf%252Fopencan-frame.png%3Falt%3Dmedia%26token%3Db03ffc25-96be-41cf-8253-5a31a1185bbb&width=768&dpr=4&quality=100&sign=b5f8f596&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FDUDyWZowhLSfLSqaugtW%252FCANopen-Identifier-Allocation-PDO-SDO-Standardized-Table_3.png%3Falt%3Dmedia%26token%3D2f98da31-22bc-4b7f-ba4c-59873e1c357e&width=768&dpr=4&quality=100&sign=dd5ec76b&sv=2) [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#nmt-network-management) NMT Network Management ----------------------------------------------------------------------------------------------------------------------------------------- The NMT frame is used to configure the operational mode of the motor controller. To configure the operational mode, the master sends an NMT frame to the slave device. In the NMT frame, byte 0 is set to be the requested mode, and byte 1 is set to be the target device ID. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#sdo-service-data-object) SDO Service Data Object ------------------------------------------------------------------------------------------------------------------------------------------- The SDO frames are used to configure the device parameters. To read the current value from a parameter, the master sends out a RECEIVE\_SDO frame. The 5-7 bit in byte 0 should be set to 2 (upload). Byte 1-2 should be set to the address of the target parameter. After sending, the master should listen for a TRANSMIT\_SDO frame from the slave device. Byte 0-3 should contain the resulting data. To write a new value to a parameter, the master sends out a RECEIVE\_SDO frame. The 5-7 bit in byte 0 should be set to 1 (download). Byte 1-2 should be set to the address of the target parameter. Byte 4-7 should contain the new value of the parameter. The slave does not transmit a response for write requests. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#pdo-1-process-data-object-1) PDO 1 Process Data Object 1 --------------------------------------------------------------------------------------------------------------------------------------------------- The PDO1 frame is used to detect if the target device is present on the bus. The frame can also be used for debugging purpose. The master sends out a RECEIVE\_PDO\_1 frame. The slave will respond with a TRANSMIT\_PDO\_1 frame. The data will echo the received frame. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#pdo-2-process-data-object-2) PDO 2 Process Data Object 2 --------------------------------------------------------------------------------------------------------------------------------------------------- The PDO2 frame is used for normal control. The master sends out a RECEIVE\_PDO\_2 frame. The data field contains the target position and velocity in fp32 format. The slave will respond with a TRANSMIT\_PDO\_2 frame. The data field contains the measured position and measured velocity in fp32 format. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#pdo-3-process-data-object-3) PDO 3 Process Data Object 3 --------------------------------------------------------------------------------------------------------------------------------------------------- The PDO3 frame is used for torque compensation control. The master sends out a RECEIVE\_PDO\_3 frame. The data field contains the target position and target feed-forward torque in fp32 format. The slave will respond with a TRANSMIT\_PDO\_3 frame. The data field contains the measured position and measured torque in fp32 format. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#pdo-4-process-data-object-4) PDO 4 Process Data Object 4 --------------------------------------------------------------------------------------------------------------------------------------------------- The PDO4 frame is used for event-driven update frame. When fast-frame update is enabled, the slave will periodically send out TRANSMIT\_PDO\_4 frames containing the current measured position and velocity. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#flash-flash-operation) FLASH Flash Operation --------------------------------------------------------------------------------------------------------------------------------------- The FLASH frame is used to save and load the configuration parameters. When storing the current parameters to flash, the master sends out a FLASH frame. Byte 0 should set to 1 (store). When loading the current parameters to flash, the master sends out a FLASH frame. Byte 0 should set to 2 (load). In both cases, the slave will not respond frame. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#heartbeat-heartbeat) HEARTBEAT Heartbeat ----------------------------------------------------------------------------------------------------------------------------------- The HEARTBEAT frame is used to update the safety watchdog timer. The master sends out a HEARTBEAT frame. Upon receiving the frame, the slave will reset its safety watchdog timer. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#troubleshoot-the-can-communication) Troubleshoot the CAN communication ----------------------------------------------------------------------------------------------------------------------------------------------------------------- Copy ip -details -statistics link show canX Log all data and error frames Copy candump -l any,0:0,#FFFFFFFF Example: Copy tk@tk-MINI-S:~/Desktop/berkeley_humanoid_lite_lowlevel$ ip -details -statistics link show can2 10: can2: mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10 link/can promiscuity 0 minmtu 0 maxmtu 0 can state ERROR-ACTIVE restart-ms 0 bitrate 1000000 sample-point 0.750 tq 62 prop-seg 5 phase-seg1 6 phase-seg2 4 sjw 1 gs_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1 clock 48000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus usb parentdev 1-3.3:1.0 RX: bytes packets errors dropped missed mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 tk@tk-MINI-S:~/Desktop/berkeley_humanoid_lite_lowlevel$ ip -details -statistics link show can3 11: can3: mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 10 link/can promiscuity 0 minmtu 0 maxmtu 0 can state ERROR-ACTIVE restart-ms 0 bitrate 1000000 sample-point 0.750 tq 62 prop-seg 5 phase-seg1 6 phase-seg2 4 sjw 1 gs_usb: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1 clock 48000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 parentbus usb parentdev 1-3.4:1.0 RX: bytes packets errors dropped missed mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/can-communication#minimizing-the-can-noise) Minimizing the CAN noise --------------------------------------------------------------------------------------------------------------------------------------------- Here are some good resources on how to properly do CAN electrical connections: Decap and common-mode choke: [https://community.st.com/t5/stm32-mcus-products/can-bus-massive-noise-on-the-bus-when-a-power-converter-starts/td-p/682045](https://community.st.com/t5/stm32-mcus-products/can-bus-massive-noise-on-the-bus-when-a-power-converter-starts/td-p/682045) Split termination: [https://electronics.stackexchange.com/questions/512653/can-split-termination-capacitor-calculation](https://electronics.stackexchange.com/questions/512653/can-split-termination-capacitor-calculation) How Termination CAN Improve EMC Performance in a CAN Transceiver: [https://www.ti.com/lit/ta/ssztam0/ssztam0.pdf?ts=1750097536718](https://www.ti.com/lit/ta/ssztam0/ssztam0.pdf?ts=1750097536718) [PreviousIMU Comparision](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/imu-comparision) [NextJoint ID Mapping](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/joint-id-mapping) Last updated 2 months ago --- # Exporting Robot Description Files from Onshape | Berkeley Humanoid Lite Docs [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/exporting-robot-description-files-from-onshape#setting-up-onshape-developer-key) Setting up Onshape developer key ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Get API key from the Onshape Developer Portal [![Logo](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2Fcad.onshape.com%2Ffavicon.png&width=20&dpr=4&quality=100&sign=fd2c2f6&sv=2)App Store - Onshape](https://cad.onshape.com/appstore/dev-portal) When creating the key, make sure that at least “Application can read your documents” is selected. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FFXtYfkxVkOVQyWKfwS9N%252Fimage.png%3Falt%3Dmedia%26token%3Dcab996d4-e0e2-4d26-a5c9-8b6802e99a65&width=768&dpr=4&quality=100&sign=35d95ce&sv=2) export the key as environment variable Copy export ONSHAPE_API=https://cad.onshape.com export ONSHAPE_ACCESS_KEY=Your_Access_Key export ONSHAPE_SECRET_KEY=Your_Secret_Key [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/exporting-robot-description-files-from-onshape#install-isaac-lab-less-than-2.0.0) Install Isaac Lab < 2.0.0 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ At the time of writing (2025 March), the USD export function of Isaac Lab ≥ 2.0.0 seems to be broken. To use the URDF to USD converter, we need to use an older version of Isaac Lab release. After some testing, Isaac Lab 1.4.0 seems to be a good choice. The procedure is similar to the normal Isaac Lab install. The only difference is that for Isaac Sim, we need to install an older version, Isaac Sim == 4.2.0.2. Copy conda create -yn isaaclab-1.4.0 python=3.10 conda activate isaaclab-1.4.0 Copy pip install isaacsim==4.2.0.2 isaacsim-extscache-physics==4.2.0.2 isaacsim-extscache-kit==4.2.0.2 isaacsim-extscache-kit-sdk==4.2.0.2 --extra-index-url https://pypi.nvidia.com Additionally, there is an issue on finding the correct RSL\_RL repository during Isaac Lab installation in this version. Since we will not use this Isaac Lab install to do any training, we can comment out the dependency in `source/extensions/omni.isaac.lab_tasks/setup.py`. setup.py Copy # Extra dependencies for RL agents EXTRAS_REQUIRE = { "sb3": ["stable-baselines3>=2.1"], "skrl": ["skrl>=1.3.0"], "rl-games": ["rl-games==1.6.1", "gym"], # rl-games still needs gym :( - "rsl-rl": ["rsl-rl@git+https://github.com/leggedrobotics/rsl_rl.git"], + # "rsl-rl": ["rsl-rl@git+https://github.com/leggedrobotics/rsl_rl.git"], "robomimic": [], } # Add the names with hyphens as aliases for convenience EXTRAS_REQUIRE["rl_games"] = EXTRAS_REQUIRE["rl-games"] - EXTRAS_REQUIRE["rsl_rl"] = EXTRAS_REQUIRE["rsl-rl"] + # EXTRAS_REQUIRE["rsl_rl"] = EXTRAS_REQUIRE["rsl-rl"] [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/exporting-robot-description-files-from-onshape#install-onshape-to-robot) Install onshape-to-robot -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Follow the [guide](https://onshape-to-robot.readthedocs.io/en/latest/getting_started.html#installing-the-package) from onshape-to-robot. The rest should be pretty straight forward. [PreviousJoint ID Mapping](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/joint-id-mapping) [NextTraining Environment Coding Convention](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention) Last updated 4 months ago --- # Training Environment Coding Convention | Berkeley Humanoid Lite Docs We found that keeping track of all the reward functions, configuration settings, and robot parameters in the training environment can quickly become overwhelming. To help manage this complexity, we’ve adopted a coding convention that organizes these elements consistently, making them easier to locate and maintain. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention#environment-configuration-class-ordering) Environment configuration class ordering The configuration classes within a environment definition is ordered as follows: Copy @configclass class YourEnvCfg(ManagerBasedRLEnvCfg): """Configuration for your robot learning environment.""" # Scene settings scene: SceneCfg = SceneCfg() # Policy commands commands: CommandsCfg = CommandsCfg() # Policy observations observations: ObservationsCfg = ObservationsCfg() # Policy actions actions: ActionsCfg = ActionsCfg() # Policy rewards rewards: RewardsCfg = RewardsCfg() # Termination conditions terminations: TerminationsCfg = TerminationsCfg() # Randomization events events: EventsCfg = EventsCfg() # Curriculum curriculum: CurriculumCfg = CurriculumCfg() def __post_init__(self): # post init of parent super().__post_init__() # override default configuration parameters ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention#configuration-term-parameter-ordering) Configuration term parameter ordering For the parameter within each term, we order the parameters based on the class argument ordering: Copy # example observation term base_ang_vel = ObsTerm( func=mdp.base_ang_vel, noise=Unoise(n_min=-0.2, n_max=0.2), scale=0.2, ) # example reward term track_lin_vel_xy_exp = RewTerm( func=mdp.track_lin_vel_xy_exp, params={"command_name": "base_velocity", "std": math.sqrt(0.25)}, weight=1.0, ) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention#asymmetric-observation-config) Asymmetric observation config Typically, for asymmetric observations, we will add all actor observations to the critic along with some additional privileged observations. To ensure that the configurations of the duplicated terms are consistent, the critic observation config should inherit from the actor's. One thing to note is that we do not want to add noise to the critic's observation terms. To do this, we can set the `enable_corruption` parameter to `False` . The resulting code should look like Copy @configclass class ObservationsCfg: """Observation specifications for the MDP.""" @configclass class PolicyCfg(ObsGroup): """Observations for policy group.""" # observation terms (order preserved) velocity_commands = ObsTerm( func=mdp.generated_commands, params={"command_name": "base_velocity"}, ) base_ang_vel = ObsTerm( func=mdp.base_ang_vel, noise=Unoise(n_min=-0.2, n_max=0.2), scale=0.2, ) # ... (more terms) def __post_init__(self): self.enable_corruption = True # <-- enable noise for actor obs class CriticCfg(PolicyCfg): # <-- inherit all terms from the actor """Observations for critic group.""" # observation terms (order preserved) base_lin_vel = ObsTerm(func=mdp.base_lin_vel) # ... (more terms) def __post_init__(self): self.enable_corruption = False # <-- disable noise for critic obs # observation groups policy: PolicyCfg = PolicyCfg() critic: CriticCfg = CriticCfg() ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention#reward-terms) Reward terms Reward terms are grouped by their purpose. Measurements on task-space performance is put at the front due to its importance. Then, terms for basic behaviors, such as survival, motion smoothness etc. are followed. Lastly, terms for "fine-tuning" the policy are added. Copy @configclass class RewardsCfg: """Reward terms for the MDP.""" # === Reward for task-space performance === # ... (terms) # === Reward for basic behaviors === # ... (terms) # === Reward for encouraging behaviors === # ... (terms) ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/training-environment-coding-convention#post_init__-behavior) \_\_post\_init\_\_ behavior Differ from the Isaac Lab code, we encourage to set configurations in the corresponding config class and config terms. Only override parameters in the `__post_init__()` function: 1. during temporary debugging and parameter space explorations, 2. when the base configuration is inaccessible (for example, the `ROBOT_CFG` variable) [PreviousExporting Robot Description Files from Onshape](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/exporting-robot-description-files-from-onshape) [NextSyncing Files From Training Server](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/syncing-files-from-training-server) Last updated 1 month ago --- # Contribute | Berkeley Humanoid Lite Docs We wholeheartedly welcome contributions from the community to make this robot platform more mature and useful for everyone. We appreciate any kind of contributions, including bug reports, feature requests, or code contributions. Also, please reach out to us to tell us about your projects and how you are using this robot platform. We would love to feature your work on our website and social media. [](https://berkeley-humanoid-lite.gitbook.io/docs/contribute#community) Community -------------------------------------------------------------------------------------- Please consider joining our community with the following links. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FhVJruUCBlHIlNTK7uGkt%252Fdiscord-invite.png%3Falt%3Dmedia%26token%3D1a8b9382-eed6-4eac-8df9-4943fa110cd5&width=768&dpr=4&quality=100&sign=1b1830bb&sv=2) Discord Server ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FNDGnNab3qCSfzxSEdDwE%252Fwechat-invite.jpg%3Falt%3Dmedia%26token%3De64b37b0-3d48-4c48-8e27-3ecec3b0999a&width=768&dpr=4&quality=100&sign=b0eee47a&sv=2) WeChat Group [PreviousSyncing Files From Training Server](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/syncing-files-from-training-server) Last updated 4 months ago --- # Motor Characterization | Berkeley Humanoid Lite Docs The overall actuator performance depends on several characteristics of the motor, including the winding type, phase resistance, phase inductance, and more. To achieve a smaller sim-to-real gap, we need to identify the actual value of these motor parameters. In this note, we characterize the MAD Components M6C12 and 5010 motor that are used in the robot actuators. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#phase-winding-type) Phase Winding Type -------------------------------------------------------------------------------------------------------------------------------------- ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FwEcWlRDDQM4nF3Ih067q%252Fbldc-winding-type.png%3Falt%3Dmedia%26token%3D3682335b-f514-4c08-acd0-91b229a0d294&width=768&dpr=4&quality=100&sign=16862882&sv=2) For BLDC motors, there are two possible winding types, delta winding and wye winding. The line-to-line measurement that we are going to do in the following sections have different implications for different motor winding types, so we need to determine the winding type of our motor first. To identify the phase connection, we energize two phase wires with power supply set to 1.00 V and current limit to 10.0 A. The winding type can be determined by observing the thermal image of the winding. When two phase wires are energized, only one-third of the windings are heated. Hence, both motors are using delta winding. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#m6c12-motor-delta-winding) M6C12 Motor = Delta Winding ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FWoyjZb7SAVL0S4sunp5r%252Fm6c12-phase-wire-A-B-energized.png%3Falt%3Dmedia%26token%3D36d6d37c-4910-492c-8fbe-fc8abb380cec&width=768&dpr=4&quality=100&sign=88d92e24&sv=2) Phase wire A-B energized ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FGvMH1lJJpiS7kuJWAPKX%252Fm6c12-phase-wire-B-C-energized.png%3Falt%3Dmedia%26token%3D42b4924b-73fa-4f1a-af39-9201a112c0c3&width=768&dpr=4&quality=100&sign=6606561f&sv=2) Phase wire B-C energized ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#id-5010-motor-delta-winding) 5010 Motor = Delta Winding ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252Fc7o4Ls08JLHE0QGK5riq%252F5010-phase-wire-A-B-energized.png%3Falt%3Dmedia%26token%3D8eccbd09-bd48-4caa-a0c4-728406e5ce33&width=768&dpr=4&quality=100&sign=eb1fcf1d&sv=2) Phase wire A-B energized ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FtMI6DTnrweE5yPi2BGLa%252F5010-phase-wire-B-C-energized.png%3Falt%3Dmedia%26token%3Dfd47d2d3-be0c-4bc2-a77a-b3f88ce21026&width=768&dpr=4&quality=100&sign=2da56aad&sv=2) Phase wire B-C energized [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#phase-resistance) Phase Resistance ---------------------------------------------------------------------------------------------------------------------------------- The phase resistance can be calculated from the line-to-line resistance with the following relation: Rwye\=12RllRdelta\=32RllR\_{wye} = \\frac{1}{2}R\_{ll} \\qquad\\qquad\\qquad R\_{delta} = \\frac{3}{2}R\_{ll}Rwye​\=21​Rll​Rdelta​\=23​Rll​ To measure line-to-line resistance, we energize phases with a constant voltage and measure the current flowing through the winding. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#m6c12-motor-0.1886-r) M6C12 Motor = 0.1886 R The power supply is set to be 0.99 V. Phase wire A-B energized, measured current 7.872 A. Phase wire B-C energized, measured current 7.879 A. The line-to-line resistance is calucated to be Rll\=VllIll\=Avg(0.99 V7.872 A,0.99 V7.879 A)≈0.1257 ΩR\_{ll} = \\frac{V\_{ll}}{I\_{ll}} = Avg(\\frac{0.99~\\text{V}}{7.872~\\text{A}}, \\frac{0.99~\\text{V}}{7.879~\\text{A}}) \\approx 0.1257~\\Omega Rll​\=Ill​Vll​​\=Avg(7.872 A0.99 V​,7.879 A0.99 V​)≈0.1257 Ω The phase resistance can then be caluclated as Rq\=32Rll\=32×0.1257 Ω\=0.1886 ΩR\_q = \\frac{3}{2}R\_{ll} = \\frac{3}{2} \\times 0.1257~\\Omega = 0.1886~\\OmegaRq​\=23​Rll​\=23​×0.1257 Ω\=0.1886 Ω The phase resistance of the M6C12 motor is 0.1886 Ω. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#id-5010-motor-0.6193-r) 5010 Motor = 0.6193 R The power supply is set to be 1.00 V. Phase wire A-B energized, measured current 2.468 A Phase wire A-B energized, measured current 2.378 A The line-to-line resistance is calucated to be Rll\=VllIll\=Avg(1.00 V2.468 A,1.00 V2.378 A)≈0.4129 ΩR\_{ll} = \\frac{V\_{ll}}{I\_{ll}} = Avg(\\frac{1.00~\\text{V}}{2.468~\\text{A}}, \\frac{1.00~\\text{V}}{2.378~\\text{A}}) \\approx 0.4129~\\OmegaRll​\=Ill​Vll​​\=Avg(2.468 A1.00 V​,2.378 A1.00 V​)≈0.4129 Ω The phase resistance can then be caluclated as Rq\=32Rll\=32×0.4129 Ω\=0.6193 ΩR\_q = \\frac{3}{2}R\_{ll} = \\frac{3}{2} \\times 0.4129~\\Omega = 0.6193~\\OmegaRq​\=23​Rll​\=23​×0.4129 Ω\=0.6193 Ω The phase resistance of the M6C12 motor is 0.6193 Ω. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#phase-inductance) Phase Inductance ---------------------------------------------------------------------------------------------------------------------------------- The phase inductance can be calculated from the line-to-line inductance with the following relation: Lwye\=32LllLdelta\=12LllL\_{wye} = \\frac{3}{2}L\_{ll} \\qquad\\qquad\\qquad L\_{delta} = \\frac{1}{2}L\_{ll}Lwye​\=23​Lll​Ldelta​\=21​Lll​ We use a digital LCR tester to measure the inducance of the winding. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#m6c12-motor-0.0325-mh) M6C12 Motor = 0.0325 mH Between phase wire A-B: 0.065 mH Between phase wire A-C: 0.065 mH Between phase wire B-C: 0.065 mH The average line-to-line inductance is hence Lll\=6.50e−5 HL\_{ll} = 6.50e^{-5}~\\text{H}Lll​\=6.50e−5 H The phase inductance can then be caluclated as Lq\=12Rll\=12×6.50e−5 H\=3.25e−5 HL\_q = \\frac{1}{2}R\_{ll} = \\frac{1}{2} \\times 6.50e^{-5}~\\text{H} = 3.25e^{-5}~\\text{H}Lq​\=21​Rll​\=21​×6.50e−5 H\=3.25e−5 H The phase resistance of the M6C12 motor is 0.0325 mH. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#id-5010-motor-0.0850-mh) 5010 Motor = 0.0850 mH Between phase wire A-B: 0.170 mH Between phase wire A-C: 0.168 mH Between phase wire B-C: 0.172 mH The average line-to-line inductance is hence Lll\=1.70e−4 HL\_{ll} = 1.70e^{-4}~\\text{H}Lll​\=1.70e−4 H The phase inductance can then be caluclated as Lq\=12Rll\=12×1.70e−4 H\=8.50e−5 HL\_q = \\frac{1}{2}R\_{ll} = \\frac{1}{2} \\times 1.70e^{-4}~\\text{H} = 8.50e^{-5}~\\text{H}Lq​\=21​Rll​\=21​×1.70e−4 H\=8.50e−5 H The phase resistance of the M6C12 motor is 0.0850 mH. Alternative Approach[](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#alternative-approach) An alternative approach to measure the phase inductance is to supply a square wave to the motor phase winding, and measure the voltage change. However, we couldn't interpret the result correctly. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FQz4c6kNlJCXHeZ3eVSeS%252Fphase-indutance-testbench.jpg%3Falt%3Dmedia%26token%3Dc9217e3b-b06b-48da-a3c4-a907c2effc80&width=300&dpr=4&quality=100&sign=d9e63163&sv=2) Testbench setup ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FAw9CqjG1CbHB0l6YLPow%252Fm6c12_rise_time_ab.png%3Falt%3Dmedia%26token%3D3de92be5-e0af-47a5-bafc-fcff9ceb793c&width=300&dpr=4&quality=100&sign=a077944f&sv=2) Rise time of the M6C12 between phase A and B [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#motor-back-emf-constant) Motor Back EMF Constant ------------------------------------------------------------------------------------------------------------------------------------------------ Vll,wye\=2Vq\=2kemfdθmdtVll,delta\=23Vq\=23kemfdθmdtV\_{ll,wye} = \\sqrt{2}V\_{q} = \\sqrt{2}k\_{emf}\\frac{d\\theta\_m}{dt} \\qquad\\qquad\\qquad V\_{ll,delta} = \\sqrt{\\frac{2}{3}}V\_{q} = \\sqrt{\\frac{2}{3}}k\_{emf}\\frac{d\\theta\_m}{dt}Vll,wye​\=2​Vq​\=2​kemf​dtdθm​​Vll,delta​\=32​​Vq​\=32​​kemf​dtdθm​​ τ\=kemfIq\=321kemfIq\\tau = k\_{emf}I\_q = \\sqrt{\\frac{3}{2}}\\frac{1}{k\_{emf}}I\_qτ\=kemf​Iq​\=23​​kemf​1​Iq​ [reference](https://www.radiocontrolinfo.com/about-rc-brushless-motor-windings/) [reference](https://www.youtube.com/watch?v=jrWDBkeOVQY&t=901s) To test the BEMF value, the motor under test is driven with a electrical drill with a constant velocity. The voltage is measured between two phase wires. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#m6c12-motor-0.0919-nm-a) M6C12 Motor = 0.0919 Nm / A ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FVe6Nr6t9TC7lZDETRoJO%252Fm6c12_bemf.png%3Falt%3Dmedia%26token%3D41d9827a-dea7-444f-aa4d-a7fcd58e8459&width=768&dpr=4&quality=100&sign=43cf32e2&sv=2) From the oscilloscope reading, we get electrical rotation frequency to be 344.27 Hz, and peak-to-peak line-to-line voltage to be 23.20 V. Calculate electrical rotation velocity ωelec\=2πfelec\=2π×344.27 Hz\=2163.11 rad/s\\omega\_\\text{elec} = 2 \\pi f\_\\text{elec} = 2\\pi \\times 344.27~\\text{Hz}= 2163.11~\\text{rad/s}ωelec​\=2πfelec​\=2π×344.27 Hz\=2163.11 rad/s Calculate mechanical rotation velocity ωmech\=ωelecNpole-pair\=2163.11 rad/s14\=154.51 rad/s\\omega\_\\text{mech} = \\frac{\\omega\_\\text{elec}}{N\_\\text{pole-pair}} = \\frac{2163.11~\\text{rad/s}}{14} = 154.51~\\text{rad/s}ωmech​\=Npole-pair​ωelec​​\=142163.11 rad/s​\=154.51 rad/s As a sanity check, we can first calculate the measured KV value KV\=ωmech12Vpk-pk\=154.51 rad/s0.5×23.20 V\=13.320 rad/Vs\=127.19 RPM/VK\_V = \\frac{\\omega\_\\text{mech}}{\\frac{1}{2}V\_\\text{pk-pk}} = \\frac{154.51~\\text{rad/s}}{0.5 \\times 23.20~\\text{V}} = 13.320~\\text{rad/Vs} = 127.19~\\text{RPM/V}KV​\=21​Vpk-pk​ωmech​​\=0.5×23.20 V154.51 rad/s​\=13.320 rad/Vs\=127.19 RPM/V This result roughly matches the label on the motor, which is 150 KV. To calculate the torque constant, we have Kτ\=3212Vpk-pkωmech\=3212×23.20 V154.51 rad/s\=0.0919 Vs/rad\=0.0919 Nm / A\\begin{aligned} K\_\\tau &= \\sqrt\\frac{3}{2} \\frac{\\frac{1}{2}V\_\\text{pk-pk}}{\\omega\_\\text{mech}} \\\\ &= \\sqrt\\frac{3}{2} \\frac{\\frac{1}{2} \\times 23.20~\\text{V}}{154.51~\\text{rad/s}} \\\\ &= 0.0919~\\text{Vs/rad} \\\\ &= 0.0919~\\text{Nm / A} \\end{aligned}Kτ​​\=23​​ωmech​21​Vpk-pk​​\=23​​154.51 rad/s21​×23.20 V​\=0.0919 Vs/rad\=0.0919 Nm / A​ Thus, the torque constant of the M6C12 motor is 0.0919 Nm / A ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#id-5010-motor-0.1176-nm-a) 5010 Motor = 0.1176 Nm / A ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FmIw3eumzEz4RVMyq9K4l%252F5010_bemf.png%3Falt%3Dmedia%26token%3D67a70f75-ff9d-4072-b0c6-6cbbefa2255d&width=768&dpr=4&quality=100&sign=74c2754c&sv=2) From the oscilloscope reading, we get electrical rotation frequency to be 250.59 Hz, and peak-to-peak line-to-line voltage to be 21.60 V. Calculate electrical rotation velocity ωelec\=2πfelec\=2π×250.59 Hz\=1574.50 rad/s\\omega\_\\text{elec} = 2 \\pi f\_\\text{elec} = 2\\pi \\times 250.59~\\text{Hz}= 1574.50~\\text{rad/s}ωelec​\=2πfelec​\=2π×250.59 Hz\=1574.50 rad/s Calculate mechanical rotation velocity ωmech\=ωelecNpole-pair\=1574.50 rad/s14\=112.465 rad/s\\omega\_\\text{mech} = \\frac{\\omega\_\\text{elec}}{N\_\\text{pole-pair}} = \\frac{1574.50~\\text{rad/s}}{14} = 112.465~\\text{rad/s}ωmech​\=Npole-pair​ωelec​​\=141574.50 rad/s​\=112.465 rad/s As a sanity check, we can first calculate the measured KV value KV\=ωmech12Vpk-pk\=112.465 rad/s0.5×21.60 V\=10.413 rad/Vs\=99.44 RPM/VK\_V = \\frac{\\omega\_\\text{mech}}{\\frac{1}{2}V\_\\text{pk-pk}} = \\frac{112.465~\\text{rad/s}}{0.5 \\times 21.60~\\text{V}} = 10.413~\\text{rad/Vs} = 99.44~\\text{RPM/V}KV​\=21​Vpk-pk​ωmech​​\=0.5×21.60 V112.465 rad/s​\=10.413 rad/Vs\=99.44 RPM/V This result roughly matches the label on the motor, which is 110 KV. To calculate the torque constant, we have Kτ\=3212Vpk-pkωmech\=3212×21.60 V112.465 rad/s\=0.1176 Vs/rad\=0.1176 Nm / A\\begin{aligned} K\_\\tau &= \\sqrt\\frac{3}{2} \\frac{\\frac{1}{2}V\_\\text{pk-pk}}{\\omega\_\\text{mech}} \\\\ &= \\sqrt\\frac{3}{2} \\frac{\\frac{1}{2} \\times 21.60~\\text{V}}{112.465~\\text{rad/s}} \\\\ &= 0.1176~\\text{Vs/rad} \\\\ &= 0.1176~\\text{Nm / A} \\end{aligned}Kτ​​\=23​​ωmech​21​Vpk-pk​​\=23​​112.465 rad/s21​×21.60 V​\=0.1176 Vs/rad\=0.1176 Nm / A​ Thus, the torque constant of the 5010 motor is 0.1176 Nm / A [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#motor-rotor-inertia) Motor Rotor Inertia ---------------------------------------------------------------------------------------------------------------------------------------- ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FCjhoC8SJSdS6sFiJahSm%252F6512_rotor.jpg%3Falt%3Dmedia%26token%3Dc313ef29-713d-430b-80bc-8efad47e6e8e&width=768&dpr=4&quality=100&sign=5f33153a&sv=2) ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FzMpSY20pCqIU8WB42naq%252F5010_rotor.jpg%3Falt%3Dmedia%26token%3Dd8804f77-f2d2-4693-8196-c15112592b9f&width=768&dpr=4&quality=100&sign=6b5d4240&sv=2) The rotor can be approximated as a cylindrical shell. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FIhkDqYSVphgsziVamDwc%252Finertia.png%3Falt%3Dmedia%26token%3Dbab46420-0a1d-4bdf-b767-1cf86036119f&width=768&dpr=4&quality=100&sign=1ad37bde&sv=2) The diameter of the rotors are 68 mm for M6C12, and 53 mm for 5010. IM6C12\=MR2\=0.086 kg×(0.5×0.068 m)2\=9.942e−05 kg⋅m2I\_{M6C12} = M R^2 = 0.086~\\text{kg} \\times (0.5 \\times 0.068~\\text{m})^2 = 9.942e^{-05}~\\text{kg}\\cdot\\text{m}^2IM6C12​\=MR2\=0.086 kg×(0.5×0.068 m)2\=9.942e−05 kg⋅m2 I5010\=MR2\=0.047 kg×(0.5×0.053 m)2\=3.301e−05 kg⋅m2I\_{5010} = M R^2 = 0.047~\\text{kg} \\times (0.5 \\times 0.053~\\text{m})^2 = 3.301e^{-05}~\\text{kg}\\cdot\\text{m}^2I5010​\=MR2\=0.047 kg×(0.5×0.053 m)2\=3.301e−05 kg⋅m2 The final reflected inertia is magnified by the gearbox, which we would mutiply by the **reduction ratio squared**. The final results are IM6C12\=9.942e−05 kg⋅m2×152\=0.0224 kg⋅m2I\_{M6C12} = 9.942e^{-05}~\\text{kg}\\cdot\\text{m}^2 \\times 15^2 = 0.0224 ~\\text{kg}\\cdot\\text{m}^2IM6C12​\=9.942e−05 kg⋅m2×152\=0.0224 kg⋅m2 I5010\=3.301e−05 kg⋅m2×152\=0.00743 kg⋅m2I\_{5010} = 3.301e^{-05}~\\text{kg}\\cdot\\text{m}^2 \\times 15^2 = 0.00743 ~\\text{kg}\\cdot\\text{m}^2I5010​\=3.301e−05 kg⋅m2×152\=0.00743 kg⋅m2 [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-characterization#summary) Summary ---------------------------------------------------------------------------------------------------------------- As a result, we summarize the motor characteristics in the following table Motor Name Phase Resistance (Ω) Phase Inductance (mH) Motor BEMF (Nm / A) Motor Rotor Inertia (kg · m²) M6C12 150KV 0.1886 0.0325 0.0919 0.0224 5010 110KV 0.6193 0.0850 0.1176 0.00743 5010 140KV 0.3939 0.0433 0.0913 0.00743 5010 310KV 0.1462 0.0023 0.0298 0.00743 [PreviousMotor Controller Firmware Execution Timing Information](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information) [NextIMU Comparision](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/imu-comparision) Last updated 2 months ago --- # Field Oriented Control (FOC) Operation | Berkeley Humanoid Lite Docs [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-1.-brushless-dc-motor) 1\. Brushless DC Motor -------------------------------------------------------------------------------------------------------------------------------------------------------------- A brushless direct-current (BLDC) motor consists of magnets and phase-winding coils. To illustrate its operating principle, consider a simplified model featuring one pair of magnetic poles and three coils. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FSsN0xgZX8G5tPUACVcid%252Ffoc.png%3Falt%3Dmedia%26token%3D506fe376-826b-4d11-8044-77112ec1abcd&width=768&dpr=4&quality=100&sign=945083da&sv=2) In this model, the coils form the stator. When current flows through a coil, it generates a magnetic field that either attracts or repels the adjacent magnet on the rotor. This magnetic interaction causes the rotor to rotate. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-2.-a-simple-control-scheme-six-step-commutation) 2\. A Simple Control Scheme: Six-Step Commutation ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- In a BLDC motor, the ends of the three coils are connected to form three external terminals that interface with the driving circuit. These coils can be connected either in a star (wye) configuration or a delta configuration. The star connection is more common: one end of each coil is accessible as an external lead, while the other ends are joined internally to form a neutral point. To control the three wires, a three-phase inverter circuit is used. This inverter is composed of three half-bridge drivers, which can be viewed as six switches connecting between VDD and ground. Each half-bridge can operate in one of four states: * High-side ON, low-side OFF (**1**) * High-side OFF, low-side ON (**0**) * High-side ON, low-side ON (**X**) * High-side OFF, low-side OFF (**N**) The **X** state is invalid because it directly connects VCC to ground, while the **N** state is not used because it leaves the phase coil in a floating condition, reducing the driver’s maximum output capability. This leaves only two valid states: state **1** connects the phase to VCC, and state **0** connects it to ground. By combining these two valid states for the three phases, there are eight possible inverter states: * 000 * 100 * 110 * 010 * 011 * 001 * 101 * 111 Out of these, the states **000** and **111** are non-driving because all phases are tied to the same voltage level (either VCC or ground), resulting in no voltage differential between them. The remaining six states are the driving states. For example, consider the motor in state **100**: * **Phase A** is connected to VCC. * **Phases B and C** are connected to ground. In this configuration, current flows from phase A through the neutral point to phases B and C, and then to ground. This current generates a magnetic field oriented toward phase A (0°), which attracts the rotor's magnets and rotates the rotor to 0°. Next, switching to state **110**: * **Phases A and B** are connected to VCC. * **Phase C** is connected to ground. This creates a magnetic field pointing between phases A and B (approximately 30°), which turns the rotor toward the 30° direction. Similarly, the remaining driving states sequentially direct the rotor to 60°, 90°, 120°, 150°, and finally back to 0° when returning to state **100**. By switching through these states in order, the motor can be driven continuously and efficiently. **Reference**: [Six Step Commutation - MathWorks](https://www.mathworks.com/help/mcb/ref/sixstepcommutation.html) [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-3.-efficiency-improved-vector-control) 3\. Efficiency Improved: Vector Control ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- By analyzing the magnetic forces generated from the stator winding acting on the rotor, we can decompose the overall force into two orthogonal components: one aligned with the rotor’s magnetic field (the d-axis component, FdF\_dFd​) and one perpendicular to it (the q-axis component, FqF\_qFq​). In vector control, only the perpendicular component, FqF\_qFq​, contributes to generating torque. The component FdF\_dFd​, which is parallel to the rotor magnet, does not aid in rotation and is essentially wasted energy. To drive the motor efficiently, the control strategy aims to minimize FdF\_dFd​ while maximizing FqF\_qFq​, thereby ensuring that most of the electrical energy is converted into useful rotational force. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-4.-frame-transformation) 4\. Frame Transformation ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Since the motor’s phase voltages are floating and lack a fixed reference point, it is impractical to use power resistors for sampling. A simpler approach is to add resistors under the low-side MOSFETs, which allows us to sample and obtain three approximate sine-wave phase currents. However, the resulting measurement would yield three sinusoidal signals that are correlated with each other. This makes designing the controller for it very challenging. Instead, with the use of a series of mathematical transformations, we can convert the three phase BLDC motor model into a two phase DC motor model. Tracking the transformation between these two models can be particularly challenging due to differences in reference frames. In the three-phase BLDC motor model, physical quantities are defined relative to each individual phase, with the reference frame rotating along with the rotor. In contrast, the simplified two-phase DC motor model defines quantities with respect to the orthogonal D (direct) and Q (quadrature) axes within a stationary reference frame. It's essential to pay close attention to the frame in which each variable is defined. In the following discussion, we will clearly state the reference frame along with the corresponding variables. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#alpha-beta-transform) Alpha Beta Transform The three phase currents IaI\_aIa​, IbI\_bIb​, and IcI\_cIc​ are three sinusoidal, rotating vectors, each offset by 120° relative to the others. Since they all lie in the same plane, the [Clarke transform](https://www.mathworks.com/help/mcb/ref/clarketransform.html) (also named [alpha-beta transform](https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_transformation) ) can be used to reduce them into two orthogonal components, IαI\_\\alphaIα​ and IβI\_\\betaIβ​. ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FZcFlnQm08WHpnxGaLR9P%252Falpha-beta.png%3Falt%3Dmedia%26token%3D1ea95ced-7824-43fc-8794-a32448ad89c8&width=768&dpr=4&quality=100&sign=b454b1c&sv=2) First, we can express IαI\_\\alphaIα​ and IβI\_\\betaIβ​ in terms of IaI\_aIa​, IbI\_bIb​, and IcI\_cIc​: Iα\=Ia+cos⁡(23π)Ib+cos⁡(43π)IcIβ\=sin⁡(23π)Ib+sin⁡(43π)Ic\\begin{aligned} I\_\\alpha &= I\_a + \\cos(\\frac{2}{3}\\pi)I\_b + \\cos(\\frac{4}{3}\\pi)I\_c \\\\ I\_\\beta &= \\sin(\\frac{2}{3}\\pi) I\_b + \\sin(\\frac{4}{3}\\pi)I\_c \\end{aligned}Iα​Iβ​​\=Ia​+cos(32​π)Ib​+cos(34​π)Ic​\=sin(32​π)Ib​+sin(34​π)Ic​​ Using Kirchhoff Circuit Laws, Ic\=Ia+IbI\_c = I\_a + I\_bIc​\=Ia​+Ib​, we can further simplify the equation to be the following Iα\=Ia+cos⁡(23π)Ib+cos⁡(43π)Ic\=Ia+cos⁡(23π)Ib−cos⁡(43π)Ia−cos⁡(43π)Ib\=Ia−12Ib+12Ia+12Ib\=32Ia\\begin{aligned} I\_\\alpha &= I\_a + \\cos(\\frac{2}{3}\\pi)I\_b + \\cos(\\frac{4}{3}\\pi)I\_c \\\\ &= I\_a + \\cos(\\frac{2}{3}\\pi)I\_b - \\cos(\\frac{4}{3}\\pi)I\_a - \\cos(\\frac{4}{3}\\pi)I\_b \\\\ &= I\_a - \\frac{1}{2}I\_b + \\frac{1}{2}I\_a + \\frac{1}{2}I\_b \\\\ &= \\frac{3}{2}I\_a \\end{aligned}Iα​​\=Ia​+cos(32​π)Ib​+cos(34​π)Ic​\=Ia​+cos(32​π)Ib​−cos(34​π)Ia​−cos(34​π)Ib​\=Ia​−21​Ib​+21​Ia​+21​Ib​\=23​Ia​​ Iβ\=sin⁡(23π)Ib+sin⁡(43π)Ic\=sin⁡(23π)Ib−sin⁡(43π)Ia−sin⁡(43π)Ib\=32Ib+32Ia+32Ib\=32Ia+3Ib\\begin{aligned} I\_\\beta &= \\sin(\\frac{2}{3}\\pi) I\_b + \\sin(\\frac{4}{3}\\pi)I\_c \\\\ &= \\sin(\\frac{2}{3}\\pi) I\_b - \\sin(\\frac{4}{3}\\pi)I\_a - \\sin(\\frac{4}{3}\\pi)I\_b \\\\ &= \\frac{\\sqrt{3}}{2}I\_b + \\frac{\\sqrt{3}}{2}I\_a + \\frac{\\sqrt{3}}{2}I\_b \\\\ &= \\frac{\\sqrt{3}}{2}I\_a + \\sqrt{3}I\_b \\end{aligned}Iβ​​\=sin(32​π)Ib​+sin(34​π)Ic​\=sin(32​π)Ib​−sin(34​π)Ia​−sin(34​π)Ib​\=23​​Ib​+23​​Ia​+23​​Ib​\=23​​Ia​+3​Ib​​ However, we also need to ensure that the magnitude of the signal should match. Therefore, we need to scale the result by factor of NNN. #### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#note) Note In an amplitude-invariant transformation, the normalization factor NNN should be set to 2/32 / 32/3, while a power-invariant transformation requires N\=2/3N = \\sqrt{2/3}N\=2/3​. For this FOC application, it is important to preserve the magnitude of the signals (i.e. phase current readings) during transformation, so we choose, so we set N\=2/3N = 2/3N\=2/3. [reference](https://zhuanlan.zhihu.com/p/172484981) After magnitude scaling, we get the final Clarke transform equation: {Iα\=IaIβ\=33Ia+233Iβ\\begin{cases} I\_\\alpha = I\_a \\\\ I\_\\beta = \\frac{\\sqrt{3}}{3}I\_a + \\frac{2\\sqrt{3}}{3}I\_\\beta \\end{cases}{Iα​\=Ia​Iβ​\=33​​Ia​+323​​Iβ​​ or in matrix format: \[IαIβ\]\=\[100332330\]\[IaIbIc\]\\begin{bmatrix} I\_\\alpha \\\\ I\_\\beta \\end{bmatrix} = \\begin{bmatrix} 1 & 0 & 0 \\\\ \\frac{\\sqrt{3}}{3} & \\frac{2\\sqrt{3}}{3} & 0 \\end{bmatrix} \\begin{bmatrix} I\_a \\\\ I\_b \\\\ I\_c \\end{bmatrix}\[Iα​Iβ​​\]\=\[133​​​0323​​​00​\]​Ia​Ib​Ic​​​ ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#dq-transform) DQ Transform Next, incorporating the information on rotor position θ\\thetaθ, the [Park transform](https://www.mathworks.com/help/mcb/ref/parktransform.html) can be used to convert the IαI\_\\alphaIα​ and IβI\_\\betaIβ​ components from the rotor reference frame to a stationary frame. This yields two stationary components, typically denoted as IdI\_dId​ (the direct axis component) and IqI\_qIq​ (the quadrature axis component). These stationary components simplify the motor control strategy by decoupling the torque and flux control. {Id\=cos⁡(θ)Iα+sin⁡(θ)IβIq\=−sin⁡(θ)Iα+cos⁡(θ)Iβ\\begin{cases} I\_d = \\cos(\\theta)I\_\\alpha + \\sin(\\theta)I\_\\beta \\\\ I\_q = -\\sin(\\theta)I\_\\alpha + \\cos(\\theta)I\_\\beta \\end{cases}{Id​\=cos(θ)Iα​+sin(θ)Iβ​Iq​\=−sin(θ)Iα​+cos(θ)Iβ​​ or in matrix format: \[IdIq\]\=\[cos⁡(θ)sin⁡(θ)−sin⁡(θ)cos⁡(θ)\]\[IαIβ\]\\begin{bmatrix} I\_d \\\\ I\_q \\end{bmatrix} = \\begin{bmatrix} \\cos(\\theta) & \\sin(\\theta) \\\\ -\\sin(\\theta) & \\cos(\\theta) \\end{bmatrix} \\begin{bmatrix} I\_\\alpha \\\\ I\_\\beta \\end{bmatrix}\[Id​Iq​​\]\=\[cos(θ)−sin(θ)​sin(θ)cos(θ)​\]\[Iα​Iβ​​\] After converting the three phase currents into stationary DQ currents using the Clarke and Park transforms, we now have a simplified representation that is much easier to control. However, our control is limited to adjusting the applied voltages. To regulate the current, we employ a controller that modulates the input voltage. A detailed discussion of this controller will be provided in the next section. For now, let's explore how the DQ voltage is converted back into the three phase voltages. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#inverse-dq-transform) Inverse DQ Transform Similarly, we can take the desired voltages VdV\_dVd​ and VqV\_qVq​ and use the inverse Park transform to convert them into signals VαV\_\\alphaVα​ and VβV\_\\betaVβ​ that rotate together with the rotor. {Vα\=cos⁡(θ)Vd−sin⁡(θ)VqVd\=sin⁡(θ)Vd+cos⁡(θ)Vq\\begin{cases} V\_\\alpha = \\cos(\\theta)V\_d -\\sin(\\theta)V\_q \\\\ V\_d = \\sin(\\theta)V\_d + \\cos(\\theta)V\_q \\end{cases}{Vα​\=cos(θ)Vd​−sin(θ)Vq​Vd​\=sin(θ)Vd​+cos(θ)Vq​​ or in matrix format: \[VαVβ\]\=\[cos⁡(θ)−sin⁡(θ)sin⁡(θ)cos⁡(θ)\]\[VqVd\]\\begin{bmatrix} V\_\\alpha \\\\ V\_\\beta \\end{bmatrix} = \\begin{bmatrix} \\cos(\\theta) & -\\sin(\\theta) \\\\ \\sin(\\theta) & \\cos(\\theta) \\end{bmatrix} \\begin{bmatrix} V\_q \\\\ V\_d \\end{bmatrix}\[Vα​Vβ​​\]\=\[cos(θ)sin(θ)​−sin(θ)cos(θ)​\]\[Vq​Vd​​\] #### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#note-1) Note Since rotation matrices are orthogonal, A−1\=ATA^{-1} = A^TA−1\=AT. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#svpwm) SVPWM Unlike the process of transforming current signals, converting voltage signals involves a different approach. This is because the applied voltage ultimately controls digital signals—either 0 or 1—that determine the switching of the MOSFETs in the upper and lower bridge arms, rather than influencing analog values from current measurements. Consequently, we must adopt an alternative method to discretize our desired voltage. From the six-step commutation scheme, we know that the motor driver can generate voltage vectors (or forces) pointing in six distinct directions. These can be thought of as six fundamental vectors originating from the center and directed toward 0°, 30°, 60°, and so on. By controlling the motor driver to rapidly switch between two states and adjusting the proportion of time spent in each state, we can synthesize a resultant voltage vector that points in a direction between the two fundamental vectors. Furthermore, by incorporating the two non-driving states—which effectively act as zero vectors—we can also adjust the magnitude of the resultant vector. Va\=cos⁡(0)Vα+sin⁡(0)Vβ\=VαV\_a = \\cos(0)V\_\\alpha + \\sin(0) V\_\\beta = V\_\\alphaVa​\=cos(0)Vα​+sin(0)Vβ​\=Vα​ Vb\=cos⁡(23π)Vα+sin⁡(23π)Vβ\=−12Vα+32VβV\_b = \\cos(\\frac{2}{3}\\pi)V\_\\alpha + \\sin(\\frac{2}{3}\\pi) V\_\\beta = -\\frac{1}{2} V\_\\alpha + \\frac{\\sqrt{3}}{2} V\_\\betaVb​\=cos(32​π)Vα​+sin(32​π)Vβ​\=−21​Vα​+23​​Vβ​ Vc\=cos⁡(43π)Vα+sin⁡(43π)Vβ\=−12Vα−32VβV\_c = \\cos(\\frac{4}{3}\\pi)V\_\\alpha + \\sin(\\frac{4}{3}\\pi) V\_\\beta = -\\frac{1}{2} V\_\\alpha - \\frac{\\sqrt{3}}{2} V\_\\betaVc​\=cos(34​π)Vα​+sin(34​π)Vβ​\=−21​Vα​−23​​Vβ​ As a result, we have: {Va\=VαVb\=−12Vα+32VβVb\=−12Vα−32Vβ\\begin{cases} V\_a = V\_\\alpha \\\\ V\_b = -\\frac{1}{2}V\_\\alpha + \\frac{\\sqrt{3}}{2}V\_\\beta \\\\ V\_b = -\\frac{1}{2}V\_\\alpha - \\frac{\\sqrt{3}}{2}V\_\\beta \\end{cases}⎩⎨⎧​Va​\=Vα​Vb​\=−21​Vα​+23​​Vβ​Vb​\=−21​Vα​−23​​Vβ​​ or in matrix format: \[VaVbVc\]\=\[10−1232−12−32\]\[VαVβ\]\\begin{bmatrix} V\_a \\\\ V\_b \\\\ V\_c \\end{bmatrix} = \\begin{bmatrix} 1 & 0 \\\\ -\\frac{1}{2} & \\frac{\\sqrt{3}}{2} \\\\ -\\frac{1}{2} & -\\frac{\\sqrt{3}}{2} \\end{bmatrix} \\begin{bmatrix} V\_\\alpha \\\\ V\_\\beta \\end{bmatrix}​Va​Vb​Vc​​​\=​1−21​−21​​023​​−23​​​​\[Vα​Vβ​​\] ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#theoratical-maximum-rpm) Theoratical Maximum RPM To control the motor correctly during high speed region, the **FOC commutation frequency** must be significantly higher than the **electrical frequency** of the motor. A general rule is that commutation frequency must be at least 10x the electrical frequency. The motor’s mechanical frequency can then be calculated from the electrical frequency and pole pair: fmech\=felecNppf\_{mech} = \\frac{f\_{elec}}{N\_{pp}}fmech​\=Npp​felec​​ NppN\_{pp}Npp​ is the number of pole pairs. For example, for a motor with 14 pole pair, if FOC commutation is set to 10 kHz. Then, the maximum supported electrical frequency is 1 kHz. The maximum mechanical frequency would then be: fmech\=1 kHz14\=71 rad/s\=678 RPMf\_{mech} = \\frac{1 \\text{ kHz}}{14} = 71 \\text{ rad/s} = 678 \\text{ RPM}fmech​\=141 kHz​\=71 rad/s\=678 RPM [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-5.-current-loop) 5\. Current Loop -------------------------------------------------------------------------------------------------------------------------------------------------- As mentioned above, our objective is to regulate the currents IdI\_dId​ and IqI\_qIq​. To accomplish this, we control the voltages VdV\_dVd​ and VqV\_qVq​ applied to the motor. A straightforward method to map these voltage inputs to the desired current outputs is by using a proportional-integral (PI) controller. ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#dc-motor-model) DC Motor Model ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252F77iKw9BrMtqPim6UdkPM%252Fdc-motor.png%3Falt%3Dmedia%26token%3D9fcfcb31-1b74-47a6-9197-fd44c800b3b0&width=768&dpr=4&quality=100&sign=5aae576e&sv=2) In the simplified DC motor model, the motor can be seen as a resistor and inductor in series. Therefore, the voltage across the motor can be written as: V\=IR+LdIdt+kemfωV = IR + L\\frac{dI}{dt} + k\_{emf}\\omegaV\=IR+LdtdI​+kemf​ω where III is the current flowing through the motor winding, RRR is the resistance of the motor winding, LLL is the inductance of the motor winding, kemfk\_{emf}kemf​ is the back-EMF coefficient, and ω\\omegaω is the rotation speed. #### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#note-2) Note The resistance here is not the **winding resistance**. It is the equivalent resistance we get after performing the Clarke and Park transformation. Same applies for the inductance. Since we are focusing on low-rpm scenario, the back-EMF term can be ignored, simplifying the equation to be: V\=IR+LdIdtV = IR + L\\frac{dI}{dt}V\=IR+LdtdI​ Performing Laplace transform to the equation, we get: V(s)\=I(s)R+LsI(s)−LI(0)V(s) = I(s)R + LsI(s) - LI(0)V(s)\=I(s)R+LsI(s)−LI(0) We can assume the initial condition to be I(0)\=0I(0) = 0I(0)\=0, hence getting: V(s)\=I(s)R+LsI(s)V(s) = I(s)R + LsI(s)V(s)\=I(s)R+LsI(s) As a result, the transfer function of the motor is: M(s)\=I(s)V(s)\=1R+Ls\=1R1+LRsM(s) = \\frac{I(s)}{V(s)} = \\frac{1}{R + Ls} = \\frac{\\frac{1}{R}}{1 + \\frac{L}{R}s}M(s)\=V(s)I(s)​\=R+Ls1​\=1+RL​sR1​​ ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#pi-controllers) PI Controllers There are two configurations of PI controller, the parallel configuration (the most common one) and the series configuration. #### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#parallel-pi-controller) Parallel PI Controller For parallel configuration, we have c(t)\=kpe(t)+ki∫e(t)dtC(s)\=kp+kis\=kps+kis\\begin{aligned} c(t) &= k\_p e(t) + k\_i \\int e(t) dt \\\\ C(s) &= k\_p + \\frac{k\_i}{s} = \\frac{k\_p s + k\_i}{s} \\end{aligned}c(t)C(s)​\=kp​e(t)+ki​∫e(t)dt\=kp​+ski​​\=skp​s+ki​​​ ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FdLodojPjnorqCAl29iyF%252Fparallel-pi-controller.png%3Falt%3Dmedia%26token%3D64f395e4-01ae-42f4-96bc-29fe4ebd64ed&width=768&dpr=4&quality=100&sign=55190af5&sv=2) #### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#serial-pi-controller) Serial PI Controller For series configuration, we have c(t)\=kp′e(t)+kp′ki′∫e(t)dtC(s)\=kp′(1+kis)\=kp′s+kp′ki′s\\begin{aligned} c(t) &= k\_p' e(t) + k\_p' k\_i' \\int e(t) dt \\\\ C(s) &= k\_p' (1 + \\frac{k\_i}{s}) = \\frac{k\_p's + k\_p'k\_i'}{s} \\end{aligned}c(t)C(s)​\=kp′​e(t)+kp′​ki′​∫e(t)dt\=kp′​(1+ski​​)\=skp′​s+kp′​ki′​​​ ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FhQTqyJUPE0NK9mNNdOKb%252Fserial-pi-controller.png%3Falt%3Dmedia%26token%3De3a49f2e-1255-4daf-82ba-447f8920b778&width=768&dpr=4&quality=100&sign=b27e9034&sv=2) Since the subsequent calculations are more straightforward with a series PI controller, we will adopt this configuration. Example C implementation of the serial PI controller Copy float kp, ki; float target, measured; float limit; // integrator anti-windup value float dt; // loop execution time float integrator; float error = target - measured; integrator = clampf(integrator + kp * ki * error * dt, -limit, limit); float result = kp * error + integrator; ### [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#system-model) System Model For open loop control, we have the transfer function as: Gopen(s)\=M(s)C(s)\=1R1+LRskp′s+kp′ki′s\=1R1+LRskp′ki′ski′+1s\\begin{aligned} G\_{open}(s) &= M(s)C(s) \\\\ &= \\frac{\\frac{1}{R}}{1 + \\frac{L}{R}s} \\frac{k\_p's + k\_p'k\_i'}{s} \\\\ &= \\frac{\\frac{1}{R}}{1 + \\frac{L}{R}s} k\_p'k\_i' \\frac{\\frac{s}{k\_i'} + 1}{s} \\end{aligned}Gopen​(s)​\=M(s)C(s)\=1+RL​sR1​​skp′​s+kp′​ki′​​\=1+RL​sR1​​kp′​ki′​ski′​s​+1​​ In order to simplify the equation, we want 1+LRs\=ski′+11 + \\frac{L}{R}s = \\frac{s}{k\_i'} + 1 1+RL​s\=ki′​s​+1 which means ki′\=RLk\_i' = \\frac{R}{L}ki′​\=LR​ Setting ki′\=RLk\_i' = \\frac{R}{L}ki′​\=LR​, we can simplify the equation as Gopen(s)\=kp′ki′1RsG\_{open}(s) = k\_p'k\_i' \\frac{\\frac{1}{R}}{s}Gopen​(s)\=kp′​ki′​sR1​​ For closed-loop feedback control, we have the transfer function as Gclosed(s)\=Gopen(s)1+Gopen(s)G\_{closed}(s) = \\frac{G\_{open}(s)}{1 + G\_{open}(s)}Gclosed​(s)\=1+Gopen​(s)Gopen​(s)​ Therefore, Gclosed\=kp′ki′1Rs1+kp′ki′1RsG\_{closed} = \\frac{k\_p'k\_i' \\frac{\\frac{1}{R}}{s}}{1 + k\_p'k\_i' \\frac{\\frac{1}{R}}{s}}Gclosed​\=1+kp′​ki′​sR1​​kp′​ki′​sR1​​​ Substituting ki′\=RLk\_i' = \\frac{R}{L}ki′​\=LR​, into the equation, we get: Gclosed\=kp′RL1Rs1+kp′RL1Rs\=kp′1Ls+kp′1L\=1skp′L+1G\_{closed} = \\frac{k\_p'\\frac{R}{L} \\frac{\\frac{1}{R}}{s}}{1 + k\_p'\\frac{R}{L} \\frac{\\frac{1}{R}}{s}} = \\frac{k\_p' \\frac{1}{L}}{s + k\_p '\\frac{1}{L}} = \\frac{1}{\\frac{s}{\\frac{k\_p'}{L}} + 1}Gclosed​\=1+kp′​LR​sR1​​kp′​LR​sR1​​​\=s+kp′​L1​kp′​L1​​\=Lkp′​​s​+11​ The coefficient kp′L\\frac{k\_p'}{L}Lkp′​​ determines the frequency where the system response decreases by 3dB, or, the response cutoff bandwidth ω. The unit is rad / s. In other words, we have kp′\=L∗ωcutoffk\_p' = L \* \\omega\_{cutoff}kp′​\=L∗ωcutoff​ ωcutoff\=kp′L\\omega\_{cutoff} = \\frac{k\_p'}{L}ωcutoff​\=Lkp′​​ with ω\=2πf\\omega = 2\\pi fω\=2πf, fcutoff\=12πkp′Lf\_{cutoff} = \\frac{1}{2\\pi}\\frac{k\_p'}{L}fcutoff​\=2π1​Lkp′​​ Usually in practice, we want to ensure that the current bandwidth is less than 10% of the switching frequency, i.e. 20% of the Nyquist rate. {kp′\=2πfsampleLki′\=RL\\begin{cases} k\_{p}' = 2\\pi f\_{sample} L \\\\ k\_i' = \\frac{R}{L} \\end{cases}{kp′​\=2πfsample​Lki′​\=LR​​ For example, if the switching frequency is 20kHz, the maximum bandwidth would be 2kHz. {kp,2kHz′\=2πL∗2∗103ki′\=RL\\begin{cases} k\_{p, 2kHz}' = 2 \\pi L \* 2\*10^3 \\\\ k\_i' = \\frac{R}{L} \\end{cases}{kp,2kHz′​\=2πL∗2∗103ki′​\=LR​​ **Reference:** [Digital PI Controller Equations](https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/902/PI-controller-equations.pdf) [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-6.-torque-control) 6\. Torque Control ------------------------------------------------------------------------------------------------------------------------------------------------------ Usually, we want to control the motor's output torque, instead of the current. Therefore, we must establish the relation between current IqI\_qIq​ and the output torque τ\\tauτ. The torque is proportional to the phase current, with a factor of motor torque constant KτK\_\\tauKτ​. τ\=Kτ×Iphase\\tau = K\_\\tau \\times I\_{phase}τ\=Kτ​×Iphase​ However, for the drone BLDC motors, vendors typically only provide the KV rating, representing the revolution per minute per volt applied between the motor phases. A typical measurement process of this KV value is to rotate the motor at a specific rotation speed and measure the peak-to-peak voltage difference between two phases. Hence, this KV value equals to the line-to-line back EMF voltage of the motor. To convert the KV rating to motor torque constant, two caveats need to be paied attention for. The first thing is the unit conversion. KV is given in revolution per minute. To convert it to the SI unit radius per second per volt, we need to use KV,SI\=2π60KVK\_{V,SI} = \\frac{2\\pi}{60}K\_VKV,SI​\=602π​KV​. Another aspect is that the measurement of KV is done between two phases of the motor, which the reference frame is different from the DQ frame the PI controller are situated at. To convert it to the correct DQ frame, the following equation establishes: Kτ\=12KV,SI\=122π60KV≈0.0740KVK\_\\tau = \\frac{1}{\\sqrt{2}} K\_{V,SI} = \\frac{1}{\\sqrt{2}}\\frac{2\\pi}{60} K\_V \\approx 0.0740 K\_{V}Kτ​\=2​1​KV,SI​\=2​1​602π​KV​≈0.0740KV​ [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-7.-position-loop) 7\. Position Loop ---------------------------------------------------------------------------------------------------------------------------------------------------- Similar to current control loop, we can build a PD controller to regulate the rotor position by controlling the target torque. [](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/field-oriented-control-foc-operation#id-8.-conclusion) 8\. Conclusion ---------------------------------------------------------------------------------------------------------------------------------------------- As a result, we get the following motor controller block diagram. We can inject user control targets at different stage to achieve control of each quantity (e.g. position, velocity, torque, current, or voltage control). ![](https://berkeley-humanoid-lite.gitbook.io/docs/~gitbook/image?url=https%3A%2F%2F2396875388-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FJ943fa7TiyZgDTAM8Bt7%252Fuploads%252FzlTX0wqbt72nfIfwplHd%252Frecoil-motor-controller-block-diagram.png%3Falt%3Dmedia%26token%3D9073ec29-b4c8-42fd-801b-e56fefb4fc32&width=768&dpr=4&quality=100&sign=fb110e52&sv=2) [PreviousIn-depth Contents](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents) [NextMotor Controller Firmware Execution Timing Information](https://berkeley-humanoid-lite.gitbook.io/docs/in-depth-contents/motor-controller-firmware-execution-timing-information) Last updated 5 months ago ---