キノコの自省録

日々適当クリエイト

プロダクト設計にはDtoDの当てはまりが良さそう……な気がする

タイトル通り、かなりフワっとしているお話になります。

上流設計、特にどういう製品を作っていこうか、というプロダクト設計には、DtoD(Discover to Deliver)というフレームワークの当てはまりが良さそうだなあと思ったお話です。

私自身、DtoDについて詳しく調べたり本を読んだりしているわけではありませんので、こんなものがあるんだ、という参考程度に。

Discover to Deliverとは

米国EBG Consulting社のエレン・ゴッテスディーナーさんとメアリー・ゴーマンさんが、2015年に考案したフレームワークです。割と最近ですね。本家はこちらです。

Discover To Deliver

日本では、オージス総研がまとめています。

DtoD手法に基づくアジャイル要求 | 株式会社オージス総研

こちらのページでは、こんな風に紹介されています。

  1. ワークショップの活用 専門家単独で行うのではなく、顧客、業務、技術という異なる視点の人々が参加するワークショップを開催して、迅速にニーズをより多面的に理解し、表現し、開発内容を検討し、合意を形成する。

  2. 多様なモデルの活用 ワークショップで、ニーズや開発内容を軽量でとっつきやすい様々なモデル(短文記述を含む)により多面的に表現し、理解する。これらは、「プロダクトの7側面」という形でまとめられる。

  3. 分析者の役割の変更 分析者がワークショップのファシリテーターモデラーの役割を担うことで、プロダクトオーナーの役割を分担する。

個人的には、「プロダクトの7側面」がとても当てはまりの良いモデルだと感じました。

プロダクトの7側面

オージス総研のページにも少し紹介がありますが、ソフトウェア開発にはユーザストーリーマッピングスクラムといった開発フレームワークがあります。これらのフレームワークはかなり浸透してきてはいますが、如何せんソフトウェア開発に直結していることもあって、少し技術者寄りな側面が否めない部分があります。特にスクラムはそうですね、。そして、ユーザーストーリーマッピングも、それだけではプロダクト設計を考える上では、不十分です。開発すべき部分ではない部分、例えばクレーム対応や在庫管理といった点は、ユーザーストーリーマッピングにはなかなか登場しないと思います。

少し話が脇道にそれますが、私の関わっているプロダクトオーナーは非技術者が多いせいなのか、プロダクトの方針について全く整理されていない状態で、新規プロダクトの話を持ち掛けられることが多いです。はっきり言ってしまうと、顧客要望をそのまま伝達しているようにしか見えません。せめて、プロダクトの指針くらいは決めて欲しいのですが、ある部分について顧客要望がない場合「何も言ってこないんですよ」と言ってくることがあります。ないならないでプランを立てるのがプロダクトオーナーの役割だと思うので、それを技術者に言うのはどうかと思います。

じゃあ、プロダクトオーナーに対して、「せめてこのくらいは考えたり、顧客からヒアリングしてほしい」というのは何ですか、と聞かれると、なかなかうまく整理して話せなかったりします。そこで、このプロダクトの7側面です。よくまとまってるなあと感じました(もしかしたら曲解しているかもしれませんが)。

プロダクトの7側面は、以下の通りです。

ユーザ

プロダクトの使用者です。どういう使用者を想定しているのか、という部分を考えましょう、ということです。ユーザストーリーマッピングも、ここにある程度含まれます。使用者を主眼に置いた分析といえば、ペルソナが有名ですね。

稀に、プロダクトの納入先(要するに顧客)が使用者のスコープを想定していない場合がありますが、だからといってユーザ分析をしなくていいわけではないと思います。ちょっと考えただけでも、万人向けなのか、弱い部分をターゲットにするのか、強い部分をさらに伸ばすのかのプランがあり、それによってプロダクトの方針が変わります。顧客が外部企業の場合、それらのプランを提示するのもプロダクトオーナーの役目だと思います。

