お腹.ヘッタ。

関数型とかセキュリティとか勉強したい。進捗つらぽよ

リーン開発の現場を読んだノート

リーン開発の現場

という本のノートを描いて見た。この本は実例を交えながら紹介している本である。

当ノートは自分なりに本の中身を元にまとめて見ている。 個人的に後から考えてもいいのではみたいな章は省いたり、簡約したり纏めたりしてる。他にも自分で知っていることを含めて見たりもしているので必ずしもこれが正解とかは言えない可能性もあるのを忘れずに。

さて、そもそもアジャイルとかリーンとは何じゃ、ということをざっくり説明します。

アジャイルの概要

ソフトウェアコミュニティの17人のオピニオンリーダーたちが2001年にユタ州のスキーリゾートに集まってソフトウェア開発を成功させる方法について議論しお互いの考えを擦り合わせていくうちにアジャイルソフトウェア開発という言葉が誕生しました。そしてソフトウェア開発を成功させる方法に関する共通のビジョンを見つけて文章化したもので、いわゆるアジャイルマニフェストと呼ばれる文章になったもの。 内容を以下に示す。

私達は、ソフトウェア開発の実践、あるいは実践を手助けする活動を通じて、より良い開発方法を見つけ出そうとしている。この活動を通して、私たちは以下の価値に至った。

  • プロセスやツールよりも個人と対話を。

  • 包括的なドキュメントよりも個人と対話を。

  • 契約交渉よりも顧客との協調を。

  • 計画に従うことよりも変化への対応を。

価値とする。すなわち、左記の事柄に価値があることを認めながらも私たちは右記のことに価値を置く。

  • 顧客満足を最優先し、価値のあるソフトウェアを速く継続的に提供する
  • 要求の変更はたとえ開発の後期であっても歓迎する。変化を味方に身に付けることでお客の競争力を引き上げる。
  • 動くソフトウェアを2〜3週から2〜3ヶ月という短い時間の間隔でリリースします。
  • ビジネス側の人と開発者はプロジェクトを通じて日々一緒に働かなくてはいけません。
  • 意欲に満ちた人々を集めてプロジェクトを構成します。環境と支援を与え、仕事が無事終わるまで彼らを信頼します。
  • 情報を伝える最も効率的な方法はフェイストゥフェイスで話すことです。
  • 動くソフトウェアこそが最も進捗の重要な尺度である。
  • アジャイルプロセスは持続可能な開発を促進します。一定のペースを継続的に維持できるようにしなくてはなりません。
  • 技術的卓越性と優れた設計に対する普段の注意が機敏さを高めます。 シンプルさが本質です。(言い換えると無駄なく作れる量を最大限にすること。)
  • 最良のアーキテクチャ・要求・設計は、事故組織的なチームより生み出されます。
  • チームがもっと効率を高めるかどうかを定期的に振り返り、それに基づいて自分たちのやり方を最適に調整します。

アジャイルという言葉自体は2001年に誕生したが、ほとんどのアジャイルの方法論は1980年代にはすでに作られていた。アジャイルはこれらを包括的に指す言葉で、様々な共通点があればアジャイルとも言えなくもない。 つまり全てアジャイルとも言える。 逆に言えばではあるが、これらの共通点原則を持つものをアジャイルという多面的な表現を許容することでもあると考えれる。

スクラムの概要

ソフトウェア開発のフレームワークのことである。1990年ごろにできた。 スクラムは経験則に基づいたプロセス制御や複雑適用系理論を元にしている。 以下にコアコンセプトを説明する。

  • 順番付けされたプロダクトバックログ

  • 実現すべき事柄を小さくリリース可能な作業一覧に分割することを指している。

  • プロダクトオーナー(OP)はプロダクトビジョンを定義して、ビジネス価値やリスク、依存関係などのエレメントに基づきプロダクトバックログを作る。

  • 要は全体の仕事の山を分割する。

  • 職能横断型チーム
    • 自己組織化したチームに小さく分割していく。
    • それぞれのチームにはPOとスクラムマスター(SM)が存在している。POはビジネス全体のプライオリティをチームに提供して、スクラムマスターはチームの改善や障害を取り除く作業に力を注ぐ。
  • スプリント
    • 開発期間を短く固定されたイテレーションのことを指す。例えばリリース期間とかのこと。
    • 目標まで走り抜けるのでスプリンターから来てる。
      • しかし。短距離ランナーではなくペース配分をするマラソンランナーの方が現実は正解なのであるのは忘れずに。
  • 継続的にリリース計画を調整する。
    • プロダクトオーナーはリリース計画を最適化し、各スプリント後のフィードバックを顧客と強調しながら優先順位について更新する。
  • 継続的にプロセスを調整する。
    • それぞれのフィードバック後の振り返りによって最適化していく。

大人数で長い期間大きなものを作るのではなく、少人数で短期間で小さいものを作るのがスクラムであるということである。

XPの概要

1990年中盤に生まれたエクストリームプログラミングとは

  • シンプル

  • コミュニケーション

  • フィードバック

  • 勇気

  • 敬意

というジャンプばりの五つの価値を基盤にしたものである。 スクラムと並行して進化して来たためにほとんど同じ要素を持っている。例えばXPにおけるオンサイト顧客はスクラムのプロダクトオーナーとほぼ同一。

じゃあスクラムと何が違うかというと外向的か内向的かである。

スクラムはしばしばXPを取り囲んでると言われる。何故ならば組織構造の課題や外部とのコミュニケーションに着目しているからである。

ではXPはどうかというと、エンジニアリングプラクティスが主幹的だったりする。

  • 継続的インテグレーション
  • 自動ビルド、自動的な統合。そしてチームが開発したコードを自動テストする仕組み。これによって作業の品質が関わる早期のフィードバックをチームはより早く得ることができる

  • ペアプログラミング

  • ペアでプログラミングする。学習や設計品質を最大限引き上げることができる。また欠陥の発生を最小限にできる。
  • ペアのレベル差が大きいと片方のレベルが格段に上がる。

  • テスト駆動開発

  • テストコードを書いてテストを通すためのコードを書く。
  • またリファクタリングをしてコードを洗練させていく。

  • コードの共同所有

  • チームメンバは全員ソースを修正することが許されている。また奨励されている。これにより理解が進み協同的な感覚が生まれる。

  • インクリメンタルな設計の改善

  • 初めはシンプルで実現可能な設計から始める。
  • その後改善してブラッシュアップしていくアプローチ

カンバンの概要

カンバンはアジャイルソフトウェア開発におけるリーン的なアプローチだ。これは日本語から来てて工場にあるカンバンと同じところから来ている。つまるところ物理的な伝達システムのこと。

しかし、勘違いしてはいけないのが2004年にデイビットアンダーソンがソフトウェア開発におけるカンバンとしたのだ。間違っても天井に貼り付けるあのカンバンとは微妙に違う。

カンバンのルールを以下に示す

  • ワークフローを可視化する。
  • 作業を小さく分けてそれぞれをカードに書いて壁に貼り付ける。
  • それぞれのカードがワークフローのどのstatusであるのか可視化するためにそれのラベルのついたものに貼り付ける。

  • WIPを制限する。

  • サイクルタイムを測定し管理する。

  • これを元にプロセスを最適化していく。
  • 例えば人員の転換やさらに仕事の分割など。

リーンの概要

リーンとは「TPS」というトヨタ生産方式を元にしたものである。(というかぶっちゃけ同じで西洋でTPSと呼ばれるだけの話。)このTPSという方式は様々なものに適用可能とされている。その中にはソフトウェア開発も含まれる。

よくある勘違いとしてアジャイルとリーンは共通の価値があるために親戚や同一視されるが起源は異なっている。 リーンは製造業から、アジャイルはソフトウェア開発から誕生した。お互いの原則は相性が良く、適用できる範囲も広い。 最近多いのは製品コンセプトの開発〜デリバリまでというエンドツーエンドの開発の流れ全体でアジャイルとリーンをどう組み合わせて適用していくのかということが探求されている。

このリーン(TPS)の原則を、リーンソフトウェア開発として提唱したのがメアリー・ポッペンディークとトム・ポッペンディークである。

全体を最適化する

システムの一部分の最適化に時間をかけても必ずしもシステム全体の最適化にはならない。

  • ストリーム全体を最適化する。
  • つまりコンセプトからデプロイまでの包括的な部分を指している

  • 完全な製品を提供する。

  • 顧客の一番の目的は問題解決なのでそれを解決できるソフトを作ろう。

無駄をなくす

無駄とは、顧客に価値を付加することのないあらゆるものである。ソフトウェア開発では3つの大きな無駄がある。

  • 間違ったものを作るという無駄。

  • 学び損ねるという無駄。

  • 頻繁な引き継ぎや現場からかけ離れれた意識決定などいわゆる方針のブレのことを指してる。

  • 過度な作業切り替えによる無駄。

品質を作り込む

プロダクトのテスト段階で毎回過度の欠陥が見つかるのであればプロセスに問題があると言える。

  • 最終テストで欠陥を見つけないような仕組みづくり。

  • テスト駆動開発による誤りを防ぐプロセス。信頼を担保し続ける必要がある。

  • 依存関係を断ち切る。

  • 機能追加や変更を可能な構造をすべきで疎結合なものであるシステムアーキテクチャである必要があるべき。

たゆまぬ学び

