diff --git a/src/content/docs/teleop/starter-project.md b/src/content/docs/teleop/starter-project.md index f5a99d6..af01f07 100644 --- a/src/content/docs/teleop/starter-project.md +++ b/src/content/docs/teleop/starter-project.md @@ -2,433 +2,509 @@ title: "Teleop Starter Project" --- -#**OUT OF DATE** +## Introduction -# Introduction +Here, you will complete a Vue component by: +* Creating page elements. +* Formatting page elements. +* Importing other components (```ArmControls``` and ```Rover3D```). +* Sending/receiving messages to/from the backend. -This project will involve building an ArmControls component on a testing view, connecting that to the backend, then using the simulator and the THREE.js component to verify the implementation. +The tasks you complete in this project will be similar to tasks that you see in the future. Don't be afraid to ask questions if you can't understand something, or are just curious. At a quick glance, the teleop system may seem simple, but there are a lot of moving parts. -Any spot marked with a ```TODO``` indicates that code should be added there. +--- + +## Getting Started + +### Opening the Code +First, go to [Teleop Quickstart](quickstart.md) and make sure your environment is set up. Critically, make sure you've run ```./build.sh``` and have all necessary dependencies. -Please make sure you understand what you are adding when you add it and ask questions as you go. This project is solely for your learning so take as much time as you need to understand what is actually happening as you go through it. +Open up a terminal, and type ```mrover```. Then: + +Checkout/go to the branch that has the starter project code: -# Getting Started -First, checkout the branch that has the starter project code: ```bash -git checkout teleop-starter-new +git checkout teleop-starter-2026 ``` -Then checkout a new branch to work on: + +Copy it into a new branch: + ```bash -git checkout -b /starter-project -example: git checkout -b tjn/starter-project +git checkout -b /starter-project-2026 +example: git checkout -b km/starter-project-2026 ``` +:::note +Whenever you create a new feature, you should make a new branch and follow the naming convention of ```/```. You'll often checkout from main, but not always. +::: -Make sure that you have gone through the process detailed in [Teleop Quickstart](/teleop/quickstart) so that all dependencies are installed correctly -Since this starter project is just another blank page added to the codebase, you would launch the backend just like you normally would, with: +Now you (hopefully) have the starter code ready to be worked on. But how do you run and debug it? +### Running the Code + +Go to the url ```http://localhost:8080/starter``` in your browser. You should see an error page. This is because it is trying to access a server on and IP address that doesn't have any - ```localhost``` a.k.a. ```127.0.0.1``` a.k.a. **your** computer. To create the server it needs, go to your terminal, and run ```bash -ros2 launch mrover basestation.launch.py +ros2 launch mrover basestation.launch.py mode:=dev ``` +:::note +```mode:=dev``` launches in development mode. Without it, the basestation will launch in production mode and in a new window. +::: -Then, open your browser, and go to ```http://localhost:8080/starter``` to verify that it has launched correctly. You should see the header, and the text "body" below. +This launches both the frontend and the backend. Now once you go back to your browser, you should see a webpage with a header and some text with "Hello World!" in it after reloading. If not, make sure you did everything in [Teleop Quickstart](quickstart.md), or ask for help. + +:::note +* The ```/starter``` part of the url specifies that you are on the "Starter" page of the basestation. You can remove it to see the main page. +* The ```:8080``` part of the url is the port number. It functions as a sort of "id" for the server on the particular computer. +::: --- -# Understanding Websockets +## Vue Files and Editing -Websockets provide a persistent, two-way communication channel between the frontend and backend, Once the connection is established, messages are sent instantly with very low latency, which makes it suitable for live data applications like our frontend. +Now, open up ```StarterProject.vue``` in a code editor. It's easiest to just run this in a new terminal: +```bash +mrover +code . +``` +Then press **ctrl-p** and type the file's name to search for it. It should look something like this: ---- +```html + -# WebsocketStatus component + -``` +:::note +A *flexbox* is a container that holds elements in a single row or column. It can shrink or grow elements as needed to fit inside of its empty space. + +*Grid* is also a common choice for holding multiple elements. It displays them in... well... a grid. Prefer to use it over *flexbox* when a layout starts to get cluttered, as *grid* is more predictable. + +See more info at [this Geeks for Geeks article](https://www.geeksforgeeks.org/css/comparison-between-css-grid-css-flexbox/) (albeit, for base CSS). +::: -Check your browser window to see how it looks. Pretty neat, isnt it? +:::caution +The basestation is designed to display best on a **1080p** screen - the one used at competition. You might have to adjust your settings or fullscreen the page to match it. +::: --- -# Developing ```ArmControls``` +## ```Arm Controls``` and ```Rover3D``` -Now open up ```ArmControls.vue``` in your preferred text editor, located at ```/teleoperation/basestation_gui/frontend/src/components/ArmControls.vue```. The core functionality in this component has already been implemented. +### Overview -## Mode Selector +```Rover3D``` is a display of the rover in its current state. It also displays a *costmap*, a grid of how "expensive" it would be for the rover to navigate a certain section of terrain. -First, lets make a button group to modify the **mode** variable. Add a div with the bootstrap group ```btn-group``` below the ```
``` containing the ```

