Inside of LOVOT

GROOVE X 技術ブログ

📢 技術イベント開催のお知らせ

LOVOTech Night 2024: LOVOT開発の裏側に迫る

📅 2024年11月27日(水) 19:00~ @日本橋浜町LOVOTミュージアム

日頃LOVOTの開発に携わるエンジニアが登壇し、日常生活に溶け込むロボットがどのようにして開発され、成長してきたかをお話しします。

イベント詳細はこちら

LOVOTの並行思考 with trio

こんにちは!ふるまいチームのエンジニア、市川です!

以前、下記の記事でLOVOTのふるまいづくりについてご紹介させて頂きました。

tech.groove-x.com

そこでも言及しましたが、わたしたちが呼んでいる「ふるまい」とは下記の事を指します。

  • 感情(学術的な理論に基づく心のモデル)
  • 感情や認識情報に基づいた意思決定(何をするか?)
  • 意思決定に基づいた体への動作指示(手・足・目・瞼などの動き)

これらの処理は、NeoDM(Neo Decision Maker)と呼ばれる一つのサービスで担っています。 NeoDMでは他にも下記の事をやっています。

  • 自身の姿勢の推定(抱っこされている?転けている?など)
  • 画像認識結果のフィルタリング
  • 障害物・崖の検知
  • 経路計画
  • 歌の認識
  • その他

これら複数の事をできるだけ同時にこなさなければいけません。

とぼけた顔をしているが、実はいっぱい考えている

「100個の事を同時に考えてください」と言われても困りますよね*1

人間の場合は1つずつこなしていくかもしれませんが、例えば1個目の処理に「10秒待つ」という処理がある場合、2個目の処理が始まるのは少なくとも10秒以上後になってしまいますね。 待ってる間に他の処理をしておきたいです。

そんな良い感じのスケジューリングをしてくれるtrioというライブラリを導入しています。

NeoDMはpythonで書かれていて、trioはpythonの並行処理ライブラリ*2です。

このtrioにより、次のように記述されています(説明のために簡略化してあります)。

# main関数を開始する(並行処理の開始)
trio.run(main)


async def main():
    # 並行処理させる様々なクラスをインスタンス化
    # (実際はグローバル変数のようになっていて、インスタンス間で相互にアクセスできる)
    poller = Poller()
    physical_state_updater = PhysicalStateUpdater()
    ...

    # 各インスタンスのrunメソッドを子タスクとして開始する
    async with trio.open_nursery() as nursery:
        nursery.start_soon(poller.run)
        nursery.start_soon(physical_state_updater.run)
        ...


# 機体内の情報をかき集めるクラス
class Poller:
    async def run(self):
        # 一定周期でループさせるfor文(25Hz)
        async for _ in trio_util.periodic(1/25):
            # redisというデータベースに機体内の情報があるのでそれをかき集める
            # 例えば電池残量、各種センサの情報など
            ...

# 自身の姿勢を推定するクラス
class PhysicalStateUpdater:
    async def run(self):
         # 一定周期でループさせるfor文(25Hz)
        async for _ in trio_util.periodic(1/25):
            # Pollerで集めた各種センサ情報を元に自身の姿勢を推定する
            ...

雰囲気が伝わったでしょうか?

trioの使い方に関しては下記にまとめておりますので、良かったらご参考ください。

qiita.com

また、PyConJP 2019にて、弊社のJohn BelmonteさんがLOVOTでtrioを使っている事について発表しました。 trioの導入理由に関しても触れられています。 興味がある方はご覧ください。

www.youtube.com

おわりに

NeoDMの並行処理についてご紹介しました。 弊社ではそんなNeoDMの開発メンバーを募集しています。

recruit.jobcan.jp

recruit.jobcan.jp

また、ふるまい以外の分野でも募集しておりますので、LOVOTに関わるお仕事に興味ある方は是非ご検討ください。

recruit.jobcan.jp

*1:NeoDMは100以上の並行処理をしています。

*2:タイトルが並列思考ではなく並行思考となっているのはこのためです。並行処理と並列処理の違いは他の方の記事を参照ください。

