Skip to content
README.md 4.91 KiB
Newer Older
Martin Marcinčák's avatar
Martin Marcinčák committed
# Newbie software task on the DRS unit.

This repository contains the framework for completing the newbie software task.
You have been given a board that controls anti-roll bar and some of the shutdown system.
Your task is to implement the functionality of [drag reduction system DRS](https://en.wikipedia.org/wiki/Drag_reduction_system) onto it.
You'll have to implement the missing pieces in `ARB/newbie_task.cpp`, `ARB/canmanager.cpp` and `ARB/main.cpp`.
The relevant parts are marked with the word `TASK:`, so you can use your IDE's search function to see what you're missing.

---
## The very first task
There are a few onboard LEDs, to start off, you could try blinking the leftmost one.
To toggle the LED, use the following function call:
```c++
bsp::gpio::led2.Toggle();
```
The recommended spot for the LED-blinking code is in the file `ARB/main.cpp`, in the function called `main()`. There's an if-statement, `if(sample_step)`, which is true every 500 us (frequency 2 kHz).

# Main task
From the software point of view, DRS is basically a servo that needs to be set to the right position. 
You are given a partial implementation of the software - we've implemented the [CAN bus](https://en.wikipedia.org/wiki/CAN_bus), timers, ADCs, MCU initialization, etc. for you.
You'll have to use the existing codebase and implement the logic to move the servo.

The DRS should respond to commands from CAN bus.
In `ARB/main.cpp`, you'll find a function called `DRSCommandCallback`, where you'll have to correctly call `DRS_Controller::set_state(State new_state)` function, to tell the DRS what to do (hint - the enum that's passed in is different from the enum class that DRS uses internally - you'll have).
Most of the control logic should happen in `DRS_Controller::update()`, which you'll need to call from the `main()` function in `ARB/main.cpp`.

Changing the servo position from one position to another instantly is difficult for the real car and causes several issues.
Try to find a way to slowly move it to the desired position at a slower speed.

## Controlling the servo
The position of the servo is set by sending repeated pulses of certain width. 
The pulse duration ranges from 1000 us to 2000 us. These pulses are generated by a hardware timer. 
The hardware timer is set up already, you'll only have to set the pulse width with
```c++
bsp::tim::servoPWM.SetDutyCycle(bsp::tim::TimChannel::CH2N, pulse_width / options::drs::period_us);
```

A [servo timing diagram from Wikipedia](https://en.wikipedia.org/wiki/Servo_control#/media/File:Servomotor_Timing_Diagram.svg) demonstrates the situation nicely, except **we don't use the 20 ms period**.

# Optional tasks
* There's a function in `DRS_Controller` called `setpoint_timed_out`.
  It is invoked if the CAN bus hasn't received a DRS command for too long.
  When it gets called, disable the DRS until a new command is received and update your status accordingly.
* Figure out how braking messages are processed and force DRS to close when braking.

---
# Toolchain installation
The latest toolchain can be downloaded from [the official ARM website](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads).
You'll also need to install [cmake](https://cmake.org/download/), [ninja](https://github.com/ninja-build/ninja/releases) and [git](https://git-scm.com/downloads).
The code is flashed via [openOCD](https://github.com/xpack-dev-tools/openocd-xpack/releases).
An alternative tool for flashing is [STM32CubeProgrammer](https://www.st.com/en/development-tools/stm32cubeprog.html).

Clone the repository with
```shell
git clone https://eforce1.feld.cvut.cz/gitlab/marcima8/newbie-sw-task-drs.git
cd newbie-sw-task-drs
git submodule update --init --recursive
```

Make sure you can compile the project as-is before you start making your own modifications.

Linux users will need to install `git`, `cmake`, `ninja` and `arm-none-eabi-g++` (and/or `arm-none-eabi-gcc`, that depends on your distro).
Also make sure your udev rules are fine, [this is what I use for the ST-Link.](https://gist.githubusercontent.com/daniel-p-carvalho/5b533d7e743081960637e73535f60e6d/raw/030d84602096e6b2f6f152b7a415b24d1d650a64/49-stlinkv2.rules)
For Ocarina V, use the following rule (change plugdev to dialout, if that's what you prefer):
```
SUBSYSTEM=="tty", ATTRS{idVendor}=="f055", ATTRS{idProduct}=="beef", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="block", ATTRS{idVendor}=="f055", ATTRS{idProduct}=="beef", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="scsi_generic", ATTRS{idVendor}=="f055", ATTRS{idProduct}=="beef", MODE="0660", GROUP="plugdev"
```

# Build and flash

On Windows, run these commands in Git Bash (installed together with git), not in CMD or PowerShell.

Build:
```shell
sh compile.sh
```
Flash:
```shell
sh flash.sh
```

## Interfacing with CAN bus
To test your DRS code, you'll need to give the boards some commands. This is done through our software called can-gui.
Ask someone at the electronics workshop for the details, they'll be happy to help. :)