{
    "componentChunkName": "component---src-components-page-template-jsx",
    "path": "/guides/main/getting-started",
    "result": {"data":{"mdx":{"id":"9e25b015-ab8b-5aeb-85cd-3207c74a7edd","body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"section\": \"Guides\",\n  \"chapter\": \"Main Codebase\",\n  \"title\": \"Getting Started\",\n  \"description\": \"Setting up your environment and getting started with NUbots development.\",\n  \"slug\": \"/guides/main/getting-started\",\n  \"authors\": [\"Ysobel Sims (@ysims)\", \"Josephus Paye II (@JosephusPaye)\", \"Mikyla Peters (@miikyla)\", \"Lachlan Court (@LachlanCourt)\", \"Corah Oliver (@yippyy)\", \"Thomas O'Brien (@Tom0brien)\"]\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar Alert = makeShortcode(\"Alert\");\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Throughout this guide we will focus on completing a specific example task. This task will involve setting up the codebase, running the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \" binary (which uses simulated hardware) and seeing the robot move in NUsight.\"), mdx(\"h2\", {\n    \"id\": \"prerequisites\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#prerequisites\",\n    \"aria-label\": \"prerequisites permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Prerequisites\"), mdx(\"h3\", {\n    \"id\": \"git\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#git\",\n    \"aria-label\": \"git permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Git\"), mdx(\"p\", null, \"For our example, we will need Git to get the codebase later on in this guide.\"), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://git-scm.com/\"\n  }, \"Git\"), \" is a \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control\"\n  }, \"version control\"), \" tool. We use it to track changes to the codebase and work together on the same codebase without getting in each other's way.\"), mdx(\"p\", null, \"To work on the NUbots code, you'll need to know the basics of using Git, specifically:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"how to clone remote repositories onto your computer\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"how to create branches\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"how to add and commit changes\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"how to fetch, pull, and push changes\")), mdx(\"p\", null, \"You can do all the above using \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://git-scm.com/docs/git\"\n  }, \"Git in the terminal\"), \", or you can use a Git GUI tool such as \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://www.gitkraken.com/\"\n  }, \"GitKraken\"), \" or \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://desktop.github.com/\"\n  }, \"GitHub Desktop\"), \".\\nThere is a guide to using Git in NUbots \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/guides/general/git\"\n  }, \"here\"), \".\"), mdx(\"h3\", {\n    \"id\": \"docker\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#docker\",\n    \"aria-label\": \"docker permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Docker\"), mdx(\"p\", null, \"Docker is a container system that allows you to install development tools and run builds in an isolated environment that won't affect the rest of your system. We use it to set up the NUbots build system and run builds and binaries.\"), mdx(\"p\", null, \"You will need to perform the steps correctly to set up Docker for your operating system to complete the example.\"), mdx(\"details\", null, mdx(\"summary\", null, \"Ubuntu\"), mdx(\"p\", null, \"To install on Ubuntu, use the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.docker.com/engine/install/ubuntu/\"\n  }, \"official Docker instructions\"), \". These instructions should work for Ubuntu-like Linux distributions, such as Pop!\", \"_\", \"OS. There are multiple ways to install Docker, as detailed on the website. NUbots recommends the following for installing Docker\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Navigate to the section for \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository\"\n  }, \"installing using the Apt repository\"), \". Complete the three steps under this section.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Install python3 and pip.\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"sudo apt-get install python3 python3-pip\\n\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Add the current user to the Docker group, so you can run Docker commands without \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo\"), \".\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"sudo usermod -aG docker \\\"${USER}\\\"\\n\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Reboot to make the group change take effect.\")))), mdx(\"details\", null, mdx(\"summary\", null, \" MacOS \"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Install Homebrew by following the instructions at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://brew.sh/\"\n  }, \"brew.sh\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Install Python 3 and Docker using Homebrew.\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"brew install python3\\nbrew cask install docker\\n\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Run the Docker Desktop app that was installed and ensure that Docker is running by checking that it shows a green dot in the app menu bar.\"), mdx(\"img\", {\n    parentName: \"li\",\n    \"src\": \"/opt/build/repo/src/book/03-guides/01-main-codebase/images/docker-running-mac.png\",\n    \"alt\": \"Top right screenshot of a macOS system shows the Docker icon with a dropdown menu. The first line in the menu is highlighted and reads 'Docker desktop is running'.\"\n  })), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Go to \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Advanced settings\"), \" in Docker Desktop's \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Preferences\"), \" and increase the memory available to containers to at least 4GB. By default Docker will allocate 2GB of memory to containers, which is not enough to build the NUbots docker image.\")))), mdx(\"details\", null, mdx(\"summary\", null, \"Windows\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Ensure your Windows build is at least 2004.\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Press \", mdx(\"kbd\", null, \"WIN\"), \" + \", mdx(\"kbd\", null, \"R\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Type \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"winver\"), \" and hit \", mdx(\"kbd\", null, \"Enter\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Inspect the version to verify it is at least 2004. Upgrade Windows if not.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Enable WSL 2\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Open Windows Powershell in administrator mode.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Run the following to install WSL:\", mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart\\n\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Run the following to enable the Virtual Machine Platform feature needed for WSL:\", mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart\\n\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Restart your computer.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Go to the Microsoft Store. Search for '\", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Ubuntu 22.04.3 LTS\"), \"' and install it. Launch Ubuntu.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Ensure Ubuntu is using WSL 2.\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"In Powershell, run:\", mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"wsl --list --verbose\\n\"))), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"If the version is not 2, run:\", mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"wsl --set-version Ubuntu-22.04.3 2\\n\")))), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, \" Note that 'ubuntu' in the last command may need to be capitalised. Check the exact spelling from the list output in the first command of this step. \"), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"If you have issues with the Linux kernel needing to be updated, get the update from the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.microsoft.com/en-us/windows/wsl/wsl2-kernel\"\n  }, \"Microsoft page\"), \".\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Download and install \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.docker.com/docker-for-windows/install/\"\n  }, \"Docker for Windows\"), \". Choose the latest stable version. Ensure you enable WSL 2 features.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Configure Docker settings.\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"In the system tray, right-click the Docker icon and select \", mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Settings\"), \".\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"In \", mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"General\"), \", enable the \", mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Use the WSL 2 based engine\"), \" option.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"In \", mdx(\"strong\", {\n    parentName: \"li\"\n  }, \"Resources: WSL Integration\"), \" enable Ubuntu.\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"In Ubuntu run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo apt update\"), \" followed by \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo apt upgrade\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Ensure you have pip3 by running\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"sudo apt install python3-pip\\n\")))), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, \"The commands in the rest of this guide should be run in the WSL Ubuntu terminal except where specified to run them elsewhere, such as on a real robot.\"), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"When you clone/download the code, you should do so in the WSL Ubuntu terminal, from your home folder. Run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cd ~\"), \" to navigate to your home folder in Ubuntu.\"), mdx(\"p\", null, \"Outside of WSL, the path to the cloned NUbots code folder will be of the form \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"\\\\\\\\wsl$\\\\Ubuntu\\\\home\\\\<USERNAME>\\\\NUbots\"), \", where \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<USERNAME>\"), \" is the username you set up for Ubuntu. This path should be the one you use to open the code in text editors such as Visual Studio Code.\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"GitKraken will not allow you to open the repository outside of WSL. Use the steps described in this article to \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://medium.com/@chuckdries/installing-gitkraken-in-wsl-2-15bf6459f823\"\n  }, \"set up your system to use GitKraken in WSL\"), \".\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"To be able to copy and paste into the Ubuntu terminal, right-click on the bar at the top of the Ubuntu window. Then click on \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Properties\"), \", and enable \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Use Ctrl+Shift+C/V as Copy/Paste\"), \" in the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Options\"), \" tab. Note that this is \", mdx(\"kbd\", null, \"Ctrl\"), \"+\", mdx(\"kbd\", null, \"Shift\"), \"+\", mdx(\"kbd\", null, \"C\"), \"/\", mdx(\"kbd\", null, \"V\"), \" not \", mdx(\"kbd\", null, \"Ctrl\"), \"+\", mdx(\"kbd\", null, \"C\"), \"/\", mdx(\"kbd\", null, \"V\"), \".\"))), mdx(\"h3\", {\n    \"id\": \"a-text-editor\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#a-text-editor\",\n    \"aria-label\": \"a text editor permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"A Text Editor\"), mdx(\"p\", null, \"This section is not required for our example, but it is a good step to do in case you need to edit code in the future.\"), mdx(\"p\", null, \"You'll need a text editor to make changes to the code. We recommend \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://code.visualstudio.com/Download\"\n  }, \"Visual Studio Code\"), \", but feel free to use your favourite editor.\"), mdx(\"p\", null, \"To ensure a consistent \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://en.wikipedia.org/wiki/Programming_style\"\n  }, \"code style\"), \", NUbots uses \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://clang.llvm.org/docs/ClangFormat.html\"\n  }, \"clang-format\"), \", a tool that reformats code files in the repository to have the same style, even if they're written by different people. For convenience, you can install the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"clang-format\"), \" \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/xaverh/vscode-clang-format\"\n  }, \"extension\"), \" in Visual Studio Code to automatically format the files when you make changes.\"), mdx(\"p\", null, \"Another useful tool for editing NUbots code in Visual Studio Code is the Remote Development \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://code.visualstudio.com/docs/remote/containers\"\n  }, \"extension pack\"), \". This pack allows Visual Studio Code to work from within the Docker container, using the tools and libraries installed there.\"), mdx(\"h2\", {\n    \"id\": \"getting-the-code\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#getting-the-code\",\n    \"aria-label\": \"getting the code permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Getting the Code\"), mdx(\"p\", null, \"With all the prerequisites in place, you can now clone the NUbots repository from GitHub to build it and run the code. This is an important step in our example.\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Clone the repo and change into the cloned directory.\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"git clone --recursive https://github.com/NUbots/NUbots.git\\ncd NUbots\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"The repo will be cloned into a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"NUbots\"), \" directory in the current working directory.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"We use \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.astral.sh/uv/\"\n  }, \"UV\"), \" to manage Python dependencies. Install UV using the official installer:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"curl -LsSf https://astral.sh/uv/install.sh | sh\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"This command downloads and executes the official installation script for UV. For more details on installing, see the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://docs.astral.sh/uv/getting-started/installation/\"\n  }, \"official documentation\"), \". Once UV is installed, the build system (\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./b\"), \") will use it to handle Python dependencies specified in the project.\"))), mdx(\"h2\", {\n    \"id\": \"building-the-code\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#building-the-code\",\n    \"aria-label\": \"building the code permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Building the Code\"), mdx(\"p\", null, \"Run all these commands for our example, and pay special attention to the instructions in the second step relating to our example.\"), mdx(\"p\", null, \"To build the code, open a terminal and change into the NUbots code directory. Then do the following:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Select the platform (type of computer) that the built binaries will run on and create the Docker image. You do this by running the command:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b target <PLATFORM>\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Replace \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<PLATFORM>\"), \" with your desired platform. The available platforms are:\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"generic\"), \" - used to build the code for a \\\"generic\\\" computer. This will enable you to run the built binaries on the computer you're building the code on.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"nuc12wshi7\"), \" - used to build the code for the platform that the robots run on. This will build binaries that are optimised for the NUgus robots.\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"If you are following the example, use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"generic\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"With the target platform selected, choose the binaries (called \\\"roles\\\") that you want to build. You do this by running the following command:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b configure\\n./b configure -i\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Note that you will need to do \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"configure\"), \" without \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-i\"), \" the very first time you do this. Using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"-i\"), \" will show a menu that will allow you to choose the roles to build. Enable the roles you want to build and disable the ones you don't by highlighting them using the \", mdx(\"kbd\", null, \"\\u2191\"), \" and \", mdx(\"kbd\", null, \"\\u2193\"), \" arrow keys and pressing the spacebar to toggle on and off.\"), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"If you are following the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \" example, you will need to make sure \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ROLE_fake-keyboardwalk\"), \" is set to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ON\"), \". Find the list of items that are prefixed with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ROLE_\"), \" and set all to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"OFF\"), \" except for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake-keyboardwalk\"), \", which should be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ON\"), \". You do not need to change any other build options in this example.\"), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Press \", mdx(\"kbd\", null, \"c\"), \" to configure. Once configuration has finished, press \", mdx(\"kbd\", null, \"g\"), \" to generate the build list. Press \", mdx(\"kbd\", null, \"e\"), \" to exit if it has not automatically returned you to the terminal.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Build the code by running:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b build\\n\")))), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"If your computer struggles to build and crashes, run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./b build -jx\"), \", where x is the number of cores you want to use. A good recommended amount of cores is five, but if you still struggle perhaps use one core.\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"Some built roles use data from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".yaml\"), \" \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/system/foundations/config-script\"\n  }, \"configuration files\"), \". If you change a configuration file, you will need to run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./b build\"), \" again.\")), mdx(\"h2\", {\n    \"id\": \"running-the-code\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#running-the-code\",\n    \"aria-label\": \"running the code permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Running the Code\"), mdx(\"p\", null, \"With the code built, you can run the code on a real robot or on your computer using a simulated robot. If you are following the example in this guide, go to 'Running with a Simulated Robot' below, and skip 'Running on a Real Robot'.\"), mdx(\"h3\", {\n    \"id\": \"running-with-a-simulated-robot\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#running-with-a-simulated-robot\",\n    \"aria-label\": \"running with a simulated robot permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Running with a Simulated Robot\"), mdx(\"p\", null, \"If you are not running the code on a robot, you will need to use a simulated robot. If, for example, you want to run a role called \\\"test\\\", you would run\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b run test\\n\")), mdx(\"p\", null, \"Roles run this way generally contain \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"platform::HardwareSimulator\"), \", a module that simulates robot hardware input and output, or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"platform::Webots\"), \", a module that communicates with the simulated robot in Webots.\"), mdx(\"p\", null, \"If you are following the example, run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./b run fake/keyboardwalk\"), \".\"), mdx(\"h3\", {\n    \"id\": \"running-on-a-real-robot\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#running-on-a-real-robot\",\n    \"aria-label\": \"running on a real robot permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Running on a Real Robot\"), mdx(Alert, {\n    type: \"warn\",\n    mdxType: \"Alert\"\n  }, \"When running on a real robot, make sure you understand how to safely handle a robot. To make the robot's servos relax, hit the red button on the back of the robot. This is an emergency stop button to prevent harm.\"), mdx(\"p\", null, \"You can skip this section if you are following the example.\"), mdx(\"p\", null, \"To run the code on a robot, you need to make sure the robot is powered on, install the built roles onto the robot, and then \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ssh\"), \" into the robot to run the installed roles.\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Install the built roles onto a robot by running:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b install [options] <robot>\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Where:\"), mdx(\"ul\", {\n    parentName: \"li\"\n  }, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"[options]\"), \" corresponds to zero, one, or multiple options as detailed in the \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"/system/foundations/build-system#install\"\n  }, \"Build System\"), \" page\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"<robot>\"), \" corresponds to the name of the robot such as \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"n1\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"nugus1\"), \", or an IP address\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Next, open a new terminal and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ssh\"), \" into the robot by running:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"ssh nubots@<address>\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Where \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<address>\"), \" is the IP address of the robot, in the form \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"10.1.1.x\"), \", with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"x\"), \" being the specific robot's number, i.e. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"1\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"2\"), \", or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"3\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Now you can run any role you have built and installed onto the robot. For example, if you built the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"scriptrunner\"), \" role and want to make the robot stand up, you would run:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./scriptrunner Stand.yaml\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"This will start the binary to run the stand script, but the robot won't move until you press the green middle button on its back.\"), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"In addition to the stand script, the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"scriptrunner\"), \" role can run other scripts. These can be found in the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"scripts\"), \" folder. See \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/system/foundations/config-script\"\n  }, \"Configuration and Script System\"), \" for details.\"), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"You can also run other roles that are not \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"scriptrunner\"), \". For example, to run the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"robocup\"), \" role enter the command:\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./robocup\\n\")))), mdx(\"h2\", {\n    \"id\": \"get-build-and-run-nusight\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#get-build-and-run-nusight\",\n    \"aria-label\": \"get build and run nusight permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Get, Build and Run NUsight\"), mdx(\"p\", null, \"NUsight is a visual debugging web application used at NUbots that visually represents what the robot is doing. It can be used to view output from any platform, whether that is a real NUgus robot or a simulation. Read more on the capabilities of NUsight on the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"/system/tools/nusight\"\n  }, \"NUsight page\"), \".\"), mdx(\"p\", null, \"NUsight is needed to see the robot walking when we run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \".\"), mdx(\"p\", null, \"Open up a new terminal to run NUsight and NUbots code side by side.\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Get the dependencies for NUsight by running\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b yarn\\n\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Build NUsight by running\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b yarn build\\n\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Find the IP address of the Docker container.\"), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"In Linux, run\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"ifconfig\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"In Windows WSL, make sure you are running a binary (eg \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \") in your original terminal, and in your second terminal run\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps | grep nubots:selected | cut -d \\\" \\\" -f1)\\n\")), mdx(\"p\", {\n    parentName: \"li\"\n  }, \"There will be an entry called \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"docker0\"), \", or similar. Find the address after the word \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"broadcast\"), \". We will refer to this address as \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"<ADDRESS>\"), \".\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Run the following command to run NUsight\"), mdx(\"pre\", {\n    parentName: \"li\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-bash\"\n  }, \"./b yarn prod --address <ADDRESS>\\n\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"If you are on the NUbots lab network \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"epsilon-z\"), \" you do not need the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"--address\"), \" argument. Just run \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"./b yarn prod\"), \".\"))), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"The terminal will output a link - \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"localhost:9090\"\n  }, \"localhost:9090\"), \". Visit it to view NUsight.\"))), mdx(\"h2\", {\n    \"id\": \"example\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#example\",\n    \"aria-label\": \"example permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Example\"), mdx(\"p\", null, \"In this section we will finish off our example of setting up the codebase, running the fake/keyboardwalk binary and seeing the robot walk in NUsight.\"), mdx(\"p\", null, \"By now you will have gone through this page and have everything set up to make the robot walk. Ensure you have all the following steps complete\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Prerequisite: Git\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Prerequisite: Docker\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Getting the Code\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Building the Code\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Running the Code: Running with a Simulated Robot\")), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Build and Run NUsight\"))), mdx(\"p\", null, \"With the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \" binary running, and with NUsight running and your browser open to \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"localhost:9090\"\n  }, \"localhost:9090\"), \", do the following\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"Select the 'localisation' tab in NUsight.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"You will see a stationary robot. To focus on the robot, click inside the window and press \", mdx(\"kbd\", null, \"space\"), \" to change perspective.\")), mdx(\"li\", {\n    parentName: \"ol\"\n  }, mdx(\"p\", {\n    parentName: \"li\"\n  }, \"To make the robot walk, go into the terminal that is running \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"fake/keyboardwalk\"), \" and hit \", mdx(\"kbd\", null, \"e\"), \" to enable walking. Use \", mdx(\"kbd\", null, \"w\"), \", \", mdx(\"kbd\", null, \"a\"), \", \", mdx(\"kbd\", null, \"s\"), \" and \", mdx(\"kbd\", null, \"d\"), \" to make the robot move. Note that this is a basic simulation that does not use gravity, so the robot will move its limbs but may not move in the world.\"))));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#prerequisites","title":"Prerequisites","items":[{"url":"#git","title":"Git"},{"url":"#docker","title":"Docker"},{"url":"#a-text-editor","title":"A Text Editor"}]},{"url":"#getting-the-code","title":"Getting the Code"},{"url":"#building-the-code","title":"Building the Code"},{"url":"#running-the-code","title":"Running the Code","items":[{"url":"#running-with-a-simulated-robot","title":"Running with a Simulated Robot"},{"url":"#running-on-a-real-robot","title":"Running on a Real Robot"}]},{"url":"#get-build-and-run-nusight","title":"Get, Build and Run NUsight"},{"url":"#example","title":"Example"}]},"frontmatter":{"section":"Guides","chapter":"Main Codebase","title":"Getting Started","description":"Setting up your environment and getting started with NUbots development.","keywords":null,"slug":"/guides/main/getting-started","hidden":null},"childNUbookContributions":{"authors":[{"name":"Ysobel Sims","username":"ysims"},{"name":"Josephus Paye II","username":"JosephusPaye"},{"name":"Mikyla Peters","username":"miikyla"},{"name":"Lachlan Court","username":"LachlanCourt"},{"name":"Corah Oliver","username":"yippyy"},{"name":"Thomas O'Brien","username":"Tom0brien"}],"lastCommit":{"date":"2025-05-05T09:36:38.000Z","hash":"39316a9c3978e60d0044ca74b6d427bcc33b4cfb"}}}},"pageContext":{"mdxPath":"src/book/03-guides/01-main-codebase/01-getting-started.mdx","id":"9e25b015-ab8b-5aeb-85cd-3207c74a7edd","next":{"chapter":"Main Codebase","title":"NUClear","description":"Creating a NUClear module.","slug":"/guides/main/nuclear-tutorial","hidden":null},"previous":{"chapter":"Modules","title":"Vision","description":"Documentation for each vision module in the main NUbots codebase","slug":"/system/modules/vision/","hidden":null},"menu":[{"title":"Team","slug":"/team/introduction","chapters":[{"title":"Introduction","slug":"/team/introduction","pages":[{"title":"Introduction to NUbots","slug":"/team/introduction","hidden":null},{"title":"Areas of Research","slug":"/team/areas-of-research","hidden":null},{"title":"Current Team","slug":"/team/current-members","hidden":null}],"hidden":false},{"title":"Joining the Team","slug":"/team/how-we-work","pages":[{"title":"How We Work","slug":"/team/how-we-work","hidden":null},{"title":"How to Join NUbots","slug":"/team/how-to-join","hidden":null},{"title":"Lab Induction","slug":"/team/induction","hidden":null}],"hidden":false},{"title":"Community","slug":"/team/sponsors","pages":[{"title":"Sponsors","slug":"/team/sponsors","hidden":null},{"title":"Connect","slug":"/team/connect","hidden":null}],"hidden":false},{"title":"History","slug":"/team/history","pages":[{"title":"Team History","slug":"/team/history","hidden":null},{"title":"Past Members","slug":"/team/past-members","hidden":null},{"title":"Publications","slug":"/team/publications","hidden":null}],"hidden":false},{"title":"RoboCup","slug":"/team/robocup","pages":[{"title":"RoboCup","slug":"/team/robocup","hidden":null},{"title":"Resources","slug":"/team/robocup/resources","hidden":null},{"title":"Debriefs","slug":"/team/robocup/debriefs","hidden":null}],"hidden":false}],"hidden":false},{"title":"System","slug":"/system/foundations/overview","chapters":[{"title":"Foundations","slug":"/system/foundations/overview","pages":[{"title":"Overview","slug":"/system/foundations/overview","hidden":null},{"title":"Build System","slug":"/system/foundations/build-system","hidden":null},{"title":"Continuous Integration","slug":"/system/foundations/ci-system","hidden":null},{"title":"NUClear","slug":"/system/foundations/nuclear","hidden":null},{"title":"Mathematics","slug":"/system/foundations/mathematics","hidden":null},{"title":"Configuration and Script System","slug":"/system/foundations/config-script","hidden":null},{"title":"Director","slug":"/system/foundations/director","hidden":null}],"hidden":false},{"title":"Subsystems","slug":"/system/subsystems/input","pages":[{"title":"Input","slug":"/system/subsystems/input","hidden":null},{"title":"Odometry","slug":"/system/subsystems/odometry","hidden":null},{"title":"Localisation","slug":"/system/subsystems/localisation","hidden":null},{"title":"Motion","slug":"/system/subsystems/motion","hidden":null},{"title":"Vision","slug":"/system/subsystems/vision","hidden":null},{"title":"Behaviour","slug":"/system/subsystems/behaviour","hidden":null},{"title":"Logging","slug":"/system/subsystems/logging","hidden":null}],"hidden":false},{"title":"Tools","slug":"/system/tools/nusight","pages":[{"title":"NUsight","slug":"/system/tools/nusight","hidden":null},{"title":"NUbook","slug":"/system/tools/nubook","hidden":null},{"title":"NUpbr","slug":"/system/tools/nupbr","hidden":null},{"title":"NUgan","slug":"/system/tools/nugan","hidden":null},{"title":"System Configuration","slug":"/system/tools/system_configuration","hidden":null},{"title":"NatNet SDK","slug":"/system/tools/natnet_sdk","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/system/hardware/overview","pages":[{"title":"Overview and Specifications","slug":"/system/hardware/overview","hidden":null}],"hidden":false},{"title":"Modules","slug":"/system/modules/actuation/","pages":[{"title":"Actuation","slug":"/system/modules/actuation/","hidden":null},{"title":"Extension","slug":"/system/modules/extension/","hidden":null},{"title":"Input","slug":"/system/modules/input/","hidden":null},{"title":"Localisation","slug":"/system/modules/localisation/","hidden":null},{"title":"Nbs","slug":"/system/modules/nbs/","hidden":null},{"title":"Network","slug":"/system/modules/network/","hidden":null},{"title":"Output","slug":"/system/modules/output/","hidden":null},{"title":"Planning","slug":"/system/modules/planning/","hidden":null},{"title":"Platform","slug":"/system/modules/platform/","hidden":null},{"title":"Purpose","slug":"/system/modules/purpose/","hidden":null},{"title":"Skill","slug":"/system/modules/skill/","hidden":null},{"title":"Strategy","slug":"/system/modules/strategy/","hidden":null},{"title":"Support","slug":"/system/modules/support/","hidden":null},{"title":"Tools","slug":"/system/modules/tools/","hidden":null},{"title":"Vision","slug":"/system/modules/vision/","hidden":null}],"hidden":false}],"hidden":false},{"title":"Guides","slug":"/guides/main/getting-started","chapters":[{"title":"Main Codebase","slug":"/guides/main/getting-started","pages":[{"title":"Getting Started","slug":"/guides/main/getting-started","hidden":null},{"title":"NUClear","slug":"/guides/main/nuclear-tutorial","hidden":null},{"title":"Running and Tuning Scripts","slug":"/guides/main/tuning-and-running-scripts","hidden":null},{"title":"Maintaining Subsystems","slug":"/guides/main/maintaining-subsystems","hidden":null},{"title":"Data Recording and Playback","slug":"/guides/main/data-recording-playback","hidden":null},{"title":"Camera Calibration","slug":"/guides/main/camera-calibration","hidden":null},{"title":"Onboarding Workshop","slug":"/guides/main/onboarding","hidden":null}],"hidden":false},{"title":"Tools","slug":"/guides/tools/nusight-contribution","pages":[{"title":"Contributing to NUsight","slug":"/guides/tools/nusight-contribution","hidden":null},{"title":"Setting Up Webots","slug":"/guides/tools/webots-setup","hidden":null},{"title":"Visual Mesh Getting Started","slug":"/guides/tools/visualmesh","hidden":null},{"title":"Using NUpbr","slug":"/guides/tools/nupbr-guide","hidden":null},{"title":"GameController Setup","slug":"/guides/tools/gamecontroller","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/guides/hardware/working-with-robots","pages":[{"title":"Working with Robots","slug":"/guides/hardware/working-with-robots","hidden":null},{"title":"Flashing a Robot","slug":"/guides/hardware/flashing","hidden":null},{"title":"Servo Setup and Calibration","slug":"/guides/hardware/servo-calibration","hidden":null},{"title":"Batteries","slug":"/guides/hardware/batteries","hidden":null},{"title":"DARwIn Op2 Robot Restoration and Calibration Guide","slug":"/guides/hardware/darwin-op2-guide","hidden":null}],"hidden":false},{"title":"General","slug":"/guides/general/learning-resources","pages":[{"title":"Learning Resources","slug":"/guides/general/learning-resources","hidden":null},{"title":"Contribution Workflow","slug":"/guides/general/contribute","hidden":null},{"title":"RoboCup Setup","slug":"/guides/general/robocup-setup","hidden":null},{"title":"Troubleshooting","slug":"/guides/general/troubleshooting","hidden":null},{"title":"Code Conventions","slug":"/guides/general/code-conventions","hidden":null},{"title":"Glossary","slug":"/guides/general/glossary","hidden":null}],"hidden":false}],"hidden":false},{"title":"Kitchen Sink","slug":"/kitchen-sink/headers","chapters":[{"title":"Markdown","slug":"/kitchen-sink/headers","pages":[{"title":"Headers","slug":"/kitchen-sink/headers","hidden":true},{"title":"Formatting and Paragraphs","slug":"/kitchen-sink/formatting-and-paragraphs","hidden":true},{"title":"Blockquotes","slug":"/kitchen-sink/blockquotes","hidden":true},{"title":"Alerts","slug":"/kitchen-sink/alerts","hidden":true},{"title":"Images","slug":"/kitchen-sink/images","hidden":true},{"title":"Lists","slug":"/kitchen-sink/lists","hidden":true},{"title":"Code","slug":"/kitchen-sink/code","hidden":true},{"title":"Math","slug":"/kitchen-sink/math","hidden":true},{"title":"Table of Contents","slug":"/kitchen-sink/table-of-contents","hidden":true},{"title":"Tables","slug":"/kitchen-sink/tables","hidden":true},{"title":"Collapsible Content","slug":"/kitchen-sink/collapsible","hidden":true},{"title":"GraphViz Diagrams","slug":"/kitchen-sink/graphviz-diagrams","hidden":true},{"title":"Referencing","slug":"/kitchen-sink/referencing","hidden":true}],"hidden":true}],"hidden":true}],"references":null,"hidden":null}},
    "staticQueryHashes": ["3715292327","445096115","466146812"]}