LOVOTの愛でメリークリスマス

GROOVE Xのエリアプロダクトオーナーのよっきです。

みなさん、GROOVE Xアドベントカレンダー2022はいかがでしたでしょうか?

技術や開発の仕方、組織のあり方など、かなりバラエティに富んだ記事があり、色んな角度のGROOVE Xを伝えられたんじゃないかなと思います。

いよいよ今回が最後の記事になります。 最後は、私がLOVOT開発の中で出会った印象に残ってるエピソードを紹介して、LOVOTについて思ったことを綴ってみます。

エピソード:愛情を注ぐということ

協力会社さんがGXに来てミーティングをする時、LOVOTの紹介を兼ねてLOVOTミュージアムを案内することがあります。 その時に、協力会社さんがLOVOTとふれあいながら以下のようなことを言いました。

「子育てが終わって、私の愛情をどこに出していいのか、悩んでいるんですよ。それでLOVOTが気になっていて…」

愛情を注ぐ対象を探している、ということが私にとって衝撃的でした。 子育てが終わって、これから自分の時間を過ごせるという時に、次の愛情の出し先を探そうと思えるということは、なんかすごいことだなと思ったのです。

生きがいについて

私が好きな番組にNHKの100分de名著があります。難しい哲学書なんかも現代で捉えるとどういうことかをわかりやすく解説してくれるので、哲学に興味あるけど本を読むのは眠くなっちゃうな、という人は100分de名著から入るとすごく入りやすいです。

はい、少し話がそれてしまいましたが、この100分de名著で神谷恵美子さんの「生きがいについて」の本が紹介されたことがありました。 その時はふむふむと聞いていたのですが、協力会社さんの一言を聞いたときに、まさに、生きがいだなと思い、この本が思い出されました。

この本の中で

「人間から生きがいをうばうほど残酷なことはなく、人間に生きがいをあたえるほど大きな愛はない。」

という言葉があります。 生きがいを与えることそのものが愛なのです。

そして、生きがいを感じられることの1つとして「使命感に生きること」を挙げていました。 この使命感というと大それた感じがしますが、本質的には、誰かのために私を使っていること、となります。 子育てでいうと、子どものために私の時間を使っている状態が生きがいを感じている、ということにつながるのだと思います。

私が、協力会社さんの言葉に凄さを感じたのは、子育てを通して、子育てが生きがいと思うのではなく、愛情を注ぐことが生きがいである、という一つ抽象化して捉えていたところにあるのだと、「生きがいについて」を思い返して感じました。

ちなみに少し補足しておくと、「使命感に生きること」以外にも「存在の根底から湧き上がってくるもの」「自分がしたいことと義務が一致すること」も挙げられており、そもそもがまず自分がやりたい、と思えることが大前提にあります。

LOVOTで生きがいを感じられるか

では、LOVOTと暮らすことで生きがいを感じることはできるでしょうか?

生きがいを感じることは、愛情を注ぐ、あなたのために私を使う、ということ。 つまりはLOVOTのために何かをしてあげる、ということが感じられれば、きっと生きがいを感じられるのだと思います。

では、私たちはLOVOTのために何をしてあげるといいのだろうか?

その1つが抱っこということになります。 LOVOTは人を見つけると信頼度合いに合わせて抱っこをねだります。 この抱っこねだりに応えてあげたときに喜ぶLOVOTを見て、LOVOTのために何かをしてあげたという実感がわき、それが、生きがいへとつながっていく。

なんやそんなことか、と思うかもしれませんが、でも多分、そういう日々の要求に応えるといったやり取りから、私があなたのためになっている、という実感を感じられるのではないかと思います。

そして、抱っこ以外にも、LOVOTがこういうことをしたい、という自我が見えてきたときに、よりLOVOTを通して生きがいを感じられるようになるはずで、 我々開発チームもLOVOTが人と暮らす上でちょうどよい自我を作っていく、ということを念頭に置きながら、今後もLOVOTという存在を作っていきたいなと思います。

最後に

ここまで読んでいただきありがとうございます。