``` +```Arm Controls``` allows the operator to move the robot arm with a controller, and displays the controller's state. Here, however, the code has been modified so that keyboard input also moves the arm. -```html -
+Here is part of the code for keyboard input (not all of it): -
+```typescript +interval = window.setInterval(() => { + const axes: number[] = [0, 0, 0, 0] + const buttons: boolean[] = [] + axes[0] = (keysPressed.d ? 1 : 0) - (keysPressed.a ? 1 : 0) + axes[1] = (keysPressed.s ? 1 : 0) - (keysPressed.w ? 1 : 0) + + sendMessage('arm', { + type: 'ra_controller', + axes: axes, + buttons: buttons + }) +}, 1000 / UPDATE_HZ) +``` + +It takes the keyboard input and "translates" it into a controller input. +Here is part of the code for direct controller input: + +```typescript +const { connected, axes, buttons, vibrationActuator } = useGamepadPolling({ + controllerIdFilter: 'Microsoft', + topic: 'arm', + messageType: 'ra_controller', +}) ``` -Inside this div, place two buttons, one selecting ```disabled```, and one for ```throttle```, the simplest controller mode that maps each joint of the arm to an axis: +However, pressing anything won't move the arm currently. This is for two reasons: +* The arm mode has to be set. +* The backend needs a rover with an arm to move. + +### Setting up ```Arm Controls``` + +Head inside ```ArmControls.vue```. In VSCode, you can control click its name from its html tag or import statement. Then, go to this div: + +```html +
+ +``` + +And add these buttons where the ```TODO``` is: ```html ``` -As you can now see from your browser, the ```btn-group``` creates a joined effect on the buttons, the ```@click``` modifies the ```mode``` variable when selected, and the ```:class``` styling makes the button fill solid when selected. +Click throttle. The hard part is now done. Next, we need to get the rover, or at least a virtual one. +--- -## Send Controls +## Simulator -The original code requires a **controller** to be connected in order to send controls. Here, we have modified the code using the **WASD** keys to mimic the left joystick of the controller, like so +Open a new terminal, but keep the old one running the basestation. Run and then run these commands. If you get stuck in the simulator, press **esc**: -```js -axes[0] = (this.keysPressed.d ? 1 : 0) - (this.keysPressed.a ? 1 : 0) -axes[1] = (this.keysPressed.s ? 1 : 0) - (this.keysPressed.w ? 1 : 0) +```bash +mrover +ros2 launch mrover simulator.launch.py ``` -**axes** and **buttons** are used to simulate an xbox controller. We will now send both the mode and the controls to the ```arm``` consumer. +The simulator and RViz will open in new windows. *RViz* is a useful tool that allows you to see what the rover sees, and what topics are being broadcast. The simulator provides a digital version of the rover that communicates with the basestation in a similar way to if it was real. -There is already an interval set up in ```created()```, which repeats 30 times a second. As mentioned earlier, to access and use websockets, we will use ```this.$store.dispatch()```: +### Navigating the Simulator -```js -this.$store.dispatch('websocket/sendMessage', { - id: 'arm', - message: { - type: 'ra_controller', - axes: axes, - buttons: buttons, - }, -}) -this.$store.dispatch('websocket/sendMessage', { - id: 'arm', - message: { - type: 'ra_mode', - mode: this.mode, - }, -}) -``` +The simulator is the one with the MRover logo as its symbol. You can move the camera with **WASD**, **space**, **ctrl**, and the mouse. **Esc** toggles the mouse from being locked to unlocked and back again. + +### Controlling the Rover + +Everything is currently frozen. Press **p** to enable physics, and uncheck **publish ik**. You can move the rover with **i**, **j**, **l**, and "**,**" while the mouse is locked. Go back to the Starter view in your browser. Make sure throttle mode is selected, and use **WASD** to control the arm. It will move in both the browser and the simulator. --- -## Verify commands +## ROS Topics -Open another terminal window, enter ```mrover```, then enter +One last thing - Open up yet another terminal, but leave the other two running. Run these commands: -``` +```bash +mrover ros2 topic list ``` -This should list all the topics which are live, which includes ```/arm_throttle_cmd``` which we are publishing to +It will display every topic that currently exists. Let's try to see how our arm controls are being sent. Because we're using throttle mode, they will be sent through ```/arm_thr_cmd```. Echo that topic. -Now, enter ```ros2 topic echo /arm_throttle_cmd```. Place the window along side your browser window, focus on the browser, select ```throttle```, and press the WASD keys. You should see the published values react to your keystrokes. +```bash +ros2 topic echo /arm_thr_cmd +``` -This is the method used to debug ROS topic. +Whenever you move the arm, a new message will appear. Press **ctrl-c** to stop the echoing. --- -## Completed ```ArmControls.vue``` +## Git Commits -Now, your ```