計画は立てることに意味があり、学びを得ることにその本質がある。この学びというのは実験を重ねることなどを指している。

  • 成果の予測可能性はフィードバックにより高まる。

  • 選択肢を幅広くもつ。

  • 変化への耐性を持たせる。

  • 意思決定を最終責任地点まで遅らせる。

  • 取り返しのつかない所に来る前に(決定とも表現) 可能な限り学習をしてできるだけ実験を重ねる。

速く提供する

ステークホルダー全員についての深い理解と、彼らにとっての価値を何かということを考えるところをから始めるべき。 それによって継続的にビジネス価値を生み出していく流れを作る。

  • 素早いデリバリと更新しつ。低コストでの実現。

  • 待ち行列理論は鯖だけではなく開発にも応用できる。

  • ゆえにプロセスには作業の塊を小さくして少しずつ流す。代わりにサイクルタイムを短くしていく。

  • ワークフロー管理はスケジュール管理よりも簡単にできる。

  • 任意の日にリリースする最善の方法はイテレーションやカンバンシステムを使ってしっかりとイテレート可能なワークフローを確立することにある。

全員を巻き込む

優秀なメンバーは起床資源である。チームメンバーは公平かつ公正に適切に対価を得る人々であり、自律、熟達、目的に応じて意欲を感じるのだ。

  • 自立
  • 効率よく働くチームのメンバーというのは半ば自律しているチームである。チームにはメンバーの精神面を支えるリーダーが存在し、リーダーは完了させるべき作業や意義のある作業について始めから終わりまで責任を持つ。

  • 熟達。

  • 人に敬意を払うことでチームの誰もが素晴らしい人なるための挑戦やフィードバック環境が生まれる。

  • 目的。

  • 仕事と価値を繋ぐものが目的である。仕事の意義を感じることで初めて人々は目的の達成に没頭する。

改善を続ける

結果が重要なのではなく、人と結果を出せるシステムを育てるのが重要なのである。

  • 失敗とは学ぶ機会である。
  • 小さな失敗でえ注意深く調査し、修正すれば最高に信頼できるパフォーマンスを生み出せる。

  • 標準は挑戦や改善のために存在する。

  • 現在の標準になっている物への挑戦や変更を奨励していく。その上で現状最も知られていて誰もがわかる理解を標準化していく。

  • 科学的な方法を使う。

  • 仮説の検証法、早くたくさんの実験を行うやり方、簡潔なドキュメントの作り方。これまでとは違った良いやり方をやる。

つまるところある種の信頼が担保されたものを実行することである。 何言ってるんだって感じなのでつまるところ、

  1. 顧客の目で「価値」を定義。

2.その価値の流れを可視化する。

3.それを「エンドツーエンド」で「細く、速く」流れるようにする。

4.その流れの改善活動を現場で実際に仕事をしてる人が行う。

ということである。以下から実際に当該書籍を元に紐解いていこう。

一章 プロジェクトについて

スウェーデンの国家警察で作ってるPUSTという新しい捜査報告システムを元に紹介する。これを実現するにはある要件を満たす必要があった。

  • 膨大な量のレガシーなシステムと統合

  • 相手に質問しながらリアルタイムでシステムを使うため警察官にとって簡単に使えるシステムである必要がある

  • 堅牢なセキュリティ

  • たくさんの複雑な法律や規則を遵守しなくてはいけない

  • スケジュールが厳しい

タイムライン

スタートは2009年9月から。一年後にはリリース。その後は隔月でリリース。 スケジュールの中で重要なマイルストーン

  • 1.0の最初のバージョン

  • 1.4の警察全体で使えるようなったバージョン

早めにリリースしていくスタイルである。 理由としてはバグや思い込みなど仕様をすり合わせつつ行うことのできる点にある。よって頻繁なリリースをするというのは一度のリリースに抱えるリスクを減らすと言えるだろう。 また、リーンの特徴として開発のプロセスがどんどん変わって、進化し続けることが挙げれる。

スケジュール分割について

大きなプロジェクトでリスクを最小化する鍵は大きな像を分割する方法を見つけ出すことである。こうすることで、小さい機能を徐々に増やしていくことができてシステムを何度もリリースするインクリメンタルリリースを行える。リスク分散の観点からもユーザーにそれぞれ価値を送りフィードバックをされていくというより良くしたいという流れからも良い作業と言える。 今回の場合は地理的な場所犯罪者別という点から最小化にかかった。

  • リリース1.0から1.2
  • 一つの地域のみに対応。
  • 飲酒運転など武器の所持。よくある多い犯罪種のみ対応。
  • 徐々に犯罪種のサポートを増やした

  • リリース1.3:

  • 2つ目の地域に対する拡張リリース
  • これをメインリリースとした

  • リリース1.5

  • 犯罪種別を追加押収品の管理システムなど他のシステムと統合したバージョンをリリース このような形に分割した。

顧客について

これは警察組織のプロジェクトで顧客やユーザも身内であった。がこれは当該プロジェクトではある一人が主役である「顧客」として振る舞った。 エピックにあってるかどうか、詳細なフィードバックをもらうなどを行った。 (エピックは一般的には壮大な作品という意味だが、この文脈では大まかな要求大きなストーリーという意味である。)

二章 チーム編成

ソフトウェア開発プロジェクトにおける難題の一つとしては適切な人数でチーム編成して、不空のチームが強調して動くためにはどうすれば良いのかというのが挙げれる。 メンバーの人数が増えるに従ってコミュニケーション問題やコラボレーションの難しさにぶち当たる。組織が成長する際によく発生する痛みの症状と同じ。 初めの小さい頃は疑問があれば人数が少なく近くにいることが多いのでどのように運営するかなど方針に対する容易に行えた。 これに対して、実際人数が増えたが上手くいけたのはメンバーが一つの場所で働いていたことにあるだろう。また柔軟にチーム編成を進化させた。今では5チームで行っている。

  • 要求分析

  • システムテスト

  • 機能開発が3チーム

  • チームではなく、プロジェクトマネージャや構成管理、パフォーマンステスト、コーチなどがいる。

さて。 三つの開発チームは基本的によくあるスクラムチームで構成されている。職能横断型で、自己組織化していて、昨日全体と開発とテストする能力がある。 要求分析のチームは仮想的なチームでアナリストが所属していて、基本的に他のチームに所属しながらなので仮想的。 これによってプロジェクトメンバー全員が分散して配置されている。 また、この理由としてアナリストと各プロジェクトの人たちがコミュニケーションを取りやすいようになっている。

基本的に要求分析チームは3つの役割をこなすことになる。

  • 何人かのアナリストは機能開発チームの一つに所属し、開発者からの質問に答えて要求を明確にするために、開発からチームの開発をサポートする。

  • 何人かのアナリストはどの機能開発チームにも参加せずシステムの全体像の分析に重点を置いて取り組んでいいる。彼らはシステムの概要となる昨日エリアを定義するために、将来像を見定める。

  • 残りのメンバーは上記の2つのうちどちらかに柔軟に横断して必要な作業を行う。

テストチームも同じように、

  • 何人かのテスターは機能開発チームに属して機能レベつのソフトウェアテストデバッグを手助けする。

  • 何人かのテスターはシステムの全体像に対するテスターで、リリース候補版の概要レベルのシステムテスト結合テストの実施に力を入れている。

  • 残りのメンバーは2つのうちどちらかに柔軟に横断して必要な作業をする。

初めはチームは担当する作業で分けて編成していた。要求分析チーム、テストチーム、機能開発チームをはっきり区別し、テスターやアナリストがいなかった。

しかし、これによってコミュニケーションの問題でスケールが上手くいかなかった。さらには担当するチームで分けてしまうとチーム間のコミュニケーションを文章で行ってしまうことが多くなった。そして問題責任の押し付け合いが始まってしまった。また、それぞれのチームは自分の仕事だけの完了だけをしようと考えがちであった。

例えば、アナリストであれば機能が本番環境にリリースするまでに行われる開発やテストに付き合わなくなったりする。これは要件定義を書き終え、自分の手から離れた時に機能に関する自分の仕事が完了したと考えてしまうからである。 コラボレーションの質は、スクラムのような職業横断型のチームに進化したことで劇的に改善した。

しかし、何でもかんでも一つのチームで行うのではなく、何人かのアナリストやテスターを機能開発チームから引き離してシステム全体を見るようにした。

三章 ミーティングについて。

当該書籍では朝10:15前までに3段階のミーティングを行う。

第一段階:機能開発のスタンドアップミーティング

自分たちが使っているtaskboardに立って今日やることや取り組むべき問題や課題について意見交換をしていく。 場合によっては昨日やったことや昨日やること、困っていることと言った3つのことを話すと言うことをしている。

第二段階:スペシャリティ同期(synchroの方)ミーティング

チームごとの話や各場所で行ったことを初めに決めたグループを超えて話し合う。

第3段階:プロジェクト同期ミーティング

これは組織をバラバラに考えて少数精鋭で行ったりする。これは全体的に長期的なスパンで俯瞰したり、フォーカスを広く持つことをひつようとする。

これらのミーティングの特徴として、ボトムアップからのアプローチであることが挙げられる。 細かいディティールから大きな対局へ見ていく。 その際には人を変え、場所を変え、問題を変えて課題を認識して解決していく。

これによって大きな問題を分割していくことができる。