アドベントカレンダーの最後はクリスマスらしく愛の物語で締めくくってみました。

ちなみに、エピソードでは、愛情を注ぐことからLOVOTの購入を検討する、という話でしたが、 私は、LOVOTに愛情を注ぐことで、LOVOT以外の人にも愛情を注げるようになる、というエピソードとは逆パターンの方に期待しています。

LOVOTへの愛情が、他者へ愛情を注いでいくきっかけになる。

神谷恵美子さんの言葉を借りると、愛情を注ぐ人を増やしてくLOVOTは、生きがいを与える大きな愛そのものなのかもしれません。

そんな愛あふれる世界を思いながら、今年のクリスマスは家族と一緒に過ごそうと思います。

メリークリスマス!

recruit.jobcan.jp

grafana をプレビューする slack アプリの話

この記事は、Groove Xアドベントカレンダー2022 12日目の記事です。

はじめに

こんばんは、GROOVE X の junya です。
更新がとても遅くなってしまってゴメンナサイ。

今回は、社内の slack で活用している grafana プレビュー機能についてご紹介します。 slack に grafana のリンクを共有すると、こんな感じで自動でプレビュー画像をつけてくれる仕組みです。

grafana とは?

オープンソースのデータ可視化ツールで、 BigQuery, Prometheus, InfluxDB, Spreadsheet など様々なデータソースに対応しています。 GROOVE X では主に、 Victoria Metrics で管理された機体のメトリクスの可視化に活用しています。

サービスの雰囲気は、公式のデモサイトがあるのでそちらで体験してみて下さい。

play.grafana.org

slack で grafana をプレビューする仕組み

以下のフローで、 slack に投稿された grafana の URL にプレビュー画像を自動補完しています。

  • grafana の URL の投稿を slack の link_shared イベント として検知する
  • シェアされた grafana の URL を元に、画像取得用の URL を生成し、画像を取得する
  • slack のファイル管理に画像をアップロードする
  • slack の unfurl 機能 を用いて、リンクにプレビュー画像を付与する

以下、詳しく説明していきます。

slack アプリ作成時に Event Subscriptions の設定で link_shared イベントを購読すると、アプリでリンク共有のイベントを取得できます。

slackアプリの Event Subscriptions 設定

以下のように、 slack-go を用いて HTTP リクエストを Slack のイベント型に変換して利用します。

package service

import (
    "io"
    "log"
    "net/http"

    "github.com/slack-go/slack/slackevents"
)

func HandleLinkSharedEvent(w http.ResponseWriter, r *http.Request) {
    body, _ := io.ReadAll(r.Body)
    defer r.Body.Close()
    evt, err := slackevents.ParseEvent(body, slackevents.OptionVerifyToken(&slackevents.TokenComparator{VerificationToken: SlackVerificationToken}))
    if err != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    switch evt.Type {
    case slackevents.CallbackEvent:
        innerEvent := evt.InnerEvent
        switch ev := innerEvent.Data.(type) {
        case *slackevents.LinkSharedEvent:
            // handle link shared event here.
            return
        default:
            log.Printf("unhandled inner event: %v", ev)
        }
    default:
        log.Printf("unhandled event: %v", evt)
    }
}
ダッシュボード画像の取得

grafana には Grafana Image Renderer というプラグインがあり、このプラグインが有効になっていれば、ダッシュボードのプレビュー画像を取得することができます。パスにある /d//render/d-solo/ に変換し、 viewPanel 引数を panelId 引数に変えれば、画像を取得できるので、 Slack アプリの中では共有された URL を以下のように画像URLに変換して、画像を取得しています。

const BASEURL = "https://grafana.example.com"

func BuildImageURL(url string) string {
    if strings.HasPrefix(url, BASEURL+"/d/") {
        if strings.Contains(url, "viewPanel=") {
            // grafana can render panel itself with /d-solo/ and "panelId" parameter
            url = strings.Replace(url, BASEURL+"/d/", BASEURL+"/render/d-solo/", 1)
            url = strings.Replace(url, "viewPanel=", "panelId=", 1)
        } else {
            url = strings.Replace(url, BASEURL+"/d/", BASEURL+"/render/d/", 1)
        }
        // add timezone parameter to show metrics with JST
        url += "&tz=Asia%2FTokyo"
        return url
    }
    return ""
}