インターフェイス

APIというより、どれくらいの企業や人が関わり合いを持つか、という部分です。顧客企業と自社、ユーザのみの関係で完結することは稀でしょう。例えば、プロダクトがハードウェアを含む場合、絶対に物流や倉庫が登場します。故障対応はどうするのか、ハードウェアが自社開発ではない場合、カスタマイズはどうするのか、在庫管理は顧客企業がやるのか、自社がやるのか、いろいろ考えることがあるはずです。これを考えないで技術屋に投げると100%怒られます。

アクション

トリガーです。これはユーザストーリーマッピングユースケースで考えることになると思います。

データ、制御

DtoDの資料をさらっと読む限り、業務フローや法務規制を検討するようです。技術寄り、例えばRDBのデータ構造をどうするかといった系統のものではないと思います。業務フローというのであれば、これは本当に大事で、作ったシステムが客先にマッチしない場合、受け入れを拒否されることすらあると思います。データは、顧客マスタや発注伝票なども含むかもしれません。そういう意味では、確かにプロダクト設計の段階で、絶対に把握しておく必要があります。

環境

どういう場面やシチュエーションで使用されるか、ということだと思っています。業務フローのように「流れ」を伴うものではなく、もう少し定性的なものでしょう。プロダクトの使用環境が、静かで薄暗い環境だと思っていたのに、屋外+凄いノイズ環境下でした、となった場合、プロダクトがそもそも使用できないということも考えられます。

品質特性

ソフト屋(特にサーバ屋)の場合、想定ユーザ数とアクセス頻度は絶対気にしますし、ハードウェアの場合は耐性試験などの指針にもなるので、技術者からプロダクトオーナーに、どうなってんの?と聞くことも多いと思います。非技術者にとっては何をどう気にすべきなのかわからないので、ある程度、技術屋からインプットする必要があると思います。

メモリやストレージ、CPUはどのくらいのスペックを用意すればよいのかなどは、顧客要望、およびコストと絡む場合が多いため、技術者とプロダクトオーナー間で調整が必要になるでしょう。

まとめ

正直DtoDについてそこまで調べてないのにエントリを書くのもどうかとためらったのですが、紹介してみました。というのも、プロダクトの7側面は、プロダクトオーナー自身も気にかけていて欲しいし、技術者側も、これが足りないよ、とプロダクトオーナーにつっつくべき項目として、割と当てはまりが良いと思ったためです。

PSGで風色メロディ

YMZ294のみ使用して、風色メロディを鳴らしてみました。PSG3音を使用しています。ノイズサウンドはなし。

今回はRaspberry Piを使用したのですが、めちゃくちゃ環境ノイズが乗ってます。一応1m300円くらいのシールド線を使用しているものの、それだけじゃいかんともしがたいようで。色々調べて回ると、完全を目指すならば電気的に絶縁ということなので、そうするとフォトカプラですかね。とりあえずラズパイ直だと少し厳しそうな模様。まあシンプルにいくならArduinoにすればいいのですが。

ちなみに曲のプログラムに当たっては、MMLパーサを自作して、MMLで書いています。MMLパーサ+シーケンサコードもそのうちアップするかも。

f:id:kinokorori:20170416221049j:plain:w300

音符の長さの計算式

半分はおおまぬけな話。

以前のエントリで、音符の長さとテンポから、実時間長を計算する式を公開しました。

X分音符の時間長と音階周波数の計算メソッド - キノコの自省録

数式とプログラムで表現すると、こんな感じです。

【数式】 D=\frac{60}{T}\cdot\frac{4}{L} (T=テンポ, L=X分音符, 求める長さDは秒)

# python
def get_duration(tempo = 120, note_len = 4):
    base_ms = 60.0 / tempo
    note_rate = 4.0 / note_len
    return base_ms * note_rate
