Skip to content

Camera Tick

Projects Involved: OBC

Concepts: Ticks

Abstract:

This task implements the camera tick in the OBC. This tick is the only tick that can fetch new images from the camera.

This tick will be called after either the switch or verify tick. It will load a new image from the camera and store it in mission state. After this, it will always transition to the CVLoiter tick.

All ticks inherit from the base Tick class (include/ticks/tick.hpp), which provides a common interface for all ticks.

Goals:

  • Learn about mission state manipulation
  • Tick structure and implementation

Files Involved:

OBC

Files to create and work on:

  • include/ticks/camera.hpp
  • src/ticks/camera.cpp

Base Steps:

1. Create the Header File

Reference any of the header files in include/ticks/ for the basic structure. There are a few functions that are required for every tick:

  • CameraTick(std::shared_ptr<MissionState> state);
  • void init() override;
  • Tick* tick() override;
  • std::chrono::milliseconds getWait() const override;

First, we will discuss what each of these functions do. The following is a boilerplate code for the source file (just to get you familiar with the syntax).

/**
 * This is the constructor for the tick. All it does is pass through the mission
 * state.
 *
 * The following syntax uses an initializer list to call the parent constructor.
 * If you are unfamiliar with this syntax, you can read more about it
 * here: https://www.cppreference.com/w/cpp/language/initializer_list.html
 */
CameraTick::CameraTick(std::shared_ptr<MissionState> state) : Tick(state, TickID::Camera);

/**
 * This is the initialization function for the tick. It is called once when the
 * tick is first started.
 */
void CameraTick::init();

/**
 * This is the main function for the tick. It is called periodically based on
 * how long getWait() returns (the quantization of tick time is dependent on the 
 * tick).
 *
 * At the end of the tick, return the next tick to transition to. If the tick
 * should stay the same, return nullptr
 */
Tick* CameraTick::tick();

/**
 * This function returns how long the tick should wait before calling tick() 
 * again.
 */
std::chrono::milliseconds CameraTick::getWait() const;

Additionally, you will need to have the camera instance variable in the class. This is the object that you will be interacting with to take pictures.

2. Create the Source File

3. Initialize the Camera in the constructor of the tick

4. In tick(), use the camera to take an image and store it in mission state

There already exists an instance variable in mission_state for the image.

// mission_state.hpp

/* 
* you can search up std::optional to learn about how it functions.
* for now, the relevant method is std::optional::has_value(), which returns
* true if the optional contains a value, and false otherwise.
*/
std::optional<ImageData> image;

5. Change the tick to the next tick (CVLoiter)

After this your tick diagram now looks like this:

              / ----> Verify  --> Done
             /          |
            /           v
prep --> switch ----> Camera 
                        |
                        v 

The code for the switch should be mostly implemeted already. Check out Switch and Verify so you can implement them. Since we haven't implemented CVLoiter yet, you can leave it nullptr or return an existing tick.

Tips:

Tip 1: Reference Code Look at other ticks for the format and boilerplate code.
Tip 2: STL Documentation Lookup `std::optional` and `std::shared_ptr` to understand how they work/use them.