また、これに関してはある固定した期間を持たせて無制限で行わない。また必要に応じてこれをなんどもイテレートする。 ex,9時ごろミーティングを15分、お昼に15分、帰り前に15分。 場合によっては柔軟に増やしていく。

四章 プロジェクトボード

プロジェクトボードとは、プロジェクトにおいてコミュニケーションの大元になるものとすべきものである。具体的にはプロジェクト全体の状況などを見せる。これは、カンバンシステムであったり、ストーリーマッピングであったり、様々な形が考えられる。

当該書籍におけるプロジェクトのカンバンを例に取ろう。 アイディア->機能->次の作るべき10機能->開発->システムテスト->ユーザー受け入れテスト->本番 となっている。 これらはすべてフローとなっている。

何点か細かいディティール例をあげたいと思う。

  • 機能
  • 大局として考える。
  • ユーザーストーリーと呼ばれるフォーマットで書かれている
  • XとしてYをしたい、何故ならばZだから
  • と言うフォーマット
  • ex:捜査官として住所を検索するときに地域によって絞り込みをしたい。何故ならば住所を早く見つけることができるからだ。

  • 次の10機能

  • これは先ほどのエピックといえる機能を細かく分割する。
  • 具体的に詳しい機能や必要な要求を展開する。
  • ここの中身こそミーティングでブラッシュアップを必要だったりする

  • 開発とシステムテスト

  • 継続的インテグレーションを行っていき、機能レベルのテストが出来ならばシステムテストを行っていく。
  • このときgit上には別バージョンのブランチを作って扱おう。
  • ここで素晴らしい点はここも大きい単位でテストを行うのではなく、小さい細かい単位でテストを行うこと、当該書籍の言葉を使うと継続的システムテストを行っている。

ウォーターフォールとの大きな違いとしては、初めから要求を完全に分析しているかしていないかの違いである。 カンバンシステムでは全てのフェーズを並行して進める。これよってフィードバックによるアイディアを組み込みやすく、フローとして価値を作り続けているのである。

ここでもひとつ忘れるべきではない点について、緊急の課題や、ボトルネックについての処理である。 パターン的にはマーカーをつけていろんな人からフォローをもらわなくてはいけないとわかる。

しかし、これをどのように機能させればいいのか。少人数なら気にすることはないが、大人数ならばどのようにすればいいのか。 それについて次章に入ろう。

五章 カンバンボードをスケールする

一般的にプロジェクトが進むスピード大部分は、メンバーがどれくらい状況を理解しているかによって決まる。 もしも、メンバ全員が何をしていてどこにいるのか、何が起きてるのかを理解していれば同じ方向に進むことは容易であると言えるだろう。 そう。そのためのカンバンボードである。

しかしながら、人数が増えてやることも増えたら付箋だらけだったりカードだらけでとても扱いにくいものになるだろう。 そこでカンバンを分割してあげることをする。例えば開発についてであれば複数チームがいる際に、自分のところに今やるべきメインの課題などは機能開発チームが持っていることをメインのカンバンで示してあげて、議論が深くなるであろうディテールの部分は各開発チームのボードに書き込むなどをすると言ったことができる。

ここでのポイントは階層に分けることである。しかし流れスタックは溢れてしまうものなのでWIPの制御をして行うことなどをしよう。またちゃんと同期しないとあとあと大変なことになるので注意。

六章 プロジェクトゴールの管理

プロジェクトの全体のゴールを理解していると、プロジェクトメンバーはゴールに向かって集中するようになる。 それはそうという話ではあるんですが、実際に行っていくと意見の食い違い等があることがわかる。 なのでゴールへの理解のすり合わせを行う。具体的にはミーティングのプロジェクト同期ミーティングで行ったりするべき。 彼らは初めの方はなかなか難しいという評価をするかもしれない。しかしそれに対してどのようにモチベーションをあげていくのか。また、仕様書は共通認識ではないということを理解して、ストーリーマッピングをするということを行わなくてはいけない。

これらのことは定期的に行うべきである。これによって現状とゴールのチェックを行うというのは、進捗とチームの士気と意識についてを知ることである。

技術課題を捌くとバグを捌く

以下は章に合わせず必要なことを纏めて書き留めていく。

技術課題さばき

技術課題が出てくるのは仕方ない。なのでどれくらいそれにコストがかかっているかを機能の情報と別に用意して作る。要は機能カードと技術課題カードにそれぞれどれくらい労力を必要としてるか見えるようにしよう。

やるべきものにうまく乗っていくために。

例えばリファクタリング。あまりにも技術的負債が大きいと、とてもやりたくないものである。しかし、これを嫌だからと言って看過してしまうとその後技術的負債は増大していく。

この場合は、実際にこの脅威を可視化するといい。 この場合であれば実際にそのクラスファイルを印刷をかけて、どれくらいが理想のコードサイズであるかを示すべきである。 それによって僕らが行わなくてはいけない技術的負債の線引きガン見えてくるだろう。

また、リリースの前のパイロット版にはそれに対するリハーサルをコストとして見ていこう。どこまで用心することに越したことはない。

バグさばき

カンバンを使わないで捌くとテスターがバグを見つけて、開発のサイクルの終わりにバグを見つけては要求分析にプライオリティをつけて、変更管理ミーティングをしてそれに対するコストにシンクロさせていく。