// C/C++
double getDuration(double tempo, int note_len) {
    double base_ms = 60.0 / tempo;
    double note_rate = 4.0 / note_len;
    return base_ms * note_rate;
}

この式は全く正しいので、問題なく使用できます(tempoに0を入力すると落ちますが)。

例えば、テンポT=140の8分音符の長さを算出しますと、

D=\frac{60}{140}\cdot\frac{4}{8}=\frac{60}{280}≒0.214秒

です。

以下、音符の長さにまつわる間抜けなお話。

符点4分音符は3分音符ではない

「2分音符と4分音符の間なんだから、3分音符と同じでしょ」と、ずっと勘違いしていました。同様に、符点8分音符は6分音符だと思っていたということです。

当たり前ですが、X分音符というのは、その長さが「全音符/X」という意味です。4分音符は1/4=0.25, 8分音符は1/8=0.125, 合わせると符点4分音符は0.375になります。一方、3分音符は1/3=0.333なので、微妙に短いということがわかります。ちなみに3分音符は2分音符の3連符と同じです。

符点4分音符をX分音符で表現できるか、というと、それは無理です。計算すると、8/3(≒2.67)分音符になります。

なんで気づいたかというと、作ったばかりのMMLパーサに対して、符点やタイなどのチェックをしている時です。やたらと酷い音ズレが発生したため、シーケンサーのコードのせいなのか、パーサのコードのせいなのか、上記音符の時間長計算のせいなのかと色々調べた結果、あっと気づいてしまったわけです。

パーティクルで魔法エフェクト(3) - 氷魔法編

関連記事

パーティクルで魔法エフェクト(1) - 炎魔法編 - キノコの自省録

パーティクルで魔法エフェクト(2) - 光魔法編 - キノコの自省録

f:id:kinokorori:20170327235357p:plain:w120

ウィッチクライドでは、いくつかの魔法をParticle Systemを使って表現しています。

今回は氷魔法を紹介。

氷魔法概要

前回も書きましたが、ウィッチクライドの攻撃魔法は、エフェクトを詠唱の長さに応じて3レベルに分けています。長いほど派手です。今回紹介するのは1レベル目。一番シンプルなエフェクトです。

ターゲットに雪の結晶っぽいパーティクルをワッと表示させ、外側に向かって移動+小さくなっていくエフェクトです。画像にするとこんな感じです。

f:id:kinokorori:20170410214620j:plain:w250f:id:kinokorori:20170410214622j:plain:w250f:id:kinokorori:20170410214623j:plain:w250

ムービーはこちら。

youtu.be

エフェクト実装解説

見た通り非常にシンプルで、基本は1秒間パーティクルシステムを表示しているだけです。パーティクル単体はこれです。実装にも使われています。完全不透明なので、アルファブレンディングしません。

f:id:kinokorori:20170410214913p:plain

パーティクルシステムの実装をそのまま載せておきます。Cocos-2d2なので、Objective-Cですが、他のパーティクルシステムでも基本大差ありません。

+ (CCParticleSystem*)particleIce {
    CCParticleSystem* particle = [CCParticleSystemQuad node];
    particle.texture = [[CCTextureCache sharedTextureCache] addImage:@"ice@2x.png"];
    
    particle.totalParticles = 20;
    particle.life = 1.0;
    particle.lifeVar = .3;
    particle.startSize = 60;
    particle.startSizeVar = 20;
    particle.endSize = 0;
    particle.endSizeVar = 0;
    particle.angle = 0;
    particle.angleVar = 360;
    particle.startSpin = 0;
    particle.startSpinVar = 360;
    particle.endSpin = 0;
    particle.endSpinVar = 360;
    particle.position = ccp(0,0);
    particle.posVar = ccp(10,10);
    
    //emitter setting
    particle.emissionRate = 400;
    particle.emitterMode = kCCParticleModeGravity;
    particle.duration = .3;
    particle.speed = 50;
    particle.speedVar = 20;
    particle.gravity = ccp(0, 0);
    particle.radialAccel = .2;
    particle.radialAccelVar = 0;
    particle.tangentialAccel = .3;
    particle.tangentialAccelVar = 0;
    
    //Color setting
    particle.startColor = ccc4f(5.0, 6.0, 1.0, 0.6);
    particle.endColor = ccc4f(1.0, 1.0, 1.0, 0.4);
    particle.startColorVar = ccc4f(0, 0.03, 0.01, 0);
    particle.endColorVar = ccc4f(0.04, 0.02, 0.02, 0);
    
    particle.autoRemoveOnFinish = YES;
    
    return particle;
    
}