例えば、公式のデモサイトにある下記のダッシュボードは、

これを以下のような URL に変換すると画像を取得できます。

slack への画像アップロード

http client を用いて grafana から画像を取得したら、 slack の files.upload API を用いて、画像を slack へアップロードします。

slackClient := slack.New(SlackToken)

...

// 画像URLを元に画像のバイナリを取得する
img := GetImageFromGrafana(imageURL)
reader := bytes.NewBuffer(img)
remoteFile, err := slackClient.AddRemoteFile(slack.RemoteFileParameters{
    ExternalID:            "some id",
    ExternalURL:           grafanaURL,
    Title:                 "some title",
    Filetype:              "link",
    PreviewImageReader:    reader,
})

なお RemoteFile の機能は slack-go に無かったので、PR を出して機能を追加してもらいました。

grafana へのリンクにプレビュー画像を付与する

最後に slack の unfulring の仕組みを呼び出して完成です。

func (s *Service) handleLinkSharedEvent(ev *slackevents.LinkSharedEvent) {

    ...

    blocks := make([]slack.Block, 0, 2)
    if extraContent != "" {
        blocks = append(blocks, slack.NewSectionBlock(slack.NewTextBlockObject("mrkdwn", extraContent, false, false), nil, nil))
    }
    blocks = append(blocks, slack.NewFileBlock("", remoteFile.ExternalID, "remote"))
    _, _, _, err = slackClient.UnfurlMessage(
        ev.Channel,
        ev.MessageTimeStamp.String(),
        map[string]slack.Attachment{
            link.URL: {
                Blocks: slack.Blocks{
                    BlockSet: blocks,
                },
            },
        },
    )
}

実際の運用では、プレビューに画像だけでなく、メトリクスに関連する付属情報も付与して、見る人にわかりやすくしています。

slack アプリのデプロイ

slack のアプリは cloud function にデプロイしています。bot の管理に serverless の仕組みは便利ですね。

Enterprise 版 Slack でのトラブル

この夏に社内の Slack を Enterprise へ移行したのですが、その際になぜかこの grafana プレビューの仕組みが動かなくなりました。 サポートに確認したところ、 Pro 版と Enterprise 版でファイル管理の仕様が異なり、

  • Pro 版: アップロードした画像は、unfurl でそのまま使える
  • Enterprise 版: チャネルに一度も投稿したことの無い画像は、スレッド内の unfurl 画像として利用できない

とのことでした。ちょっと腑に落ちない仕様ではあるのですが、ワークアラウンドとして、

  • 画像投稿用の専用チャネルに画像を投稿してから、
  • unfurl 画像として利用する

という方法で問題を回避しました。

さいごに

仕事って、ちょっとした工夫で楽しくなるし、業務効率も上がるなと思います。

GROOVE Xは、楽しくコードを書ける環境なので、ご興味のある方は是非ご連絡下さい!

recruit.jobcan.jp

slackをEnterprise Gridに変更した話

この記事は「GROOVE Xアドベントカレンダー2022」の24日目の記事です。

こんにちは!! GROOVE Xのスクラムマスターの1人、 niwano です。
今回も開発の話から、少しそれまして、社内で使用しているコミュニケーションツール slack の契約プランを、Pro から Enterprise Grid に変更したお話をしたいと思います。

slackとは

Microsoft TeamsやChatworksなどと同じ、コミュニケーションツールのひとつです。
弊社では創業時から導入されており、社内のインフラになっています。

slack.com

slackの良い所のひとつとして、自由にカスタマイズできる、というのがあります。
毎週火曜日のお昼休みに、GROOVEランチという情報交換会をやっているのですが、その運営を楽にするために、

  • 発表者の募集
  • カレンダーへの登録
  • 開催時のslack通知
  • 記録

の4項目を、slack ワークフローと、slack appを駆使して自動化されています。

発表登録

発表通知