が、しかしこんなのは厳しいのでしっかりとカンバンを使いたおそう。

  • 継続的システムテスト
  • 要は大きいテストをやるのではなく、一つのスプリントごとなど小さいうちに部分のテストを行っていこうというスタイル。
  • これの良い点はバグを探すなど無駄な本質から離れたことで時間を多く取らなくても済む点である。そう考えると結果として最後にまとめてテストする場合と比べると時間に関するコストが明らかに軽減される。

  • さっさとバグをぶっ殺せ。

  • テスターがバグを見つけたらさっさと殺す。いっそその場で殺しにかかるのがベターだろう。
  • 後からバグとかで揉めるより効果的
  • 会って話すというコミュニケーションをするということはバグトラッキングのシステムに状況を記述するよりも対面でのコミュニケーションの方がドキュメントコミュニケーションより多くを知ることができからである。
    • しかし、これについてはただ会って、口頭で話すというだけではなくユーザーストーリーのフォーマットなどある種のフォーマットで簡潔に述べたものを用意してそれに対するディティールとしてテスターが受け持つのが良いと言えるだろう。
    • また、引き受けたことがあるバグに近いタイプのをなんども引き取ってしまうことがあるので、バグに関する統計を取るのおも良いと考えれるだろう。
    • 開発者とテスターがお互いの仕事に関して学び合うのでチームとしての改善点など多くが見えてくると考えれる。
    • 簡単な細かい古いバグが含まれたタスクカードの管理に無駄な時間を使わなくても良い。(難しいのは適宜対応
    • では大きい難しいのはどうするのか。そういうものを優先して積極的にバグとしてバグトラッキングシステムに登録する。細かいものは統計は取るが、追加などはしない。
    • この際、どこまでもサイズが増大する可能性がある。よってバグの登録数にはラインを引く。30個とか適当なサイズを。また、バグのレベルとしてはブロッカー(絶対リリースに支障が出るバグ)かどうかなどを問い合わせて重要度を決めて登録するか決める。

バグを可視化する

何をやるべきでどんだけ今後やるべき仕事があるのか。あまりに多いならプロセス改善が必要だし、余裕があるならば今後のイテレーションに関する学習を行うことができる。

また、くりかえし起きてしまうバグに対してどのようにアプローチしていくか。繰り返し発生するバグのステージから引きずり下ろすために分割統治的なアプローチをかけていくべき。 例えば根本原因を見つけるために因果関係図を描くなどをすべき。 これを用いて本来やるべきモジュールなど、何が問題であるのかなど本質を捉えるのに役立たせる。

例えばこれによって、

  • 不要なモジュールのリファクタリング

  • ドキュメント作成に対してコストを取る。

  • (テスターや作り手同士で)お互いの技能を幅広く活用するためにどこぐらいのレベルでコラボレーションしていくかを示していく。

バグの根本原因が必ずしも技術的課題だけではないということをまずはしっかりと念頭においてほしい。ここで述べてるのは自分の技術に依存しない整理して本質を得るために書いていることを再度認識しよう。

みんなもないだろうか。数学の計算をする際に急ぎすぎて字が汚くてケアレスミスをしてしまって間違ってしまったこと。これにプロジェクト開発は似ている。多くの人がそれによって手戻りで失敗してしまう。

プロダクト(方針や開発を進めること)の中で生まれたバグというのはプロセスのバグから生まれる症状である。じゃあプロセスってどうすればもっとより良くしていけるのかを考えていこう。

継続的プロセス改善とバージョン管理

プロセスをデザインするというのはとても難しい。何故ならばプロセスというのはスケーラビティを求められるプロジェクトに包まれるものである。つまり、プロセスもスケールして変化を求められる。

そこでプロセス改善エンジンを導入していく。要は機械学習と同じで評価関数を決めてそれに対して定常偏差を合わせていくといったイメージである。下に一般化して示す。

  • 明確さ
  • プロジェクトがどのような状況なのか誰にでも伝わるように目立つところに誰もがわかる明確なゴールを示す。
  • 一週間目標などを用意して目標を層にするの有効である

  • コミュニケーション

  • チーム内で定期的にプロセス改善ミーティングを開く

  • 統計データ

  • プロセスを改善できたかどうか。できるだけシンプルな方法で動向を追跡する。
  • 例えば、ベロシティ(開発した機能の数)、サイクルタイム(機能一つあたりのかかった週)の二軸で見るなど

この三つである。これを行なっていくことで自己組織化を目指していく。

さて、これを行うに当たってチームの振り返りなどは必須である。 良くある振り返りの方法として、他者を呼んで、外部的視点を見てもらうことをしてもらうこと。他にも色々方法はある。

さて、それを通じて良くある改善内容としては

  • もっとコードをコミットしよう

  • ミーティング方法を変えていく

  • コーディング規約を更新

  • チーム内に新しい役割を増やす。バージョン管理の主幹の人を作ったり、様々なインフラ的な問題が起きた場合主幹となって動くゴールキーパーを作ったり。

これらの振り返りのキーとして、エスカレーションポイントを用意することである。エスカレーションポイントとはチームを超えて影響を与えたる、一緒に解決したりする。たとえ他のことをしているとしても、お互いにプロセスの改善を行うことで視点が養われてシナジー効果が期待できる。

プロセス改善ワークショップ

振り返りの手引きをざっくり示したい。 これを開く意義は、仕事のベクトルを明確に、そして改善することである 当該書籍ではスクラムオブスクラムで示されているが、ここで話される取り組みというのは他にも適用可能だと考える。 以下に示す。

  • 場を設定する
  • テーマを決めてそれに集中する

  • データ収集

  • 以前に実施したワークショップから行なったことを話し合う

  • アイディアを出す

  • データをもとにそれらにどんな意味があるのかを議論する
  • そして辛いポイントを出して、それを今後どうするのかを具体的に示していく

  • 何をすべきか決定していく

  • 振り返りを終了する

    • 次のワークショップまでに誰が何をすべきかを決めてクロージングする

ワークショップではみんながさっさと話せるように心がけるべきである。今思っていることをサッサといってみようと投げるぐらいの勢いで手早くしていくのがいいだろう。 しかしながら目標を見失っていくのではダメで、期待すべき事柄をしっかりと示していくことが大切。

これは運用次第であるが、リーン主義で居続けるなら漠然としたことを許さない可能性もあるが、クリエイティブな、カンバンといったことであるならばブレインストーミングや直感で決めるというのも大切である。ただしいつかは抽象から具体に変えなくてはいけないのを念頭におくべき。

早すぎても難しい

当該書籍では興味深いことを述べている。 以前は変化が少ないことが問題であった。今回は変化が多すぎることが問題だった。 ほどほどというのが必要だと感じる話だ。

こういう時はプロセス改善提案書を書いて一手間加えるワンクッションを入れてもらうことにしている。 理由は提案者に対して簡単に出しすぎないようにする枷であり、何故こうしたいのかということの再認識をすることができるからである。

  • あなたが改善したい問題は何?

  • この変更で誰が影響を受ける?

  • この変更を実施する上でどのように進めるべきなのか?

  • どれくらいのコストがかかってくるものなのか?

  • これを実現するのにどのように分割できるのか想定させることができる(注意すべきはここまではやらせるべき範囲が違う。ここでは問題を分割するのではない。)

迷ったらシンプルな解決策を選ぼう。

因果関係図

根本原因分析を行うのに有用な方法である。 なんでこれが必要かというと、適当に解決するとまた浮き彫りになlって厳しいことになるからである。 具体例を挙げると * 寝室に煙が充満してる * 窓を開けて、また寝る(ダメな例) * 煙の発生源を見つける。おっと危うく火事になるとこだったぜ(良い例)

といった話である。

A3シンキング

リーンシンキングの中核にある教えの一つとして、継続的なプロセス改善を表す「カイゼン」という言葉がある。 トヨタ曰くこの正しい問題解決手法を厳格に運用にしたからであると表現している。これをA3の用紙に描くのでA3シンキングという。

A3シンキングのサンプルやテンプレートはネットにあるので要参照 テンプレートリンク

因果関係図の使い方

基本的な流れはこう。

  • 問題を選んで書き出す。

  • 明らかな損害やそれの弊害を上向き(トップダウン)に突き止めていく

  • つまりこの書き出した問題が理由として扱えるように描く
  • 問題:リリースした奴がバグって死んでる
  • 突き止め:リリースした奴がバグって死んでるー>客がキレる

  • 根本原因を下向き(ボトムアップ)に見つけていく。

  • テスト不足
  • 描く時間が不足してたなどが上の例には当てはめれる

  • 図に現れた循環(基本的に悪循環)を特定して目立つように描く

  • 図を洗練するために上記をイテレートする。

  • 根本をどう解決するか(ミーティングに持ち込んだりする)

これを行なっていく。 もし今回の場合はテスト自動化のトレーニングとかが足りないとかそういうとこに帰着するであろう。

因果関係図の書き方

ぼっちなら線画ツール好きなの使って頑張ってくれ。

複数人8人以下ならホワイトボードや付箋と模造紙で書いて作ろう。

30人以下とかの大規模なら人数を分けて具体的な問題の一つに着目して纏めたりしておく。最後に持ち寄って纏めたりする

定期的にこれをちゃんと認識できるシステム組み込みが必要だったりするのでそこはアナログツールに頼ったりしていくべき。

よくある失敗

  • 幅優先ではなく、深さ優先探索で見ていこう。

  • 問題領域が広すぎる場合がある。分割可能な問題になのではないのかということを見極めよう。

  • 簡略化しすぎない。専門用語ではなくできるだけ一般化した言葉で話すべきである。

  • 具体例に頼ったり、専門用語に頼るのは説明ではない。一般化してる表現で説明してこそ本当の説明なのだ。

  • いらないのが出てくるけどそこは問題ではなく、根本に辿れるかが問題。あくまでブレインストーミングのような形でも問題はない。

  • 個人攻撃をしないように気をつける。しばしば誰かが足を引っ張ってることがるだろう。しかしそれはチームで解決すべき問題だ。出来ないならばそれを解決するプロセスが工数なだけなのだ。そもそとして問題解決ができるのはそのシステムに要因があると仮定できた時のみなのだ。

なぜ因果関係図を使うのか

  • 共通理解を構築するためある。
  • 他の手法としてはストーリーマッピングが挙げれる

  • 問題がどのようにビジネスに影響を与えるか明確にする。

  • 根本原因を見つける

  • 悪循環のループを見つけ、潰す

なぜやるかを意識して問題解決に当たろう。

終章 まとめ

なんでこんなのを纏めたかというと、学生が情報技術を学ぶというの通じて楽しいというのを続けたいならば、それを業務にうまくたたみこむ必要が有るんだぜということが最近よくわかってきたからというのが大きい。

結局最近思うのは実用技術>>>大局的な開発手法ということがやればやるほど僕らは痛感するだろうと思う。現に本質的ではないgitがわからなくて右往左往してみたりまだまだ辛いものはある。精進したいものである。

間違えがあったらそっと教えてください。

参考文献

学生アルバイトが決まった話とそしてコミュニティ

こんばんは。学生アルバイトで学費を稼がないと大学が通えない疑惑が出ている竹です。(初めから重い)



kazukichi.hatenadiary.com
かずきちくんがなんかこの前言及していてたということと、この前そうえば内定したよということは話してもいいと言われたので、高校生学生アルバイプログラマ(?)として僕も思うところがあって喋って見たいと思います。

僕は一発で決まってしまったのでこれから学生アルバイトとして飛び込みたい人向けではありませんが、今後何したいんだろうという話をしたいと思います。

結局どこに決まったの

インフェニットループっていう北海道で有名な会社に決まりました💫
(いやまだ定期考査明けに出社なので内定ってだけなんですけど)←
それで今年度仙台支社ができて私はそこで働くことになりました。ぜひ何もできない若輩者なので各位ご指導の程宜しくお願い申し上げます><
www.infiniteloop.co.jp


どうやらブログや大会出場を評価してくださったようで無事内定が決まりました。ぜひ自分の技術に思うところがあるなら主張してみると案外通るかもしてません。ぜひ仙台支社に仲間が増えたら私も嬉しいです!

社風としてはかなり自由な風通しのいいようで、私はとてもワクワクしています(ダーツボードがあったり生ハムの原木があったりもうなんかフリーダムすぎる笑)🌟
先輩方からいろんな知識や技術を奪えたらいいなぁと思います!!!頑張ります!

さてそれで何が思うことがあったの?

この会社を選んだ一つの決め手は情報技術のコミニュティを大切にしていることでした。
例えば勉強会やLT大会を開くにあって場所を貸してくださったり積極的に勉強会にコミットしたりなど、`仙台ではまだまだですが`北海道ではとても羨ましいぐらいに熱く!!!行なっています。
ですが仙台ではまだまだです。



そこで私は一つ野望があります。




私のいるこの仙台駅を中心に学生コミュニティを組み上げたいという野望です。
これに対しては強い気持ちがあります。主観ですが仙台の学生コミュニティはとても内向的なところが多く感じています。ざっくりとした話表面に出てくるのは東北電子専門学校のあたりのコミュニティと東北大のボンプロさんとかのコミュニティ。ぶっちゃけこの辺ぐらいしか観測できていません。とても素晴らしく学生の身分でこんなにやれるなんて素敵だと思います。ですが同じ身内ばかりで内向的なところがどこかあるのではないのか、それによって狭いところで悩みを話せず同じ共通認識がなくだから仙台はと言われる悪循環を作ってるのではないのかと強く感じます。



ですので私が考えているのはみんな所属の違うコミュニティを作るべきだと考えます。
強いていうなら風通しのいい、大学生でも、高専生でも、高校生でも、中学生でも、初心者でも、ガチプロでも自分のやってることを発信して相互的に学べるシナジーのあるコミュニティを持つべきだと強く主張します。個人単位では技術を持った人が多くいます!


そのためにも立ち上げたいと感じているだけではダメで私よりもいろんな意味でバカな奴が仲間に必要です。ぜひ私と仲良くしてくださったらとても嬉しいです!


また今後これを達成するために定期的に声を大にしてプログラムを書いてるんだぜっていうブログを書こうと思います。ぜひよろしくお願いします(着地点を地味に見失ってしまった)

「2017年にやりたいこと」

今週のお題「2017年にやりたいこと」


takeio.hatenablog.com

 恒例の抱負を書こうと思ったらはてなのお題があったのでこれを利用して少し書きたいと思います。

抱負

  • 勉学面

 数学と英語と物理を人並みにできるようになりたいです。
 数学物理は頑張ればどうにかなる機運があるんですが(自称)
 英語ばかりはどうにもダメです。これは中学からそうなので今年こそは本腰を入れて挫折しないように頑張ります!
 あと進学な()


  • 生活面

 自分で目覚ましで起きよう。たまに起きれない!!辛い!!
 あとご飯のレパートリー増やしたいなー。あと男女ともに友達を増やしたい!僕は友達が少ないだからね。。。(性格に難があるのではという気持ちだなぁ)


  • 趣味

 ダーツでのレーティングをAフラを目指したい。
 あと音ゲーを人並みに目指したいなーと思います。デレステ初見で死んじゃうの辛い。
 それと暇があれば剣道の昇段審査を受けて三段取りたいです✨


 セキュリティについて去年ちょいちょいついばむことしかできてないので本腰を入れて学びたいな。特にPwnとWeb。具体的には入学までにヒープ問題の知識があったり、ブラインドSQLiをどうにかして何も見ないで書けるようになりたい。それとインフラ周りの知識を詰め込みたいな。


 それとコーディング力がないので競技を始めようと思う。基本的なダイクストラやBFSなどはできるけど時間かかるし、DPとかはできないし、ダメダメですね。。。一年をかけてあり本を終わらせたいなと思う。それとatcoderのビギナーズと普通のやつにも毎回参加して解き直すのを癖付けたい。


 そして一番のメインは計算幾何学について知見を深めたいです。特に計算論理についてなど。全然Coqとか使っててもよくわからんパズルやってる気分だし、きちんと、しっかり、身の丈にあった学びをしてステップアップしたい。




・・・・結構あるな。。。どうやって配分したらいいんだろう・・・誰か教えて・・・

  • イベントについて

 LT大会を開きたい!結局高校の時部活が忙しすぎてできなかったので是非頑張る。
 ハッカソンに参加する!時間内にそれなりのコードを叩けるようにするぜ!
 今年こそセキュキャン受かるぞ!雑魚並みの力を見せてやるぜ!()
 また、情報系のアルバイトをしたいと思います。ぜひレベルの高い人たちから学びを得たいです!

締め

今年も至らない点あると思いますがご指導ご鞭撻を賜りますようよろしくお願い申し上げます。

現役高校生が知識ゼロから、倒立振子による玉乗りロボットの機構を作り、それを活かして杖を作ってる話。

 これはStudent Advent Calendar 2016の25日の記事です。
 qiita.com

 竹です。工業高校の三年で、専攻は電気(強電です)。ひょんなことからこんなタイトル通りのことをすることになりました。
 なぜこんなこと書こうかと思ったかというと大学に進学し、高校から離れるにあたり解体することになってしまったからです。
 そして私が未だに完全に作りきれなかったことの研究が出来なくなったからでもあります。
  f:id:taketarou2:20161225010547p:plain:w400
 これは、今後パーツや素材を一から集めれた時の備忘録&これからメカトロニクス倒立振子を始めたい人のために書きました。あと残念ながら訳あってソースコードはお見せできません。すいません。ですがそのうち載せたいと思います。


 ちなみに私自身元々は自称ソフト屋さんでマイコンを取り扱うことや弱電は一度たりともありませんでした。完全に電子工作及びメカトロ初心者で、工具の使い方ひとつでさえわかりませんでした。
 メカトロニクスについて勉強したいなーと思う人は僕みたいなフローを辿るといいかもしれません


 以下に本記事の中身を記していきます。拙い文章ですが気長にお付き合いください。


概要

 大会に出すのに人の役に立つものを作りたいと考えました。
 その中のアイディアとして自立移動する杖があればじじばばが楽になるのではという理由から自立する杖を作りたいと思いました(適当)
 ちなみにこれをやったのは二年生の後半から3年の前でした。

機構を考える

 検索しまくった結果、植え付けられたせいか私の中では立つ=倒立振子だったので倒立振子を採用しました。
f:id:taketarou2:20161223124612p:plain
こんな感じが原案。

倒立振子とは?

 読んだ名の通り「逆立ちする振り子」です。普通の振り子は支持点が重心の上方に存在するのに対し、倒立振子は支持点が重心の下方に存在します。
つまり、箒を手のひらでおっとっと〜と支える感じです。

 倒立振子が倒れないようにするには,常に支持点を重心の真下に位置させる制御技術が必要です。
つまりあれです。箒が倒れそうな方向に走っていくと倒れないアレです。

取り掛かってみる

 しかし結局検索して出てきた知識を使いたくてもどうやればいいんだこれでした。全くわからん。

 というわけで先行研究を調べました。

 どうやら東北学院大学の熊谷教授が研究しているそうです。(地元なのに知らなかった。。。。)
 論文:玉乗りロボットの開発 第一報 ロボットの実装と基本制御
 https://tohoku-gakuin.repo.nii.ac.jp/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=136&item_no=1&attribute_id=22&file_no=1&page_id=34&block_id=86

(それに乗っかるつもりで)これを読み込みました。ちなみにメカトロ知識ゼロです。大学数学もわかりません。ですので並行して自動制御とメカトロについても勉強しました。

 http://www.mech.tohoku-gakuin.ac.jp/rde/contents/sendai/mechatro/archive/RMSeminar_No09_s8.pdf
 などがあるこれまた東北学院大学の熊谷教授の資料が初心者向けで最高です。以下のインデックスから漁ってください。
 Index of /rde/contents/sendai/mechatro/archive

 また
 センサの基本と実用回路 (計測・制御テクノロジーシリーズ)
 Amazon CAPTCHA
など難しい知識が必要な時はこういう本を読んでました。
 基本方針は上で紹介した熊谷教授の公開なされているpdfを読んで、たりなきゃ考えればいいみたいなのが一番よかったと思います。

 正直そんな難しいと考え込んでしまってしまっていたのが失敗なので是非楽に考えましょう。

 ちなみに今玉乗りロボットは僕が始める時にはなかったこんな知識の宝庫みたいなサイトがあるみたいです。羨ましい。。。。
 玉乗りロボット BallIPMini 技術情報

 さてさて。どうすればいいかはなんとなくわかってきましたがそれでもモーターでさえ一つ回したことありません。

 論文中にはステッピングモーターを使っています。まずは回すとこからスタートをしました。

主に使用したもの電子デバイスは
ステッピングモーター
ArduinoMega
MPU6050(6軸センサー(加速度とジャイロ))

を使いました。
また、なめらかオムニホイールと呼ばれる軌跡が一つになる特殊なオムニホイールを使用しました。


ステッピングモーターを回す

 こういう記事ととかみたりどんなのあるのかメーカサイトを見たり。
 ステッピングモーターの基本(前編)〜Arduinoでパーツやセンサーを使ってみよう | Device Plus - デバプラ
 駆動方法を調べたりしました。ぶっちゃけモーター駆動とモーター回路が一番難しくて一番大変です。しっかりと理解しましょう。

 モータードライバは細かい動きをさせるマイクロステップをやりたいが故に市販のを使いました。
 akizukidenshi.com


 これまた僕が回路周りめっちゃ苦労した時にあったら最高だったなというサイトがありました。
この回路設計まんまパクってもいいねというぐらいいいと思います。
 1500円で作る!CNCフライス用ドライバー | 自作工房


 モーターは色々使ったんですがこの辺がすごくおすすめです。
 バイポーラ ステッピングモーター 17PM−K044−AKZ: パーツ一般 秋月電子通商 電子部品 ネット通販


 ちなみに回路周りなのですが紛失しました。。。。ごめんなさい。。。(手書きなのでどこに置いたか。。。)

 さてさてなんとなくモーター周りを理解したところで「倒立振子って結局技術的にはなんぞや」というところと「6軸センサー(角速度と加速度)の制御」、「機体の設計」の足場を固めながら三点に取り掛かります。

倒立振子って結局技術的にはなんぞや

 論文読んでもネット見てもわからん。
 今思うに、初心者には論文で使うような真面目な理論は難しすぎる。でもネットの半日でできるなんちゃらとかはの理論抜きでやりすぎてるのである程度しっかり知りたい人には全くわからない。つまりまぁ慣れろってことなんでしょうけど。

 とりあえず調べていくと平然と
”まず車体へ働く力を物理的に把握することが必要です。運動方程式を立て行います。”
とか言われます。がこれらは現代制御法の場合必要です。

 ですが今回は論文に沿うことにしたので私は今回はPD制御による加速度制御、簡単に言えば古典制御でのアプローチをしました。

古典制御とは

 偏差(修正すべきずれ)に対して比例制御、積分制御、微分制御これらを組み合わせアプローチを行う制御。
イメージとしては、
比例制御:偏差(誤差)に対して比例させて治すアプローチ。
積分制御:偏差(誤差)がどんどん溜まった際にまとめて打ち消すアプローチ。
微分制御:起こりゆく誤差に対して起こすアプローチで、少し偏差(誤差)を打ち消したい時に行うアプローチ。ズレ始めとか強く効く。
 こんな感じです。


 もう少し具体的に説明をします。
 距離、速度、加速度これらの関係は微分積分で変化させることができます。距離を二階微分すると加速度になり。で逆に二重積分すれば距離になります。この時微積分でのΔになる部分は”t:時間”です。つまるところ、微分で成分に対して制御をし、積分でまとめての大味な制御をすることができます。つまり時間のP,I,Dこれらは次元ごとの制御をしてるとも言えます。



 さてここまで理解したところで不思議なことに気がつき、疑問を持つ方もいるかもしれません。なんでPD?PIDじゃないの?という疑問です。普通に考えたらPIDの方が全部に対してやっていて良さげですよね。ですが今回の使用しているモーターはステッピングモーターです。トルクに対する指令ができません。できるのは回転速度に対することのみです。ですので角速度と角加速度のみが制御可能なので、PD制御による加速度制御となります。

具体的な制御について

f:id:taketarou2:20161225003121p:plain
  f:id:taketarou2:20161225010547p:plain
 この図はロボットに用いた,センサによるロボットの姿勢角と車輪の移動量を用いる典型的なPDフィードバックのブロック図です。


 制御部は以下の式で表されます
f:id:taketarou2:20161225003524p:plain
aは操作量で球の外周の加速度であり、θは各軸の方向の傾斜角x,yは車輪の移動量、vは速度である。添え字x,yはそれぞれの軸に関する状態量(距離)であること を示し,K*は実験を行い調整した定数制御ゲインである。またvx(y)aを数値積分することで得られました。

なおこの場合はx,y,vx,vyはワールド座標系ではなく球の回転量です。

 一般的に倒立振子はトルク制御の方が有名ですが、今回はステッピングモータ を利用したというのことから加速度制御を採用したということを前述したと思います。
 今回採用したPDフィードバックは、センサーノイズがダイレクトに操作に関わってくることが一般的に知られています。(よくわからない場合は熊谷教授のPDFを参照)
そこでセンサー対策として簡易的な一次デジタルローパスフィルタを作成し、センサデータをリプル状のノイズを消すようにしました。

f:id:taketarou2:20161225004051p:plain:w300

 パラメータはrのみで、入力を比率rをゲインとする特性を持っている。r=1のときは、ただの素通し、r=0のときは、y[k]=y[k-1]となるつまり、値を維持となります。r=0.1など小さい値にすれば変位値が元の値に寄っていながら増えるというものです。
実際に制御とデジタルローパスフィルタ(LPF)をソースに書き起こしたものが以下のソースです。なおKsという記述はゲインの入れ込んだ配列であり、LPFのゲインは実験的に求めたものです。

thx -= thofx; thy -= thofy; //PD制御
acxt = (Ks[0] * thx ) + //角度 
   (Ks[1] * thvx ) +//角速度 
   (Ks[2] * distance_x - xofs) ) + //目標距離
   (Ks[3] * vx); //速度