ポイントとしては、まずターゲット中央付近、(-10,-10)〜(10,10)にエミッションします。

    particle.position = ccp(0,0);
    particle.posVar = ccp(10,10);

さらに、パーティクルに回転をかけます。

    particle.startSpin = 0;
    particle.startSpinVar = 360;
    particle.endSpin = 0;
    particle.endSpinVar = 360;

進行方向を360°全方位として、速度を30〜70の間に設定します。

    particle.angle = 0;
    particle.angleVar = 360;
    particle.speed = 50;
    particle.speedVar = 20;

パーティクル終了時のサイズを0に固定しているので、どんどん小さくなります。

    particle.endSize = 0;
    particle.endSizeVar = 0;

主な設定値はこんなところです。ゲーム中では、1秒経過後にパーティクルを削除しています。

パーティクルで魔法エフェクト(2) - 光魔法編

関連記事 パーティクルで魔法エフェクト(1) - 炎魔法編 - キノコの自省録

f:id:kinokorori:20170327235357p:plain:w120

ウィッチクライドでは、いくつかの魔法をParticle Systemを使って表現しています。

今回は光魔法を紹介。

光魔法概要

ウィッチクライドの攻撃魔法は、エフェクトを詠唱の長さに応じて3レベルに分けています。長いほど派手です。今回紹介するのは2レベル目。ガンダム界隈ではゲロビとか言われている種類のやつです。

f:id:kinokorori:20170408193630j:plain:w200f:id:kinokorori:20170408193631j:plain:w200f:id:kinokorori:20170408193632j:plain:w200f:id:kinokorori:20170408193634j:plain:w200

このエフェクトのムービーはこちら。ムービーの方がどんな魔法エフェクトかわかりやすいと思います。

youtu.be

このエフェクトを3段階に分けて解説します。

1段階目

f:id:kinokorori:20170408193630j:plain:w200f:id:kinokorori:20170408193631j:plain:w200

チャージアクションです。これは、CCParticleSunをベースに、パーティクルカラーを白色半透明に固定したインスタンスです。このインスタンスに対し、1秒かけてスケールが0.5→3.0倍になるよう線形アニメーションを発生させています。

画像ではわかりませんが、チャージ完了後、発射アニメーションに移るまで、700msほどウェイトをかけて溜めを作っています。

これまた画像ではわかりませんが、チャージ音は機械系のSEを使用しています。ウィーンという感じの音です。

2段階目

f:id:kinokorori:20170408193632j:plain:w200

発射アクションです。1段階目で作ったチャージ用パーティクルはそのままにしています。レーザー本体もパーティクルで、やはりCCParticleSunをベースにした、白色半透明のパーティクルを使用しています。

実は発射中はアニメーションを発生させていません。パーティクルを横に30倍、縦に5倍引き延ばして表示させているだけです。パーティクルのうにょうにょが、それっぽく見せているため、何か流動性のあるアニメーションが起こっているように見えます。

3段階目

f:id:kinokorori:20170408193634j:plain:w200

発射後3秒経ったら、レーザー本体をスケール0倍になるまで300msでアニメーションさせ、エフェクトを終了させます。レーザー中心点に向かって縮小するので、レーザーがあたかも移動しているように見えます。トリックですね。