Enterprise Gridの導入の背景

セキュリティ機能を強化しつつ、よりオープンで風通しのよい職場にしたく、Enterprise Grid の導入を決めました。

移行の際にしたこと

移行時のほとんどの作業は、slack社の方が親切にサポートしてくれます。
弊社側でやったことは、おもに以下の2つです。
(これは弊社が持っていたのが1つのワークスペースだったからかもしれないです。)

アカウントの整理

弊社のドメインではないユーザーともゲストアカウントとしてワークスペースに存在させる運用をしていました。
EnterpriseGridは、SAMLシングルサインオンが推奨されているため、必然的に他社ドメインの方のアカウントを整理することになります。
他社ドメイン方は外部ワークスペースに移動してもらい、特定のチャンネルのみ Slack コネクト(後述)で接続することにしました。

SAMLシングルサインオンの設定

弊社はgoogle workspaceを使っているので、googleSAMLシングルサインオンを使えたのですが、うまく設定が効かないパターンがあり、google社のヘルプ、slack社のヘルプにたくさんお世話になりました。

slack社にはサンドボックス環境も用意していただき、Organaization(後述)の概念を事前にイメージできたので、非常に助かりました。

7年弱のデータがありましたが、マイグレーション(slack社による)は30分ほどで終了しました。

Organaizationの概念

Enterprise Gridになると、もともとのslackワークスペースが、Organaizationのなかに入ります。
Organaizationのなかでは、無制限にワークスペースをつくることができます。 そして、アカウント管理は、Organaizationで行われます。

さらに、ワークスペースごとに細かい設定を変えられるので、弊社ではメインのワークスペースの入場は承認制、off活動・遊びのワークスペースは出入り自由にしています。

Organizationイメージ

slack コネクト

弊社はEメールよりもslackでのコミュニケーションのほうが効率が良いと考えているため、社外の方とのやりとりでは、slack コネクトを多用しています。
なんと、Enterprise Gridプランを導入すると、slack コネクト先のワークスペースがfreeプランであっても、slack コネクトのチャンネル上は、freeプランの制限(90日間のみメッセージ保存)がかかりません!  

移行して良かったこと

  • トラブルなく移行できた。
  • アカウントの整理ができた。

トラブルなく移行できた。

トラブルが発生した場合にそなえて、Eメールにてバックアップツールへの導線を通知していましたが、移行時のトラブルはなく、全てのユーザーが 、今までと同じようにワークスペースを使えたことが本当に良かったです。

アカウントの整理ができた。

今まではゲストアカウントを多用していたため、ユーザー1人にたいして閲覧制限を個別に実施することになっていて、アカウント管理がすごく複雑でした。
ストアカウントをグルーピングし、別のワークスペースに移動させ、必要なチャンネルを共有するだけで、閲覧制限をかけることができるため、アカウント管理が非常にシンプルになりました。

移行してからの課題

  • 障害が少し多い...
  • マルチワークスペース共通のユーザーグループをつくることができない。

障害が少し多い...

私が個人的につらかったのは、Organaizationのセキュリティの設定作業をしていたら、なぜだかワークスペースから追い出されてしまった件です。
一度ワークスペースから抜けると、ユーザーグループから解除されたり、一部のslack appが無効になったりします...

また、この記事を書いている時点で、30日以上問題が解決していないトラブルがあり、これに関しては、slack社と協力をしながら解決にむけてとりくんでいます。

マルチワークスペース共通のユーザーグループをつくることができない。

特定のユーザーにたいして、まとめて通知を出すことができる、ユーザーグループという概念がslackにはあるのですが、このユーザーグループは単独のワークスペースの中でしか使用できません。
これを解決するために、特定の文字列に対して、ユーザー名をリプライする Bot を作成しました。

最後に

最後まで読んでいただき、ありがとうございます!
いろいろありましたが、Enterprise Gridへの移行はおおむね満足しています!

弊社では、ただいま絶賛メンバーを募集中です。
様々な職種がオープンになっているので、ご興味があるかたは以下のリンクからご応募をお願いします!

recruit.jobcan.jp