acyt = (Ks[0] * thy)+
           (Ks[1] * thvy)+
           (Ks[2] * distance_y - yofs) +
           (Ks[3] * vy );

//ローパスフィルタ //LPF:y=(1-r)y+ru(u入力、y出力、rフィルタ係数r<1)*(2^n/1) #define LPF_f(y,u) y = (LPF_A*u)+((1-LPF_A)*y)
#define LPF_A 0.05
LPF_f(acx, (acxt-acx));
LPF_f(acy, (acyt-acy));
/*積分*/
vx += acx; vy += acy;
distance_x += (vx); distance_y += (vy); MotorSpeedX = (vx);
MotorSpeedY = (vy);

このような形になります。

「6軸センサー(角速度と加速度)の制御」

今回はMPU6050と呼ばれるデバイスからセンサデータを取得し、角度を得ました。
 MPU6050は少しだけ他のデバイスと異なっていて、DMP (Digital Motion Processor) という機能を使うことで、補正済みのデータを簡単に利用できるのが特徴です。一般にジャイロ(角速度センサ)の特性は温度によって変化し、ノイズも多く乗るので適切な処理が必要とされています。
私は角度を得るために今回DMPのバージョンとカルマンフィルタのバージョンを作りました。
DMPのバージョンは多くの記事があるので割愛して、初めてセンサーを触る人のために簡単に分解能についても話し、その後カルマンフィルタについて少し説明したいと思います。