レーザー本体が閉じた後、1段階目のチャージパーティクルのリバースアニメーションを発生させ、完全に終了します。リバースアニメーションなので、1秒かけて3.0倍→0.5倍にするということです。

ソフト屋の技術区分

どうも非ソフト・非技術サイドからだと、一口にソフト屋といっても、いろんな人がいることがわかりにくいようです。というか、ソフト屋でもよくわかってないことが多い気がします。

ソフトと一括りにしてしまうと、組み込みでドライバー作っている人に、「Webクライアントアプリ書いてよ。ソフト屋なんだからできるでしょ?」みたいな話が罷り通ってしまいます。これは悲劇です。ソフト=コード書く人くらいな意識です。

ということで、ちょっとソフト屋区分を整理してみました。厳密ではなく、ああ、ソフトといっても結構幅が広いのね、くらいな気持ちで。

Webクライアント屋

Webブラウザ用アプリを作成する人です。今はhtml/css/js一択でしょう。jsと一口にいっても、jQueryをはじめ、AngularJSやReactJSなど、色々なライブラリが用意されてきている上、TypeScriptやCoffeeScriptCSSでもSCSSといった技術が最近矢継ぎ早に公開されており、それなりにキャッチアップが必要な分野でもあります。

こんなに技術の変化が激しくなったのも、Webブラウザの進化によるものです。Webクライアント用言語と言えばJavaScriptなものの、JavaScriptは仕様的にあまり大規模開発に向かないため、ライブラリがJavaScriptの欠陥を補う形で、要求に合わせてどんどん変化しているといった具合です。

また、デザイナーとのやり取りが多く発生する技術分野ということもあり、デザイナーとのコミュニケーションや納入、実装がかなりのウェートを占めると思います。一昔前のjQueryのみでのAjax実装だと、JavaScriptコードにhtmlやcssのコードが散乱して、めっちゃくちゃなことになっていました。そういうこともあって、ReactJSなどの技術が生まれているのではないかと思います。

Webサーバ屋

Webサーバ上のアプリを構築する人です。言語はPHP, Perl, Ruby, Javaあたりがメジャーで、最近ではNode.jsやPythonなども。大抵は外部公開部分(WebAPI)→コントローラ→データベースまでの処理を書くことがほとんどです。Webサーバにはデータベースがつきものなので、SQLの知識は必須です。

Webサービスがビジネスの根幹を担うことが多いこともあって、JavaPHPが書ければ食いっぱぐれないと言われるくらい、お仕事が見つかる分野でもあります。

フルスクラッチですべて書き起こすことは稀で、大抵はRailsやCake, Laravelなどのフレームワークに乗っかって実装を行います。最近は、サーバレスと言われるアーキテクチャが登場しており、それを使うならば機能モジュールの組み合わせでシステムを実装することになります。

Webサーバアプリは、コントローラ層のアーキテクチャ、データベース処理、セッション管理、セキュリティ、並列化あたりがカギだと勝手に思っています。この辺の設計が適切に行えるかどうか。

昔は、負荷分散や冗長化、デプロイやステージングといったインフラ部分を含むことが多かったですが、最近ではその部分はインフラ担当として明確に分けられていると思います。

サーバインフラ屋

サーバのインフラ担当です。あまりコードを書くことはしませんが、OSとネットワークの知識(主にLinux)が必須で、各種開発支援ツールのconfファイルの編集、シェルスクリプトなどを組んで自動化したりといったことを担当します。また、サーバ保守も大抵の場合担当します。

クラウドサービスが主流となったことで、インフラ周りも随分様変わりしたように思います。クラウドサービスが流行る前は、自社内でブレードサーバを物理的に組み上げて、サーバ自体の冗長化NIC冗長化、ハブ・スイッチの冗長化など、自分たちで色々考えて信頼性を担保していました。いわゆるオンプレミスというやつです。