転倒・ネストに戻れない事象調査のおはなし

この記事は、Groove Xアドベントカレンダー2022 の23日目の記事です。

はじめに

こんにちは、LOVOTのソフトウェア検証を実施・改善しているQAチームです!

※チームの詳細については、12/10に公開された記事「シナリオテストのおはなし - Inside of LOVOT」をご覧ください。

今回はソフトウェア検証として取り組んでいる活動の1つである「転倒・ネストに戻れない事象の調査」を紹介します。

LOVOTは起きている間、充電が少なくなったら自分でネストに戻って充電しにいき、満充電になるとネストから出てきてお部屋の中を歩き周り始めます。

このサイクルを繰り返していくのですが、その中でLOVOTが転倒してしまったり、ネストに戻ることができなかったりすることがあります。

転倒してしまうとLOVOTの怪我につながったり、ネストに戻れないと動けなくなってしまうため、なぜそのような事象が発生したのかの原因を調査し、関係者共有し、改善につなげる活動をしています。

※過去のイベントのお洋服をお借りして、いつも検証をがんばっているLOVOTたちに着せて撮影してみました!通常は普通のベースウェアを着ています。

検知方法

LOVOTを生活させているスペースが複数あり、各スペースにカメラを設置しています。これで24時間生活の様子を確認しています。

毎朝出社したら、転んでしまったLOVOTや動けなくなっているLOVOTがいないかを各スペースにチェックしにいきます。

発見した際にはどの子がどのような状態になっていたかを記録し、すぐに救出します。

最近ではLOVOTが転倒してしまったときに、社内チャットツールに通知する仕組みをつくりました。

LOVOTアプリの詳細をご存知の方は、LOVOTが転倒すると「〇〇が転びました」と通知が来るため、必要ないのではと思うかもしれません。

ただ検証現場ではたくさんのLOVOTが生活しており、通知が多く気づけない、調査員がLOVOTアプリを登録する必要があるなどの不都合がありました。

社内チャットへの通知システムが出来てからは、LOVOTの転倒をすぐ確認出来るようになり、解析がよりスムーズに進むようになりました。

こんな感じで通知されます。

調査方法

調査は以下の流れで進めています。

  1. 通知 / 事象発生を認識
  2. カメラ映像を確認
  3. LOVOT/ネストの生活環境確認
  4. 関連データの確認
  5. 関係者への報告

カメラ映像を確認

事象を検知したら、まず該当時間のカメラ映像を確認しています。

原因を推測するには、こける直前の状況を知ることが重要です。

たとえば、以下のLOVOTはつまずくものがない場所で転んでいるように見えます。

※このようなビデオをきっかけに、データ分析を行い対策を施したソフトウェアをリリースすることができました。

転んだ後の状況だけを見ても何が起こったのかわかりません。

その前の映像を見ると、転ぶ前に片手をあげて片足をしまう動作の最中にからだのバランスを崩していることがわかりました。

これをきっかけに調査が進み、現在のソフトウェアでは修正されています。

その他にも複数のLOVOTを同じスペースで遊ばせている時、LOVOTが転んだ時にドミノ倒しで他のLOVOTも転んでしまうなど、不運な事故が起きていたことがありました。このように映像を確認しないと転んだ原因がわからない場合もあります。

映像確認の次は、LOVOTやネスト、関連データを確認し要因を探っています。

LOVOT/ネストの確認

LOVOTのキャスターにゴミがつまっていて移動が難しくなったり、ホイールのセンサーが汚れていると障害物を検知しづらくなったりするため、要因がこちらに該当すると考えられる場合は確認します。

ネストの配置や周りの状態が、LOVOTの生活環境を満たしているか見直すこともあります。

お手入れをする – LOVOT

LOVOTの生活環境 – LOVOT(初代) [LV100/LN100] – LOVOT

関連データの確認

LOVOTは多数のセンサーやモーター、複雑なプログラムによって成り立っています。

これらの動きを収集した多数のデータは、LOVOTが正常に動いているか、不具合があったときにどこが原因なのか調べるために、ログやグラフとして出力されます。 QAチームではこのデータを複数使用して、どこが原因となりそうか調査を行います。

