第15回 解答例

マイコン向け設計をまとめる

演習の解答例。まず自分で書いてから読むこと。

ファイル構成

include/
├── Sensor.hpp          抽象クラス(約束ごと)
├── IMU.hpp             Sensorを継承
├── LED.hpp
├── Motor.hpp
└── FlightMode.hpp      enum class

src/
├── IMU.cpp
├── LED.cpp
├── Motor.cpp
└── main.cpp

Sensor / FlightMode

include/Sensor.hpp
#pragma once

class Sensor {
public:
    virtual ~Sensor() = default;

    virtual void update() = 0;
};
include/FlightMode.hpp
#pragma once

enum class FlightMode {
    MANUAL,
    AUTO,
    LANDING
};

IMU

include/IMU.hpp
#pragma once

#include "Sensor.hpp"

class IMU : public Sensor {
public:
    IMU();

    void update() override;

    float getRoll() const;
    float getPitch() const;
    float getYaw() const;

private:
    float roll;
    float pitch;
    float yaw;
};
src/IMU.cpp
#include "IMU.hpp"

IMU::IMU()
    : roll(0.0f), pitch(0.0f), yaw(0.0f) {
}

void IMU::update() {
    // 実機では姿勢センサから読み取る
}

float IMU::getRoll() const {
    return roll;
}

float IMU::getPitch() const {
    return pitch;
}

float IMU::getYaw() const {
    return yaw;
}

main.cpp

src/main.cpp
#include <Arduino.h>

#include "FlightMode.hpp"
#include "IMU.hpp"
#include "LED.hpp"
#include "Motor.hpp"
#include "Sensor.hpp"

LED led(LED_BUILTIN);
Motor motor(24);
IMU imu;

Sensor* sensors[] = {&imu};
const int SENSOR_COUNT = sizeof(sensors) / sizeof(sensors[0]);

FlightMode mode = FlightMode::MANUAL;

void setup() {
    Serial.begin(115200);

    led.begin();
    motor.begin();
}

void loop() {
    for (int i = 0; i < SENSOR_COUNT; i++) {
        sensors[i]->update();
    }

    switch (mode) {
    case FlightMode::MANUAL:
        led.off();
        break;

    case FlightMode::AUTO:
        led.on();
        motor.setSpeed(50);
        break;

    case FlightMode::LANDING:
        led.toggle();
        motor.stop();
        break;
    }

    delay(50);
}

main.cppが長くなってきたら

上のmain.cppには、まだ「モードごとの制御判断」が残っている。これをControllerクラスに移し、さらに全体をRobotがまとめると、main.cppは次の形まで短くなる。

#include "Robot.hpp"

Robot robot;

void setup() {
    robot.initialize();
}

void loop() {
    robot.update();
}

これが最終課題で目指す形である。

使った機能の確認

要素使っている機能学んだ回
LED / Motorクラス・カプセル化・.hpp / .cpp分割第6〜8回
Sensor抽象クラス・純粋仮想関数第12回
IMU継承・override第10〜11回
sensors[]ポリモーフィズム第13回
FlightModeenum classによる状態管理第9回
全体の構成1クラス1責務第14回

ここまで書けていれば、到達度チェックの「設計」の項目はほぼ埋まるはずである。

→ 第15回の本文に戻る