昨今のクラウドサービスでは、冗長化はもちろん、スケールアウト(負荷に応じてサーバを増やす)も自動でやってくれますし、スケールアップ(サーバ自体の性能を上げる)もポチポチするだけで終わってしまいます。凄い時代になったものです。

かといって、インフラ屋がやることなくなったかというと、そんなことはなく、物理的な心配がなくなっただけです。デプロイやステージングを考えたり、JenkinsやGit、SlackやRedmineといった開発支援のためのツールをうまく組み合わせて導入したり、シェルスクリプトを書いて自動化したりと、結構大変です。特に、ツールは流行り廃りもあるため、常にアンテナを高く張っておかないと、ついていけなくなったりします。

また、最近のクラウドサービスでは、普通のサーバインスタンス(AWSならec2)だけでなく、色々なモジュール(AWSならLambdaやAPIGatewayなど)が用意されるようなってきています。どういったものがあるかといった知見も広げておく必要があると思います。

DeepLearningなどでビッグデータを扱うとき、クラウド上で実験すると課金死するため、HadoopやSparkなどの分散処理システムを組み上げる必要に迫られます。この辺をスッとできると途轍もないイケメンです。

Webクラサバ・インフラをひっくるめて一人でできるスキルを持った人を、フルスタックエンジニアと呼んでいたこともありますが、最近でも言うのかどうか不明。

システムエンジニア

いわゆるSEです。この人は基本的にコードを書きません。要求されたシステムをどう組み上げればよいか、どういう技術と人が必要で、どれくらいかかりそうかを見積もって、スケジュールを立てる人です。QCDの番人。

コードを書かないからと言って、コードが書けなくてもいいわけではありません。自身の経験が、それぞれのタスクがどれくらいかかるかの工数見積もり精度に跳ね返ってきます。

また、浅くても良いので広い知識が必要です。「IoTデバイスから収集したデータをスマートフォンで閲覧できるシステム」の構成を考えなければならない時、IoTデバイスはサーバにどうやってデータを上げるのか、iOS/Android特有の癖、データベースはどうするのか、リアルタイム性はどこまで求められるのかなどを把握する必要があります。OSI参照モデル7層って何?httpなにそれ、iOS/Androidよく知りません、RDBMS/KVSって何?WebAPIって何?では仕事にならないでしょう。

システムが担うドメインの知識も必要になりますが、そこは知らなくても、客先やプロダクトオーナーから話を聞き出したり、不明な点を洗い出したりすることで補うことは可能です。逆に言うと、「不明な点」を正確に捉える能力が必要です。

プロダクトオーナー(プロデューサー)との連携も密に取る必要があり、場合によっては客先に技術説明をしに行ったり、技術的な不明点をヒアリングしに行くこともあります。

フレームワーク屋・ソフトウェアアーキテクト

こういう区分でいいのか迷うところですが、大き目の社内開発プロジェクトのソフトウェア構成を統括する設計者です。

この世には汎用フレームワークSDK、例えばUnityなんかもそうですが、そういったものが数多あります。しかし、それらはあくまで汎用であって、個別プロジェクトに最適化されているわけではありません。そのため、SDKだけ無計画に社内プロジェクトに導入しても、即座に破たんします。そのため、全体的なソフト設計、および適切なルール作りが必要になります。

この役割の人は、オブジェクト指向デザインパターンを適切に行使でき、プロジェクトで使用する言語のイディオムを把握している必要があります。ドメインの知識も必要で、開発チーム間の調整も多く発生します。決断力がない人や手持ち選択肢の少ない人にはあまり向きません。また、この役割の人が適当な指示を出すと、開発後段になって工数が雪だるま式に増えていき、バグつぶしがモグラ叩きの様相を呈するようになります。そしてメンバーは終わりの見えないプロジェクトに嫌気が差し、心を病むようになります。