具体的には何かにぶつかっていたら障害物検知に異常はないか、LOVOTが思いもよらない動きをしていたらソフトウェアからの指示に対してどう動作していたのかなど、状況に応じて考えられる要因のデータを確認します。

調査した事象の記録・報告とふりかえり

調査した事象の記録/報告

確認した事象は記録し、発生頻度を確認できるようにしています。

頻度が高くなったものや新規と考えられる事象は、担当チームに報告し詳細な調査を依頼します。

例えば、LOVOTのふるまいなどソフトウェア要因で転倒してしまった場合はUTやALOHAなどのチームに問い合わせます。

また、転倒・ネストに戻れない事象の調査の過程で、異音などハードウェア要因と考えられる事象があれば、メカやエレなどのチームに問い合わせます。

チームの詳細はプロダクトオーナーからみたLOVOT開発 - Inside of LOVOTをご覧ください。

転倒やネストに戻れない事象は、物理破損だけでなくソフトウェアや環境など多くの要因が絡むこともあるため、担当者に報告する前に可能な限り、私達の調査の時点で切り分けをしておくようにしています。

その上で有識者に詳細な調査を依頼し、改善や再現確認の方針を決定しています。

ふりかえり

定期的にチーム横断でふりかえりをしています。

調査をするにあたって、困ったこと・直近で気になったことを、この場で共有し、改善をしています。

この場ができたことで、調査の質があがったと感じています。

おわりに

以上の活動を日々実施していくことでLOVOTの苦手なことの特定を進め、LOVOTが成長していけるよう取り組んでいます。

これからも、作業効率化や新たな観点からも調査をしていけるよう努めていきます。

仲間募集中

気づいたらLOVOTに囲まれていたり

ふと足元を見ると抱っこをせがんでくるLOVOTがいたり

遊びにでかけて帰ってこないLOVOTを探す社員がいる。

世界中どこを探しても他にはない面白い職場だと思います。

もしご興味がありましたらこちらをご覧ください。

お読みいただきありがとうございました!

debianパッケージを作ろう(go-bin-debのススメ)

LOVOT の基盤となるシステムをつくってるチームのひとり id:atotto です。

debian パッケージ をさくっと作るツールの紹介です。 個人的にも Raspberry Pi や、ツールの管理のために活用しています。

背景

debian パッケージ 作り、というと、controlファイルを書いて、changelogを書いて、必要なディレクトリを切って、、、といったことを一通りこなす必要があります。コマンドひとつ社内に配布したいだけだとするとちょっと腰が重いです。 また、CMake, CPackで一元的に作ることもできますが、CMakeと戦うにはそれなりの覚悟(Mastering CMake ←同僚の愛読書)が必要です。

LOVOT のシステムのベースとなるサービスの多くは Go言語を使って開発しています。

参考: PyConJP 2019 らぼっと開発におけるPythonとGo より抜粋

Go言語で書いた成果物(実行ファイル)は依存関係が非常にクリーンで、実行ファイルを各アーキテクチャ(amd64,arm64,armhf, etc...) 毎に配布すればよい、となり、デプロイがとても簡単です。