分解能

このMPU6050などセンサーを調べている際にLSBという文字を目にすることがあります。LSBとは最下位のビットではなく(私が勘違いした例なんですけど)制度を論じていて、分解能という意味です.
分解能の概念は以下のサイト曰く、1メートルの物差しに1ミリメートル単位で目盛りつけた時の目盛りが、分解能だそうです。
分解能 - National Instruments

詳しくは以下のサイトなどがよくわかりやすいのかと思うので査収ください。
www.widesnow.com



カルマンフィルタ

カルマンフィルタは逐次ベイズフィルタの一種で、オンラインのフィルターです。簡単にいうと確率論をベースにしたフィルターで、昔のアポロ計画、カーナビ、今回のように角度を求めるなどなどの様々なところで利用されていて、モデルが線形である(または線形近似したもの)ことや,ノイズがガウス分布である必要があります。


基本的には

  • 状態空間表現(動作モデル,観測モデル)
  • 予測ステップ(事前推定値,事前誤差共分散)
  • フィルタリングステップ(カルマンゲイン,事後推定値,事後誤差共分散)


の三つを基本としています。
簡単にざっくりいうと対象のデータにはホワイトノイズが乗っていてその際にはどれがどのノイズかがわかりません。
そこでデータの中間を取り、それに対してその時共分散という値の関係する度合いを用いて、誤差に寄与率加えて、センサーのノイズを薄めるという手法です。



今回の場合、なぜ使うのかというと、角度を求めるのには加速度センサーを使うことで求めることができ、止まっている時は重力加速度のみなので、十分に値が取ることができます。ですがそれだけでは並行に移動し加速(以下並進加速度と呼ぶ)している時に思わぬ値が出てしまいます。そこで、角速度センサーの値を用いて、移動している時は角速度センサーの値を用い、相補的な方策で立てて対抗をすることができます。



しかし、角速度センサーには弱点があり、ドリフトと呼ばれる値のズレが存在します。それに対してのアプローチの方法がこのフィルターなのです。



具体的には

  • ジャイロにドリフトあるが、加速度センサには誤差ないとしたときがある。⇒この時は、誤差の要因は全てジャイロであり加速度センサの値を正解として補正をしたい。
  • ジャイロにドリフトないが、加速度センサには誤差あるとしたとき⇒この時は、誤差の要因は全て加速度センサであり加速度センサの値は無視したい。


という判断をしていかなくてはいけません。



もし詳しく知りたい場合は以下の記事を見てください(私の説明が正解なのか怪しいので)
qiita.com



さて、以下にソースコードを示します。なお、このソースコードは以下のサイトを参考にしました。
TKJ Electronics » A practical approach to Kalman filter and how to implement it



gist.github.com
gist.github.com

このような形になります。ぜひこれはソースコードと参考サイト、上での紹介した記事をぜひ読み込んで理解してください。


機体の設計

結論としては、球乗りの機構を実現するためにオムニホイールをモータ軸につけ、等間隔に3軸を並べそこへ球に乗せる形を作りました。またギアによるバックラッシをなくすためにステッピングモータを使用し、それをダイレクトドライブにしました。それ故移動制御 がパルス分だけの移動なので確実に移動距離を把握できるようになりました。

言葉ではわかりにくいので以下の実際の球乗りの台座を写真a写真bを参照してください。

f:id:taketarou2:20161225002808p:plain:w300
f:id:taketarou2:20161225002816p:plain:w300

ちなみにbは改良を行い捻りを加えサイズの大きいモータでも十分にコンパクトな サイズにできるようにしたものです(論文中と同じですね)

さて。モーターが三つなので少し複雑になりました。そのためにx,yの制御をに変換しなくてはいけませんですので、

まずはX,Y軸の制御を変換するために球駆動のための車輪速度の算出を行いました。

車輪速度の算出

始めに球の中心を原点とする局所座標系を定義します。
(図a)この座標系はロボット本体に固定し,z軸は球の中心とロボットの質量中心を通る鉛直線として,x,y 軸はz軸に垂直に定義します。
f:id:taketarou2:20161224225324p:plain


1.球の角速度ωを得るための車輪の速度を導くために、車輪iと球の接点をPiそ の位置ベクトルをpiとする.球の角速度ω対応する,Piにおける球の周速度viは次式で得られます。
f:id:taketarou2:20161224225435p:plain:w300