また、同じ業務をずっとやっている人より、色々なシステムや言語を触ったことのある人の方が適任です。

フロントエンド・アプリ屋(Web以外)

これもまた定義が難しいところではありますが、提供されたSDKやプラットフォームAPIをたたいて、GUIアプリケーションを作り上げる人です。フロントエンドと一口に言っても、Windowsなら大抵C#.NET、MacならCocoaマルチプラットフォームならJavaAIR、Qtなど、多岐にわたります。インタフェース記述言語もFormデザイナ、InterfaceBuilderやXAML, Flex, QtQuickなどバラバラです。

GUI設計においては、どうすれば使いやすいかといった、ユーザビリティ的な考えだけでなく、どうすれば楽しく操作できるかといった観点も結構重要で、UIの工夫がそのまま強力な特許となることが多々あります。ソフトウェア特許でUI発明というのは、侵害検知が非常に簡単なため割と重宝されます。

GUIとプラットフォームとを繋ぐ部分については、システムによってサイズが大きく異なります。1人で開発できる程度のものから、1モジュールだけで1チームが割り当てられるものまで様々です。1チーム必要なレベルのモジュールが入っている場合、それがその企業のソフトウェア価値に直結することが多いのではないかと思います。専門部隊とか呼ばれたりします。

スマホアプリ屋

フロントエンド・アプリ屋の一種で、スマホ、主にiOS/Androidアプリを作る人です。スマホアプリといっても、FGOやデレステみたいな大規模なものではなく、ここでは1,2人程度で作成する小規模なものを想定しています。

iOSならばObjective-C/Swift, AndroidならJava, UnityやXamarinなどを使用するならC#も絡みます。スマートフォンは結構癖の強いデバイスのため、開発言語だけでなく、それぞれのプラットフォーム固有の知識が多く必要になります。開発経験が全くないと、HelloWorldプロジェクトのビルドすら難しかったりします。また、iOSが出来るからと言ってAndroidが出来るとは限らず、逆も然りです。実際、どっちも書ける人はそんなにいません。Androidが出来るんだったらiOS版も作ってと気軽に言ってはいけません。

繰り返しになりますが、スマートフォンは癖の強いデバイスで、完全に独自の世界を構築しています。AndroidiOSも、ビックリドッキリ機能やお約束があったりするので、開発未経験の人に仕事を振っても、そうそうすぐにアウトプットは出てこないと思った方が良いでしょう。

ミドル・BSP・ドライバー

組み込み系の人たちです。ざっくりまとめてしまいましたが、組み込みといえばここがメインです。大抵の場合、使用する言語はC/C++です。

この界隈の人たちは、バイナリデータを扱うことが多く、デバッグコンソールに表示された16進の羅列を読み取る変な能力が身に付きます。かなりハードウェアに近いところにいるためか、あまりソフトウェアの設計能力は高くなく、C++であっても、Better Cとして扱うことを好む人が多いように見えます。

この人たちのやっていることは、Androidスマホを思い浮かべるとちょっとわかりやすいかもしれません。Androidは、Androidプラットフォームだけが共通で、ハードウェアはそれぞれの会社が独自で用意します。Androidスマホの性能を語るとき、PCと同じようにCPU+メモリ性能で考える人がそれなりにいますが、そう単純ではありません。Androidスマホは組み込み機器です。例えば、SoC基板、WiFiモジュール、GPSモジュール、Bluetoothモジュール、タッチパネル、物理キー、マイク、スピーカー、LTEモジュール、バッテリー、センサー等々が、メーカーごとに異なります。ということで、これらが1つの機器上で動作するように制御するのが組み込みエンジニアの仕事です。

これらのハードウェアをぐさっと繋いだら動くかというと、当然そんなわけはなく、まずは全てドライバーを用意しないと動いてくれません。で、ドライバーが全て用意されたらOKかというと、そんなことはなく、システムとして全体を繋いだり、キャリブレーションしたりする必要があります。システムとして繋いだらOKかというとそんなことはなく、SDK側から呼び出し可能なようにAPIを整理しなければなりません。