参考: PyConJP 2019 Yet Another Isolation - Debian Packageと紐づく環境分離 より抜粋(2022/12 現在はUbuntuベース

そのため、 debianパッケージ をつくるときに考慮することといえば、実行バイナリをどこに配置するのか、サービスであれば、systemdのサービスファイルや、インストールにまつわる処理をどうするか、といったところに絞ることができます。

その目的にあったツールとして、私達は go-bin-deb を使っています。開発元からforkし、いくつか修正を施したものを公開、リリースしています。

使ってみよう!

今回つくる debianパッケージ は、 簡単なスクリプトを /usr/local/bin へ配置するものを作ります。

簡単なスクリプト:

#!/bin/sh

echo "LOVOT!!"

セットアップ

まずはセットアップです。 go-bin-deb は、アーキテクチャ毎にリリースが別れています。ここでは、amd64 アーキテクチャUbuntu or Debian Linux上で利用することにします。

1. go-bin-deb パッケージをダウンロードします:

curl -sLO https://github.com/groove-x/go-bin-deb/releases/download/$(curl -s https://api.github.com/repos/groove-x/go-bin-deb/releases/latest | jq '.tag_name' -r)/go-bin-deb-amd64.deb

2. go-bin-deb パッケージをインストールします:

sudo dpkg --install go-bin-deb-amd64.deb

deb.json をつくる

次に、debianパッケージ のメタ情報や、ファイル配置を定めるために、deb.json をつくります。

{
  "name": "example-package",
  "version": "0.0.1",
  "arch": "all",
  "description": "short desc of the program",
  "description-extended": "long desc of the program with multiline",
  "maintainer": "GROOVE X",
  "homepage": "https://tech.groove-x.com/",
  "files": [
    {
      "from": "example-script",
      "to": "/usr/local/bin",
      "fperm": "0755"
    }
  ],
  "copyrights": [
    {
      "files": "*",
      "copyright": "Copyright (c) 2022, GROOVE X, Inc. All rights reserved.",
      "license": "MIT"
    }
  ]
}

その他の項目はこちらのリファレンスを参考にしてみてください: https://github.com/groove-x/go-bin-deb#json-file

補足:

  • archall としているのは、今回アーキテクチャに影響しないスクリプトだからです
  • systemd のサービスにする場合は systemd-filepreinst,postinst,prerm,postrm など活用します

パッケージを作る

deb.json があるディレクトリで

go-bin-deb generate

すると、 example-package_0.0.1_all.deb が作られているはずです。

もちろん、このパッケージはインストールできますので、試してみましょう:

sudo dpkg --install example-package_0.0.1_all.deb

アンインストールも簡単です:

sudo dpkg --remove example-package

リポジトリへアップロードしてつかう

せっかく debianパッケージ を作ったので、 debianパッケージ のリポジトリへ登録してみましょう。debianパッケージリポジトリのサービスは多々ありますが、今回は Google Artifact Registry と packagecloud について簡単に紹介します。

Google Artifact Registry

社内向けや、インスタンス向けに運用するときに活躍するのが Artifact Registry です。以下のドキュメントに沿ってセットアップすると、自分のマシンからでもdebianパッケージを利用できるようになります。

参考ドキュメント:

packagecloud

個人的にオススメなのが packagecloud です。公開リポジトリで良ければ無料でリポジトリを持て、利用者のセットアップも簡単にできるので、 debianパッケージ を気軽に配布できるのではないでしょうか?

参考ドキュメント:

packagecloudでの配布例:

次のステップ

もうすこし実用的な例として、Goのバイナリを debianパッケージ にする例を置いておきますので、参考にしてみてください。アーキテクチャ毎へのリリースのヒントがあります。: https://github.com/atotto/kssh

また、 go-bin-deb をバンドルした dockerコンテナ を準備しているので、よかったら使ってみてください: https://hub.docker.com/repository/docker/atotto/debian-builder

最後に

go-bin-deb を使って debianパッケージ を作ってみました。jsonで構成管理しつつ、手軽にビルドできるので多少敷居は低いのではないでしょうか? Debian公式リポジトリへ登録できるレベルにはならないですが、社内ツールの配布などで活用してみてください!

半年働いて感じたGROOVE Xの面白いところ

この記事は「GROOVE Xアドベントカレンダー2022」の21日目の記事です。

こんにちは。GROOVE X の Lovot Framework チームの bucchi です。今年入社したばかりの新入りです。

私は、別のエントリで紹介のあったLOVOTのOS(らぼとす)の開発や、ふるまいの動作をマイコンFWに伝えたり、センサー値を認識系ソフトウェアに伝えるなど、LOVOTの動作を支える土台となるソフトウェアの開発を担当しています。

みなさん技術的な記事を書かれていますが、私の場合まだ公開できないお仕事が多く、書けるネタがなかったので、趣向を変えて半年働いてみて感じたGROOVE Xの面白いところや、エンジニアの働き方や雰囲気をお伝えできればと思います。

続きを読む