2.球の周速度vと車輪の周速度vsの関係を導出する。(図b)最初に右の図の ように速度vを車軸に平行な成分vfと垂直な成分vsに分解する。vfは車輪外周 の樽型の小さいローラの自由な回転によって生成され、vsはモータの回転によ る車輪の周速度である。このvvsは,車輪の駆動方向単位ベクトルsによって対応付けられ、
f:id:taketarou2:20161224230140p:plain:w300
となり、vsの正負は車輪の回転方向を示す.各車輪の位置piと方向siを定めることにより、角速度に対応する車輪速度が求まります。

3.vsの正負は車輪の回転方向を示す。各車輪の位置piと方向siを定めることにより、角速度に対応する車輪速度が求まり、車輪の速度の基本式が
f:id:taketarou2:20161224230256p:plain:w300
とわかります。

4.3の式よりモータ3つの式を求めていく。天頂角φrを球の半径と置く時、位置ベクトルpiは以下となりました。
 f:id:taketarou2:20161225000804p:plain:w300

5.駆動方向siは球の俯瞰図及び車輪の上面図(図a)より
 f:id:taketarou2:20161225000858p:plain:w300
となる。

6.x軸周りに角速度ωxで回転させる時(ω=(ωx,0,0)とする時)サラスの公式を 用いて4.、5.より求めました。
なお単位ベクトルの和は
 f:id:taketarou2:20161225001435p:plain:w300
とします。

 f:id:taketarou2:20161225001307p:plain

7.同様にしてy軸周りに角速度ωyで回転させる時(ω=(0,ωy,0)とする時)を求めました。
 f:id:taketarou2:20161225001654p:plain

 以上よりx方向とy方向へのベクトルを分解する式を得ました。
 これをソースに書き起こす際は以下のようにしました。
 なお以下で√3/2を近似で扱った理由としてはマイコンのスペックを考慮した故です。

  //x>>1は1/2、√3/2~=222/256->√3/2*256=221.7という近似で扱っている 
  Moter_action_1 = -((long)MotorSpeedX ) + 0;//モータ1
  Moter_action_2 = ((long)MotorSpeedX >> 1) - (((long)MotorSpeedY * 222) >> 8;)//モータ2
  Moter_action_3 = ((long)MotorSpeedX >> 1) + (((long)MotorSpeedY * 222) >> 8);//モータ3

これらを用いて加速度的にモーター駆動を行いました。
この時加速度的というのは自分なりでいいのでオレオレ加速度(つまり自然界の尺ではなく相対的なものでもいい)を作りモーターの駆動を行いましょう。
意味がわかりにくいと思いますが、V=V0+atみたいなことになれば良いのです。ここがかなりキモになります。

もしピンとこない場合は以下のソースコードを読んでください。モーター駆動の記述でオレオレ加速度を設定しているのがわかります。
self balancing arduino robot

機体の作成

せっかくなので、初めて旋盤やポール盤、シャーなどを使い、色々試行錯誤した後も含め見てもらいたいと思います。

1番最初は、
   f:id:taketarou2:20161225025750j:plain:w300
このような形で鉄を曲げてそれに小型のステッピングモーターを入れました。
ちなみにアルミの柱、オムニホイールのハブはアルミの廃材より全て手作りです。(ほんと苦労した。。。。)

ですがこれでは若干のトルク不足など応答性が低いということがありました。その後もこれをベースに何度か改良をするのですが、残念ながらうまくいきませんでした。

下の写真は改良の跡で、写真の上には、球を止めるための機構で、キャスターで使うような玉がついています。
改良を行った際にピラミット型にしてその表面三つにモーターを設置できないかとアプローチした後です。
f:id:taketarou2:20161225030847j:plain:w300



その後思い切って下のベースごと変えました。

f:id:taketarou2:20161225030245j:plain:w300

この時ねじりを加える工夫を行い、モーターも通常のステッピングモーターへと換装しました。

ちなみにモーターのブランケットも手作りで、
f:id:taketarou2:20161225030648j:plain:w300
このような台紙をCADで作り、それを元に廃材のアルミ板を切り、曲げて、下のようになりました。
f:id:taketarou2:20161225031214j:plain:w300

中間はまだ安定してないのでスカスカでした笑

f:id:taketarou2:20161225031638j:plain:w300

そして上部には下からモータードライバー、マイコン、センサーと設置しました。
f:id:taketarou2:20161225031903j:plain:w300
f:id:taketarou2:20161225031940j:plain:w300
f:id:taketarou2:20161225032006j:plain:w300

そうして現在の改良を行った形へとなりました。

まとめ

ここまでお付き合いいただき有り難うございました。
肝心のこれって立つのという話ですが、まだ5〜15秒ぐらいしか安定しません。最長で30でした。何が悪いのかわからんので今後の課題です。

それと、実はこのロボットの機構には続きがあって、”ステキなすてっき”という親父ギャグの効いたシステム名をつけてもらい、まさかの友達にロゴを作ってもらうなど、いろいろなことをしました。

f:id:taketarou2:20161225040851p:plain
また、スマホで動かすためにespwroomというWi-Fimoduleを繋いでいて、iOSアプリサイドのお話も実はあるのです。また、espwroomもArduino化していて、温湿度と気圧をはかり、ミスナールの式で体感温度や気圧の変動のスパンで簡単な天気予報をしてくれる機能がついている。といったまだまだ実はネタがありますが、それはぜひまたの機会にとでも思います。もし気になる方がいれば説明書を以前作ったのでぜひ見てください。
Suteki-Na-Stick/SutekiNaStick取扱説明書.pdf at master · Suteki-Na-Stick/Suteki-Na-Stick · GitHub

 これを手伝ってださった先生や、関係している方々、所属してる部活動の人たちに感謝の気持ちを申し上げます。

 また、まだまだ初学者の身分で偉そうなことを言っていて、これにも間違えがあるかもしれません。もしよければ優しくご指導ください。



 最後になりますが、これを通じて何かお互いに拙い文章の中でも学べるものがあれば幸いと感じます。


 Studentアドベントカレンダーお疲れ様でした!!!(結局当日の朝4時までかかったので遅刻(白目))

Haskell(再)入門2回目中編。