音声経路、映像経路(フレームバッファ)も、何もしなくても出力してくれるようなことはありません。ちゃんと制御が必要です。音声ドライバはAndroidだとALSAを使うことが多いと思いますが、音なんか鳴ればいいんじゃない?みたいに設計すると遅延が酷くなります。

Androidスマホの品質がメーカーによって異様なほどバラバラで、PC的なスペックの観点があてにならないのは、これでなんとなく想像つくのではないでしょうか。組み込みエンジニアというのは、こういう世界の人たちです。

マイコン

マイクロコンピュータ用の制御コードを書く人で、組み込みエンジニアの一種です。回路屋に一番近い位置にいます。

AVRやH8などの小規模マイコンと、FPGAなどの高性能マイコンがあり、前者はCやアセンブラ、後者はVHDLを使用します。最近では、VHDLの代わりにSystemCが用いられることも増えてきたとかいう話も聞きます。

マイコンが必要になるのは、在りもののモジュールでは事足りず、ハードウェアを独自に制御する場合です。そのため、通信プロトコル仕様も、開発者が考える必要があります。この仕様を、ある程度将来の拡張に備えて設計しないと、通信プロトコルがころころ変わることになり、その度にドライバー屋が苦労します。

ちなみに私はAVRをたたいたことがある程度で、この分野詳しくありません。まあ、7年前に書いた下記エントリー見れば推して知るべしというところではありますが・・・

ソフト屋はハードウェアがわからない - キノコの自省録

コンピュータサイエンティスト

計算機科学の研究者です。圧縮技術、映像・音声符号化、暗号、機械学習、最適化、データサイエンスなど、色々なテーマがあります。この分野の人たちは、C++, Python, R, Matlabあたりを使うことが多いと思います。大抵のソフトウェアエンジニアリングの業務は、高等数学や物理の知識なんかほとんど必要ありませんが、コンピュータサイエンティストには必須です。

エンジニアではなく研究者のため、専門以外は実はよく知らないという人も結構いたりします。大学ではなく、コーポレートラボ付きの人であっても、ソフトウェアのトレンドに全く詳しくないということもザラです。ただ、地頭の良い人が多いため、何も知らない状態でも、しばらくするとあっさりキャッチアップしたりします。恐るべし。

終わりに

ということで、最近のソフト技術区分をなんとなく書いてみました。ソフトと一口にいっても、こんなに種類があるのか、と思っていただければ。

X分音符の時間長と音階周波数の計算メソッド

YMZ294を弄っていて必要になったので、公開しておきます。これ使って風色メロディ鳴らすことができたので、たぶん合っていると思います。

Raspberry piで遊んでいるので、コードはpythonです。

# ymz294_util.py
# -*- coding:utf-8 -*-

__scale_freq = []

C = 0
Cs = 1
Db = 1
D = 2
Ds = 3
Eb = 3
E = 4
F = 5
Fs = 6
Gb = 6
G = 7
Gs = 8
Ab = 8
A = 9
As = 10
Bb = 10
B = 11

def get_duration(tempo = 120, note_len = 4):
    base_ms = 60.0 / tempo
    note_rate = 4.0 / note_len
    return base_ms * note_rate

def get_freq(scale=A, octave=4):
    scale_number = 12 * octave + scale
    return __scale_freq[scale_number]    

for scale in range(88):
    ex = (scale - 57) / 12.0
    f = (2 ** ex) * 440
    __scale_freq.append(f)

ymz294_util.get_freq(scale, octave)を呼び出すと、その音階の周波数を返します。ymz294_util.get_duration(tempo, note_len)を呼び出すと、テンポと音符から算出したノートオン時間を秒単位で返します。