初心者エンジニアがRSP-01ソフト開発に参戦した結果: 学びと所感

# はじめに

趣味で宇宙開発を行う団体「[リーマンサット・プロジェクト](https://www.rymansat.com)」がお送りする[新春アドベントカレンダー](https://qiita.com/rsp-dgkz/items/497225739b88c817a90c)です。

リーマンサット・プロジェクトは「普通の人が集まって宇宙開発しよう」を合言葉に活動をしている民間団体です。
他では経験できない「宇宙開発プロジェクト」に誰もが携わることができます。
興味を持たれた方は [https://www.rymansat.com/join](https://www.rymansat.com/join) からお気軽にどうぞ。

@hokke_mirin さんによる[LTのススメ](https://qiita.com/hokke_mirin/items/d6020e10078e3640c95d)に引き続き投稿です。

# この文書は何？

本記事では、ハード開発未経験の大学生 --- 後のサラリーマン --- がRSP-01プロジェクトの組み込みソフト担当の一人として参加してから2年弱が経過した今、開発を通じて学んだこと、参加してよかったことにつらつらと触れていきます。

技術系メンバーの一例として何らかの参考になれば幸いです。


# 私は何者？

- メーカー勤務の技術職（新卒2年目）
- 最近は組み込みソフト開発が主業務
- 大学時代の専門は物理（研究ではFortranごりごり書いていました）
- RSP-01では主に以下を行っています:
    - 衛星搭載ファームウェアの開発
    - 電気系統の結合テスト
- RSP-01参加前のスキル:
    - C: 授業でやった
    - 組み込み機器: Arduinoをちょっと触ったことあるくらい

# 学びたち: 初心者による初心者のためTIPS

ぶっつけ本番で開発を行った結果~~味わったハマり~~得た学びの例を、組み込み開発新入りの目線で紹介します。

## 問題の探索範囲が広い

開発開始してからはじめに面食らったのがこれ。

組み込み開発ではチップや基板などの物も扱うため、何かうまく行かないことがある場合はソフトとハードの両方を調べる必要があります。
例えば下図のように、マイコンとRaspberry Pi (RasPi)をUART等で通信させることを考えると、通信がうまく行かないときの原因として

- 配線ミス、断線、接触不良
- マイコンのファームウェアもしくはRasPiのソフトのバグ
- マイコン、RasPi、レベルシフタ（マイコン側とRasPi側の入出力電圧を調整するもの）の故障

などがまず思いつきます。

<img height="200" alt="Screen Shot 2020-01-05 at 19.54.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270862/1176b6a0-c042-89ff-38f6-03d4af58f99d.png">

このように、問題の探索範囲はソフト単体の場合に比べて非常に広大になります。
そしてその複雑さのため、何もしていないのに壊れることがあります。
...そんなことはほぼなく、ぱっと見では原因がわからないだけで、大体はどこかに原因があるのです（泣）。

### 基本的な対策

探索範囲が広いと言っても、基本的に

- テスターで導通確認
- オシロスコープで波形確認
- テスト用プログラムで動作テスト

などによって構成要素を1個ずつ調査し、探索範囲を徐々に絞っていき、原因を特定するだけです。
最初はこの探索範囲の絞りがうまくなく、余計に時間がかかっていました。特に初めはソフトとハードどちら起因かを見極めがたく、手をこまねいて時間を浪費することしばしば...
以下はその中で得た知見です。[^malfunctions]

- 信号や電源が不安定ぽかったら、とっととロジックアナライザかオシロスコープで波形を見る
    - 変更していないはずのプログラムを延々と眺めても解決はしないのです（自戒）。
    - オシロスコープ本当に便利。
- 配線の接続はジャンプワイヤを使うよりもなるべくはんだ付けする
    - はんだ付けは面倒かもしれませんが、接触ミスによる不具合はこれによって減らせます。
    - ジャンプワイヤなら取り外し可能なので便利&楽と思うかもしれまんが、けっこう接触不安定です。
    - 基本休日しか活動できない我々にとって時間は貴重（なのだがなぜか目先を楽にしてしまい同じ失敗を繰り返すのである（自分のこと）...）
- か く に ん す る
    - 人は単純ミスをするようにできていて、自分も以下のようなやらかしを重ねてきました。
        - 古い版のファームウェアを焼き込んで動作確認しようとする（ので当然思い通りに動かない）
        - GNDと電源を逆刺し（これはICを破壊するための最も簡単な方法です）
    - こういうのはステップごとに逐次確認する癖をつけることでやっと消えるのかなと...

[^malfunctions]: 開発やテストで不具合が出るのは当然と思いますが、こういうのを目の当たりにしていると、「（自分が今使っているスマートフォンやPC含め）世の中の電子機器はよく元気に動いているなあ...どれだけ膨大な修正やテストを乗り切って来たのだろうか」と感嘆します。

## マイコンの記憶容量の壁: Arduinoの場合の対策

マイコンは当然普通のPCに比べて圧倒的に記憶容量が小さく、例えばArduino搭載の[ATMega328P](https://avr.jp/user/DS/PDF/mega328P.pdf)の場合

- ROM (Flash): 32 KB
- RAM (SRAM): 2 KB

だったりして、コマンド等機能を追加していくと簡単に上限到達します。

### RAM

RAMに関して、割を食ったものの一つがログ出力。
デバッグを行うために、UART経由で文字列を出力する`Serial.println()`を使って

```cpp
Serial.println("logging message");
```

を多用していったところ、Arduino IDEでのコンパイル時にメモリ(SRAM)不足の警告を受けました。

上記のように書くと、プログラム起動時に`()`内の文字列がSRAMに読み込まれてそのまま残り続るため、利用可能なSRAMの容量が約文字数分だけ[^logger]消費されます。

[^logger]: （「約」と書いたのは、`println("string1); ...; println("string2);`などのように複数の`println()`で文字列が部分一致していると、その共通部分が再利用されるから）。

これは実は`F()`マクロを使って回避する事ができます。文字列を`F()`で囲むと、SRAMへの文字列読み込みは起動時には実行されず、`println()`呼び出し時にFlashから読み込まれるようになります。そのためSRAMの容量の固定消費はなくなります。

```cpp
Serial.println("F(logging message)");
```

### Flash
コードの行数を増やせばその分プログラムも増大します。これを抑えるには

- 同じような動作をする部分は関数化して再利用する
- プログラムのサイズを小さくする`-Os`オプションを使ってコンパイルする（※[Arduino IDEではすでにこれがデフォルト](https://www.instructables.com/id/Arduino-IDE-16x-compiler-optimisations-faster-code/)）。`-Ox (x = 0, ..., 3)`に変更するとFlash使用量が激増します）
- デバッグ分の文字数を減らす

などによって頑張って削減する必要があります。


# RSP-01に参加してよかったこと

上記ではつらみを少し匂わせてしまいましたが、以下のような喜びがありました。

## 技術的スキルが向上した

組み込み未経験でプロジェクトに突入した結果以下のようになりました。

| スキル | BEFORE | AFTER |
|------|------|------|
| C/C++ | ポインタよくわからない... | ファームウェア書ける! |
| 回路: 設計 | コンデンサの原理とかなら... | ロジック部なら大体わかる気がする |
| 回路: テスト | やったことなし | 簡単なデバッグ・修理ならできるように |

- 自分で勉強したというよりは、まず作業場所に行って手を動かして、わからないところは経験者のメンバーから教えを乞うOJTスタイルで身につけていきました。みんな優しくて本当にありがたかった... [^helped]
- 回路は今回全く設計しませんでしたが、今度自分でもやってみようかと。衛星システムまるごと設計できるようになりたい。

[^helped]: 助け合いの精神が浸透していて、困ったら誰かに相談しやすい環境なのです。こういう環境づくりできる人になりたい

## 仕事との相乗効果

RSP-01に加えて、仕事の方でも組み込みソフトの開発を行うようになったため、片方で学んだことがもう片方にも活用されるという状態が生まれました。
プログラミングのスキルもそうですが、データシートを読み込むことに対する抵抗が無くなったのは特に良かった気がしています。（はじめは、データシートが数字や用語の謎羅列にしか見えていなかったので...）

平日と休日どちらも開発が主業務ですが、意外とモチベーションは下がりませんでした。おそらく

- 開発物や業界が異なっており、プログラミングという行為以外はあまりかぶらない
- 平日と休日ではコミュニティがほぼ完全に分かれていて、それぞれ全く異なる人々と接している。それによって平日と休日が切り分けられている
- 仕事が激務ではない（残業はある程度あるものの、休日出勤は基本なし）

といったことが理由かなと思います。

## 仲間が増えた
- メンバー同士で旅行をやる程いつの間にか交流が深まっていました:

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%83%AA%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B5%E3%83%83%E3%83%88?src=hash&amp;ref_src=twsrc%5Etfw">#リーマンサット</a>、社員旅行に来ています（会社じゃない）👨‍💼👩‍💼 <a href="https://t.co/i3NKVycgs4">pic.twitter.com/i3NKVycgs4</a></p>&mdash; リーマンサット・プロジェクト (@RymanSat) <a href="https://twitter.com/RymanSat/status/1208335608281587712?ref_src=twsrc%5Etfw">December 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

（↑ただの年末打ち上げだが見た目が社員旅行になってしまったの図。※任意参加）

良きリーダー・メンバー・組織に巡り会えたということなのだと思います。

- 宇宙関係の話ができる相手が増えたのは地味に嬉しかった。

## 宇宙開発できた！

自分がリーマンサットに参加したのはこれのためです。衛星打ち上げと運用はこれからですが、宇宙空間で動く装置を作るという目標は無事達成。

ちょっと疲れたときには、地上400kmの低軌道上に燦然と輝く01衛星が画像をダウンリンクする光景を心に思い浮かべることで気持ちを盛り上げてきました。これは宇宙開発ならではのモチベーションアップ法（？）。

![sat.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270862/64b8d34e-3dd4-0d7f-42d4-803d3e1c2b0a.jpeg)


# 参考リンク

- [宇宙開発が趣味？ - リーマン達が作る衛星の初号機がもうすぐ宇宙へ！ | マイナビニュース](https://news.mynavi.jp/article/20191106-919869/)
    - RSP-01の活動拠点を取材いただきました
- [【電子書籍版】RSP-00「激レア」開発記](https://booth.pm/ja/items/1576318)
    - RSP-01の先代であるRSP-00の開発記です。開発の経緯や衛星のシステム構成にも触れているので興味のある方はぜひ。

# 次回は...

@Gan0803 さんによる「第一回RSP杯チキンレース　参戦レポート」です！