こんにちは。竹です。そろそろ"MASAKARI"が飛んできそうで震えてますがやります。怒られることにより圧倒的な成長((

関数の定義方法。

名前::引数 ->返り値

これだけです。忘れないでください。いきなり使います。(突然)
詳しいのは後々説明しますが、とりあえず今日はこれをまず覚えてください。あとから使います。

思い出しフェイズ

[ ]

これ覚えてますか?多相型です。この前出したキーワードでした。
”仲間としては、タプルやEitherなど。
具体的に言うとC++のテンプレートのようないわゆる型ジェネリックと言われているもののように柔軟に扱えれるタイプのことです。”(前回記事よりコピペ)

今回はこれにフォーカス当てて型の続きを進めていきたいと思います。

多相型は型変数

型変数の中でも幾つかを多相型と呼びます。
Haskellにおいて多相型の具体例は

  • リスト
  • タプル
  • Either
  • Mayby

などがあります。
今回はこれらを使って”多相型と型変数”のテーマでいきたいと思います。

リスト

リストはリストです。他の言語と同じで”何かの型のリスト(配列)”という形になります。(しかし飽くまでHaskellは一つの型のみ。)
具体的には文字のリスト

[Char]

整数のリスト

[Interger]

といった感じです。
ちなみにリストの先頭に要素を追加するときは

入れたいもの:[ ]

でできます。

さて「型変数is何?」って思うと思います。ではリストの中の長さを求める関数(突然関数を覚えろといった理由)を考えることにしましょう。
例えば

[Interger]

の長さの関数を考える時

[Interger] -> Int

といった具合になります。
その際、Doubleで使いたい時とか毎回とか型を変えて関数を作るのって大変ですよね。そこで型を変数のように振舞わせれたら楽ですよね?
安心してください。それが型変数です。
ex.

length::[T] -> Int

このように定義できます。
ちなみに型コンストラクタと言ってある型に別のものを足しあわせて別の型を作ることを型コンストラクタといいます。
リストで考えると

[]

で包んでリストになるリスト型の型コンストラクタと理解してください。

タプル

いわゆる無名構造体です。2つの値を組みにした構造です。
Haskellでは

(4,5)

このように表現します。
これも多相です。
ちなみに二つの型の組み合わせを使って作る型を直積型とも言われます。

Either

二つの値のうちどちらかを取るのがEitherです。
Haskellではどっち取るかをLeft,Rightで表現します。


ナニコレ

下書きに入っていた頑張ってた跡がある過去です(めんどくさくなったんで勝手に打ち切り)

esp-wroom-02でラジコン作って遊んだのでまとめとく

この記事はStudent Advent Calendar 2016の24日目の記事です。

qiita.com


f:id:taketarou2:20161223114317p:plain
どうにか事故?自己紹介を回避しました褒めてください。



esp-wroom-02ってみなさん知っていますか?強いWi-Fiモジュールです。
知らないのであればググり倒してください。以上です。



さて、当記事は完全二番煎じで、以下のものと同じようなノリです。がっかりした方ごめんなさい。
あとやっつけです。実質2日分ぐらいで終わります。(私は、モーターの電流特性計り忘れてモタド殺したりしてしまったのでその辺なければ1日ぐらい)

https://www.elekit.co.jp/product/docs/PU-2709Wi-ficar.pdf

ハードウェア構成

RCカー を作る ( バギー工作基本セット + Arduino + Bluetooth + Androidスマートフォン )
ArduinoBluetoothesp-wroom-02で置き換えて、行いました。

また今回は速度を出すためにトルクチューンモーターを採用しました。個人的には普通のモーターでも十分です><(理由は反省点で述べる)
トルクチューン2モーター タミヤ ミニ四駆モーター・電池 15484 :4950344154845:みなと模型 Yahoo!店 - 通販 - Yahoo!ショッピング

これを使うための注意点として電圧がmax3Aなのでそれに対応したモータードライバーを使用してください。
DRV8835使用DCモータードライブキット: 組立キット 秋月電子通商 電子部品 ネット通販
私はDRV8853を採用しました。回路図はめんどくさくて作ってないです><ごめんなさい><

ソフトウェア構成

スマホをコントローラーとしてesp-wroom-02UDPでデータを投げつけたいと思います。
UDPの採用理由としてはOSCアプリ等でも利用するのを前提にしたからです。

今回はiOSのネイティブアプリを作ってUDPで投げつけました。
(時間なくてUIを作り込めませんでしたが。。。)


以下にソースを示します。

ラジコン側(esp-wroom)

gist.github.com
gist.github.com

iOSのやつ

github.com

UDPで投げるためにSwiftSocketというライブラリを使って投げました。
cocoapods.org


これらを組み合わせて使う感じです。

完成!

すいません画像撮り忘れました(学校に置きっぱなしにしてしまった。)
年明けには更新します・・・・

反省点

モーターを欲張ってトルクチューンモーターにしたところ、まさかの定格で書いてる3Aを超えて流れて熱暴走をしてしまいました。。。。(余裕を持ったHブリッチ買えばよかった。。。。)
うまくいかないのでコンデンサをモーターにさしてやったり(セラコン0.1pFぐらいかな?)逆にダイオード差し込んだりという手でどうにしましょう(リプル殺せるので)。



次は竹 (@takemioIO) | Twitterさんですw!(俺やんけ)

進学って大変ですねっていうポエム

進学って大変ですね

 こんにちは。しくじり先生(?)です。進学なんか決まったぽいんで悔しさと浅はかさを込めて自戒のための記事を書きます。ぜひ笑ってください。
(単純に希望大学全部落として、第四希望ぐらいのAOでスルッと地元の私大の新設の情報学科に入ってしまったというオチ)

 あとこれから技術だけで受けようとする人に対してちゃんと考えて欲しいという気持ちで書きます。ぜひ受験生の人は考えてください。

お前ってどこ受けたの?

coinsと農工大電通(夜間)と地元の私大です。

お前ってなんで大学行きたかったの?

高校進学時は大学でも終着駅は就職なら就職でいいだろと思っていました。
ですが元カノに大学行こうぜって誘われ、そのうち自分自身が情報を学び進めて行くうちに、様々なことに興味が出てきて、関数型言語に興味があり、特に型理論(リファーメント型でのコンパイル時の安全性など。。。)を学びたくなったから。

お前にそれだけの頭あったの?

頭ありませんでした。地元の工業高校(偏差値は50前後だと思う)に在学で評定は安定して3.5でした。

お前技術力はあるの??

微妙なところです。高校プロコン優勝でITジュニア賞もらったり、サイバー甲子園で入賞して、2015のSECCON決勝大会に出場したり、iCANという国際大会の予選に出て奨励賞とか、地元のソフトウェアコンテストで一位になってみたり、機械学習が好きで遊んだり、関数型好きで勉強したり人並み以上だとは思ってました。

実際の受験フロー(しくじり部分ともいう)

 僕は三年時にパソコン部(名前は違いますが)で部長をやっていて10月の文化祭が引退でした。ですの本当は受験勉強で忙しい3年の夏も大会のために強制的に平均睡眠時間3時間ぐらいでマイコンをいじりプログラムを書いていました。そこで私は一般を早々に諦めて技術力だけでの勝負に切り替えました(つまり推薦やAOに切り替えた)
しかしそれでも大学に出願するには大変時間がありませんでした。(どれくらい時間がなかったかというと大学に間に合うのにのせなきゃいけない郵便配達の集荷の締め切り1時間前までやってたり、台風なのに高校まで行って調査書を取りに行くなど。。。。)



 さて微妙な出来の書類をまずはcoinsへ出しました。このとき、色んな人や先生、フォロワーさんに見てもらったりして大丈夫でしょと言われ自信満々でした。
 しかし落ちました。辛い。今思うに評定なのかなとか思います。
 さて農工にも出しました。実際に受かった人に見てもらっておそらく一次は確実に通るって言われたりしてたので、この時も自信満々でしたが。落ちました。
 



 さぁ困りました。次どうしよう。。。迷走します。センターとりあえず払いこむとか他の推薦やAOを探すとか色々手当たり次第探していました。



 迷走を経て次の進路を決めました。電通大の夜間を受けることにしました。
 理由は単純でお金の面を心配せず行え、やりたい研究室もあり、かつMMAに入れるから。
さてそれに向けて頑張りました。ちなみに夜間と言いながらも入試問題は一般の電通大の推薦入試と同一の問題です。ですので私の高校では開講していない基礎なしの物理や化学、数学Bなどを自力でやりました(必死)

 しかし、努力叶わず爆死しました。それは今年の問題がレベルが過去三年分と比べてえらく上がっていたということ。例えば電磁気が今までは電気回路だったのがいきなりコンデンサの静電容量がどれくらい貯めれるとかクーロンの法則が出たりなど、また僕がそれに対して絶対これだろというふうにある程度ヤマを張っていたこと。ちなみにヤマは全て外した記憶があります。本当にしくじりました。まさか融合問題が出るとは。。。。(頭抱え)


 その後とりあえず浪人はみんなに止められたので、やめようという方針を立て始めた失意の中、顧問の先生の助けを借り、第四希望の大学に出願したのがポーンと受かりました。(おそらくそれは面接に出した賞状で殴った感じだと思う。)
まぁそんなもんだろうみたいな感じ。

まとめと反省と僕みたいに失敗して欲しくないためのポエム

 受験をなめてた。正直夏休み明けの時点で高校選択間違えたなと、さえ思った。
中学の時にもう少し頑張って高専狙うとかできれば。。。とか評定がもう少し高ければ。。。とか就職であれば楽だったのに誘われてたとこに行けば。。。とか自分より実績がない部活の同級生が公立に受かるのを見て公立なら受かったのかな。。。とかIFばかり考えてしまう。本当に後悔後先立たずとはこのことなんだろうなと思う。
 

 だけどもこの経験は後悔してはいない。自分自身の足りないところや至らないところ。言葉ばかりでとり作ってきたところ。本当に色んなところに気がついた。精進が足りませんでした。過程があれば評価されると思っていた。本当に甘かった。


もしこの記事を読んでくれた中高生(特に工業高校の人)がいるならしくじった人並みのアドバイスをします。

高校生へ。
 一度将来をしっかりと考えましょう。このためになら1~2日潰しても構いません。ネットサーフィンしまくるなり、本屋さんに行くなりして何やりたいのか考えましょう。いつでも遅くありません。できるなら一年生の時からです。
 そしてもし就職なら評定を一生懸命上げましょう。
 進学ならば、1年生は今すぐ河合塾に行くなりスタディサプリ(科目の足りない学校にいるならなおさら。)を取るなりしましょう。最低限進学就職どっちに転んでもできるように知識をつけましょう。一年生なら評定もあげやすいですし一年生の科目だけを課す試験が就職にも進学にも多いです。
2年ならまずは模試を受けるべきだと思います。自分の実力によっては最悪頑張っても難しい場合があります。全統模試など全国クラスのにしましょう。自分が低く出た方が危機感が湧きます。
3年次の人で早い段階の入試を受ける場合で部活が忙しいなら部活をやめましょう。それくらい覚悟が必要だと思います。

中学生へ。
 もし工業高校に行きたいとか思う人がいたとしてもやめておくべきだと思う。少なくても大学に行くのがお金的に無理とか家を継ぐとかない限り。もしくはそこの高校でしかできないとかない限り。初め進学なんてしねぇよと思っても、専門分野を深く学ぶうちにやっぱ大学進学したいと思うようになると思います。特に大学数学などが必要だったり化学が好きだったりとかだと特にその可能性が高くなります。(正直工業高校の化学は実用よりで大学の範囲までは言わないので)
それでも専門分野を学びたいと思うならば高専か理数科を目指すべきです。高専であれば3年次編入があり、それは高専生向けである場合多く、進学時学んでないなどでのカリキュラムで困ることが少ないと思います。理数科であれば特に物理系の部活や化学系の部活などで工業高校でやれる部分と同じ理論基礎に対して取り組めます。また、もしそのような取り組みをした場合、理数科目でのバフになり得ることが多く点数が取りやすくなり、さらにはその学校が科学オリンピックなどに力を入れてる場合が多いです。

高いレベルの高校に行く意味はあります。先生の質も変わります。是非頑張ってください。


これらは人によってはそんなことないみたいな顔するかもですけど少なくても僕がすればよかったなと感じたことなので書きました。


 僕はこれから大学生活をするわけなんですが足りない科目を自力で埋めなきゃいけません。辛いです。ですが一つやろうとしていることで大学での編入を目指そうと思っています。そのためには一度高専に行くとかしなきゃいけないんですけど。。。自分のやりたいことをするために賭けてみたいと考えています。


以上ポエムでした。

何かあれば@takemioIOにメンションをください