{
    "componentChunkName": "component---src-components-page-template-jsx",
    "path": "/system/foundations/config-script",
    "result": {"data":{"mdx":{"id":"1698f09b-6c6c-5f14-9073-14e206966f7e","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\": \"System\",\n  \"chapter\": \"Foundations\",\n  \"title\": \"Configuration and Script System\",\n  \"description\": \"The configuration and script system\",\n  \"slug\": \"/system/foundations/config-script\",\n  \"authors\": [\"Alex Biddulph (@bidski)\", \"Ysobel Sims (@ysims)\"]\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(\"h2\", {\n    \"id\": \"the-configuration-system\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#the-configuration-system\",\n    \"aria-label\": \"the configuration system 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  }))), \"The Configuration System\"), mdx(\"p\", null, \"The NUbots configuration system is based on a hierarchical \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://yaml.org/\"\n  }, \"YAML\"), \" file system.\"), mdx(\"p\", null, \"The hierarchical structure is as follows\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"config/\\n\\u251C\\u2500\\u2500 nugus1/\\n\\u2502\\xA0\\xA0 \\u2514\\u2500\\u2500 ExampleModule.yaml\\n\\u251C\\u2500\\u2500 nugus2/\\n\\u2502\\xA0\\xA0 \\u2514\\u2500\\u2500 ExampleModule.yaml\\n|   webots/\\n\\u2502\\xA0\\xA0 \\u2514\\u2500\\u2500 ExampleModule.yaml\\n\\u251C\\u2500\\u2500 robocup/\\n\\u2502\\xA0\\xA0 \\u2514\\u2500\\u2500 ExampleModule.yaml\\n\\u2514\\u2500\\u2500 ExampleModule.yaml\\n\")), mdx(\"p\", null, \"The file \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"config/ExampleModule.yaml\"), \" must exist for every module that uses configuration. This file defines all of the configuration for the module.\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"config/webots/ExampleModule.yaml\"), \" is an optional file and allows you to provide platform-specific overrides for specific configuration values, in this case it would provide overrides for any webots robots. This is useful when webots and the real nugus robot use different configurations values.\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"config/nugus1/ExampleModule.yaml\"), \" is an optional file and allows you to provide robot-specific overrides for specific configuration values, in this case it would provide overrides for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nugus1\"), \" robot. It overrides the default and platform-specific configuration files.\\nSimilarly, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"config/robocup/ExampleModule.yaml\"), \" allows for the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"robocup\"), \" role to further override configuration values. It overrides the default, platform-specific and robot-specific configuration files.\"), mdx(\"p\", null, \"It is intended that all configuration values exist in the default configuration file and that only a subset of configuration values appear in the platform-specific, robot-specific and role-specific override files.\"), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"There are exceptions to this, the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Camera\"), \" module being the best example.\"), mdx(\"p\", null, \"The \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Camera\"), \" module introduces the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"serial_number\"), \" field in the robot-specific\\noverride files as every robot will have different cameras installed in it.\\nHowever, it makes no sense for the default configuration file to contain the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"serial_number\"), \" field as there is no viable default value for this field.\")), mdx(\"p\", null, \"The platform-specific override is intended to allow for different configuration values between real robots and webots. For instance, the real NUgus robot uses a different Visual Mesh network compared to the robots run in the Webots simulator.\"), mdx(\"p\", null, \"The robot-specific override is intended to allow configuration values to be tweaked to account a slight variation in the robots hardware. For instance, the cameras on each robot have different serial numbers.\"), mdx(\"p\", null, \"The role-specific override is intended to change a modules behaviour based on which role is running. For instance, disabling the transmission of certain NUsight2 traffic while playing a competition game.\"), mdx(\"p\", null, \"To reiterate how the configuration system loads and merges configuration files\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"The default configuration file \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/ModuleName.yaml\"), \" is loaded. This forms the base configuration for the module\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A check is made to see if \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/PlatformName/ModuleName.yaml\"), \" exists. If it does, it is loaded and all values found therein override the equivalent values in the base configuration\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A check is made to see if \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/RobotName/ModuleName.yaml\"), \" exists. If it does, it is loaded and all values found therein override the equivalent values in the base configuration\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A check is made to see if \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/RoleName/ModuleName.yaml\"), \" exists. If it does, it is loaded and all values found therein override the equivalent values in the base configuration\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"If any of these 3 configuration files are modified then steps 1-4 are run again\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"It it also supported for a module to have multiple configuration files\\narranged into a folder hierarchy. In this case the configuration system is\\ndirected to monitor for any changes in an entire folder. Once again, the\\n\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Camera\"), \" module provides a good example of this. The same rules still apply,\\nhowever, rather than the \\\"default file\\\" needing to exist, the \\\"default folder\\\"\\nmust exist. The merging rules will apply on a per-file basis whenever a change\\nto a file is detected in the folder that is being monitored.\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"A module can create multiple \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Configuration\"), \" reactions, each one monitoring a different file or folder. The above detailed rules apply to each reaction individually.\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"Robot platform is derivated from the hostname/robot name. The hostname of binaries run in Docker is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"docker\"), \", unless the binary being run contains the word \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"webots\"), \". In this case, the hostname will be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"webots\"), \".\")), mdx(\"h2\", {\n    \"id\": \"the-script-system\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#the-script-system\",\n    \"aria-label\": \"the script system 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  }))), \"The Script System\"), mdx(\"p\", null, \"The script system works very much like the configuration system described above. However, default scripts are moved to a platform type folder and the merging of values is skipped as it doesn't make sense to try and merge two scripts.\"), mdx(\"p\", null, \"In the script system, we first check for a robot-specific script. If a robot-specific script does not exist, then we check for a platform-specific script.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-text\"\n  }, \"scripts/\\n\\u251C\\u2500\\u2500 nugus/\\n\\u2502\\xA0\\xA0 \\u2514\\u2500\\u2500 Stand.yaml\\n\\u2514\\u2500\\u2500 nugus2/\\n \\xA0\\xA0 \\u2514\\u2500\\u2500 Stand.yaml\\n\")), mdx(\"p\", null, \"To reiterate how the script system loads script files\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A check is made to see if \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/RobotName/Script.yaml\"), \" exists. If it does, it is loaded.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"If it doesn't exist, a check is made to see if \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"config/PlatformName/Script.yaml\"), \" exists. If it does, it is loaded.\")), mdx(Alert, {\n    type: \"info\",\n    mdxType: \"Alert\"\n  }, mdx(\"p\", null, \"Robot platform is derivated from the hostname/robot name. The hostname of binaries run in Docker is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"docker\"), \", unless the binary being run contains the word \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"webots\"), \". In this case, the hostname will be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"webots\"), \".\")));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#the-configuration-system","title":"The Configuration System"},{"url":"#the-script-system","title":"The Script System"}]},"frontmatter":{"section":"System","chapter":"Foundations","title":"Configuration and Script System","description":"The configuration and script system","keywords":null,"slug":"/system/foundations/config-script","hidden":null},"childNUbookContributions":{"authors":[{"name":"Alex Biddulph","username":"bidski"},{"name":"Ysobel Sims","username":"ysims"}],"lastCommit":{"date":"2022-06-10T17:32:01.000Z","hash":"b7d36b9a8d3c15ad6f141111515263999314e641"}}}},"pageContext":{"mdxPath":"src/book/02-system/01-foundations/06-config-script.mdx","id":"1698f09b-6c6c-5f14-9073-14e206966f7e","next":{"chapter":"Foundations","title":"Director","description":"Introduction to the Director and how to use it to build behaviours.","slug":"/system/foundations/director","hidden":null},"previous":{"chapter":"Foundations","title":"Mathematics","description":"Detailed explanation of how mathematics is written in the NUbots codebase.","slug":"/system/foundations/mathematics","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"]}