特定のRDFの変更に合わせて、それを基にクエリを実行させて別のRDFを作るCircleCI

「特定のRDFの変更に合わせて、それを基にクエリを実行させて別のRDFを作るCircleCI」

タイトルの通り
実際のPRはこちら
まぁ、訳あって(後述)マージせずに閉じましたが。

背景

im@sparqlでは自動生成系のRDFがある。

この2つは、Clothes.rdfUnit.rdfの逆方向の述語のトリプルが定義されている。
つまり、

  • Unit.rdf
    エターナルハーモニー --メンバー--> 千早
  • Unit_memberOf.rdf
    千早 --所属--> エターナルハーモニー

みたいな感じ。

なので、Clothes.rdfUnit.rdfが編集されたらそちらも編集する必要がある。
とはいえ編集するのは面倒なので、Node.jsを用意して適度に回している。

github.com

(一応公開してるが完全に自分専用って感じのゴミコード.....)

問題点

XML構文解析はど素人だし興味もないので、Node.jsでやっているのはキャラごとにまとめたSPARQLクエリをGETで叩いて、XMLっぽく排出している。
そう、SPARQLを叩いている
ということは、一旦変更をSPARQL鯖に反映しなくてはならない。
つまり作業としては,

  1. Unit.rdf || Clothes.rdfを編集してPullReq出す
  2. GitHubでマージする
  3. SPARQL鯖の更新
  4. 自動生成スクリプトを走らせる
  5. PullReqを出す
  6. GitHubでマージする
  7. SPARQL鯖の更新

というわけ。慣れればそんなに苦でもない
とはいえ傍から見ればアホ丸出しなので、苦手意識のあるCircleCI克服も兼ねて自動化しました。

結果

CircleCIでやっていることの流れ

  1. DockerImagestain/jenaでCircleCI上でSPARQLを動かせる環境を作り、自動生成で使っているのと同じクエリを撃つ
  2. 結果をJSONファイルに保存する
  3. DockerImageをcircleci/nodeに切り替える
  4. 結果を保存したJSONファイルを読み込み、自動生成で使っているのと同じ処理でXMLを作る
  5. node.jsのconsole.logはUTF-16っぽいので、エンコードを変換する
  6. GitHubbotアカウントでPullReqに対して追加コミットをする

botでの追加コミットはこちらを参考にした

www.ncaq.net

実際の動作

github.com

試行錯誤の末の結果なので、ゴミみたいなコミットは無視して欲しい

おわりに

まぁ結局、botでやる方式だとPullReqする人全員がbotのアクセスを許可しないといけなかったり、CIの発火のタイミング調整がブランチかタグしかなくてコミット時に統一しないといけなかったりと他の編集者の負担を増やしそうだったのでマージせず、別の方法をすることにした。 某所での助言より、自動生成物かつ、逆方向の述語という性質上GitHubで変更を記録するほどでも無いので、Jenkinsでどうにかしようとしている。
それはまたの機会に。

RDFまたはSPARQLの問題点・疑問に関するポエム

背景

先日のアイマスハッカソンで某氏から、im@sparqlに関するある要望を受けた

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

ハッカソン当時のアイドルのインスタンスには、アイドル名がschema:nameにxml:lang="ja"として格納されていた。(今は英語名xml:lang="en"が追加されている)

<schema:name xml:lang="ja">如月千早</schema:name>

この言語タグを付けたプロパティはよくある文字列型(xsd:String)ではなく、言語タグ付き文字列型(rdf:langString)として認識される。(datatype()関数使えば分かるよ)
つまり、

select * 
where{
  ?s ?p "如月千早".
}

では検索できない。("如月千早"はxsd:Stringなため)
検索するためには、

select * 
where{
  ?s ?p "如月千早"@ja.
}

といった具合に、言語を指定してあげる必要がある。
その際、

「この@jaって、"如月千早"が日本語タグで書かれてると知ってないと書けないよね」

と言う話になった。たしかに、実は"如月千早"が中国語として登録されていれば、日本語だと思って@jaを付ける人は「検索にヒットしねぇ...」と呟くことになる。

そこで冒頭の

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

に繋がる。

select * 
where{
  ?s ?p "如月千早"@ANY_LANGUAGE.
}

のような(上記の書き方はできない)感じで検索したいということだ。

ちなみに、

select * 
where{
  ?s ?p ?o.
  filter(str(?o)="如月千早")
}

といった感じで、str()関数でrdf:langStringをxsd:stringに型変換してフィルタリングすると実現できる。
スマートじゃないよねって結論だけど。

疑問

SPARQL触ったことある方は、上の背景を読んだだけで「言語タグ付き文字型リテラルで検索すれば良いじゃん」と思うでしょう。
SPARQLはリテラル^^を付けて後ろに型を書くと、その型リテラルになる。

"hoge"^^xsd:string
"--04-27"^^xsd:gMonthDay
"162"^^xsd:int
"162"^^xsd:float

つまり、

select * 
where{
  ?s ?p "如月千早"^^rdf:langString.
}

しかし、なぜか検索できない

調整

<schema:name xml:lang="ja">如月千早</schema:name>
↓
<schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name>

といった具合に、RDF側を調整してみることにした。言語タグ付き文字型を明示的に宣言した。
すると、

select * 
where{
  ?s ?p "如月千早"^^rdf:langString.
}

で見事、検索にヒットさせることができた。
しかし、

select * 
where{
  ?s ?p "如月千早"@ja.
}

で検索することができなくなってしまった。言語タグの情報が死んでしまった。

何故じゃ

現状(2019/4/30)

冒頭で書いたとおり、現在は

<schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name>
<schema:name xml:lang="en" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">Kisaragi Chihaya</schema:name>

のように、英語名も並んでいる。
言語タグ情報が死んでいるので、完全に並列な情報として並んでしまってる。

たぶんrdf:langStringを消すと思うけど、結局

「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」

はどうすりゃいいんでしょうね。

追記

なんか分かる所にメモりたかったもの

「近未来アウトサイダー」のカタカナ語

こちらはアイドルマスターアドベントカレンダー25日目の記事です。前日は、ろころこさんのクリスマスイブにロコについて語る(脈絡がない)です。


12/25にもなればおそらく、だいたいのPはミリシタをプレイしていなくてもTCという単語を見たことあるのではないのでしょうか?

TCとは

TC : THE@TER CHALLENGE

「THE@TER CHALLENGE!!」とは?
去年実施されたシアターブースト企画の第2弾!
ミリシタのゲームをプレイすることで手に入る投票券をつかって、 発表されたテーマと配役にあったキャストをプロデューサーの皆さんが投票していただくキャスティング投票企画です!

アイマスブログより
隣のお城の事務所の総選挙やパッション爆裂な事務所の大作戦のように、私たちの投票によってCDの内容を決める765MillionTheaterの一大イベントとなっています。上記の通り、テーマと配役にあったキャストを投票で決めます。

で、

過去2回(TA, TB)では、765TheaterAllstarsが投票の対象となっていたのですが、今回から765ASの13人も加えて過去最多の52人で3作×5役=15枠を争う形となりました。
私たち千早Pを含む、765AS勢のPとしては待望のイベントとなりました。LTF、MS、MGシリーズとミリオンへの楽曲参加がここ数年無かったので大きなチャンスです。逃したくないですね。

投票が始まって1週間近く経ちましたが、毎日のように企画や流行語による得票数ドラマが繰り広げられています。それはもちろん765ASアイドルも例外ではなく、765ASのPの積もり溜まった何かが破裂するように配役争いを続けています。
昨日の12/24は萩原雪歩の誕生日でもあり、日替わりとともに数多の表を獲得して、キャラ別総得票数1位に大差で躍り出ました。

千早P 陣営

千早P陣営は、本人には内緒でとてもアレなタグを生み出してしまいました。それは...
#ダスくっ千早
TC発表当日にはすでにタグとして流れていたことから、多くの千早Pが賛同、拡散してスタートダッシュを狙ったのでしょう。
僕はTBで風花さんに水着を着せるために奮闘したので、またお前は仕事のために担当を悲しませる営業をさせてるのか...という状態ですが、歌の仕事のためにクチバシ付けて頑張ってください。

本題

ぶっちゃっけ「近未来アウトサイダー」って何?カタカナゴワカラナイってなってしまっているので自分の勉強も兼ねて、千早P陣営の現在の矛先である「近未来アウトサイダー」をお勉強したいと思います。
f:id:crssnky:20181218232757j:plain

アウトサイダー

インサイダーの方は耳馴染みがあると思います。法律的な意味で。
英語で書けば"outsider"。いわゆる部外者・よそ者の意ですが、常識や社会という枠の外の人という意味もあり、異端者という含みのある捉え方をすることもできます。

ダスク

心と鍵が重要なゲームのエネミーしか思いつきませんでしたが、"dusk"は夕闇や夕暮れ時自体を指します。
世界が闇に包まれないようにギリギリで保つ、正義側の登場人物でしょうか。

バスターブレイド

狩猟生活のゲームではお馴染みの武器名ですね。"Buster Blade"はそのままだと破壊する刀と訳します。
"Buster"は物理的な破壊が主な意味ですが、犯罪撲滅などの撲滅させる人を指したり、ストレス解消法の"解消法"を指す時に使えたりと、悪いものを退治する意味も込められていそうです。

アウトレイジ

某映画シリーズの印象通りでしょうか。"outrage"は激しい怒りや暴力、暴動を指します。"rage"自体も怒りなどの激しい感情を指し、それらが外に出た結果=行動を指します。
アウトレイジ軍、本物の軍であればクーデター、義勇軍だとしても暴動を起こす危ない存在だと言えますね。

マリリス2

"Amaryllis"はヒガンバナ科にあるヒッペアストルム属の植物の総称みたいです。主に園芸用途で生産され、球根を持ち、(目"モク"から違うが)百合に似たラッパ型の花が特徴です。
アウトレイジ軍に捕らわれている、不思議な力を持つ少女ということもあり、ヒロイン枠となっています。

ベルベット

ローマ帝国かどこかの昔の強い指導者の名前かと思えば、織物の名前でした。"velvet"はパイル織物の一種です。このパイル織物というのは、下地から片面か両面に繊維が飛び出ている(←パイル)織り方をするものです。身近なものはタオル地がそれです。ベルベットはタオル地と違い、パイルをカットしてフシャーとするみたいですがイメージと違い、絹やレーヨンがベルベットに属します。絹などの手触りが良いのも、タオル地のようにフワフワ感を出しつつ引き締まった見た目に仕上げる高度な技術があるからなんでしょうね。
紹介文では、

アウトレイジ軍の特攻隊長。圧倒的な強さを誇る。

とありますが、繊細な生地を冠するキャラクターでもあるので、力任せに戦場を制圧するパワープレイヤーではなくて、高貴な頭脳派プレイヤーなのかもしれませんね。

ファイナルデイ

アウトレイジ軍を率い、混沌とした世界を手中に収めようとする(たぶん)悪いやつ。
"荒廃"や"混沌"はおそらくアウトレイジ軍、もといファイナルデイの企みによるものでしょう。
サイゴの日を意味しますが、果たして"最後"なのか"最期"なのか...どのような目的で世界を手に入れようとしているのか気になりますね。

以上です

あの1枚のスライドの単語たちから読み取れそうなものはこれくらいだと思います。
ミリシタの開発プロデューサーであるわかちこPでさえ、"スタッフ陣が分からない"と話した「近未来アウトサイダー」、キャスティングがお話にどれほどの影響を与えるのかは、考えるまでもないですね。

追伸

アイマスハッカソン2018でのim@sparqlのご利用ありがとうございました。

IM@Study合同本@C95 2日目東ト-56b

f:id:crssnky:20181122223018j:plain
じゃ~~ん
ここでは何度も登場しているIM@Studyというグループから、今回は希望者5人が寄稿する合同本を出すことになりました。場所はC95 2日目の東ト-56bです。
表紙は文月きょうさんにお描きいただきました。見事に「週アス」感が出ていて僕はとてもお気に入りです。

中身

  1. アイマス楽曲を歌詞解析してみた話
    著者:きりだるま
    概要:800曲近くあるアイマスミュージックがテーマです。歌詞検索ソフトで取得できた歌詞に対して自然言語解析を行い、「エモさ」を感じることを目指します。
  2. アイドルと学ぶホームページの作り方
    著者:MH35
    概要:物理層から構築するホームページの作り方がテーマです。松田亜利沙が765プロのホームページを作るために奮闘する様子が、いわゆる台本形式で描かれます。
  3. 李衣菜チャンのヘッドホンアンプをつくるにゃ!
    著者:ヘヴろく
    概要:李衣菜チャンのためにみくにゃんが奮闘する電子工作がテーマです。回路の論理設計から、シミュレーション、基盤図作り、発注までの一連の流れを、ヘッドホンアンプを例に体験します。
  4. im@sparql入門
    著者:croMisa
    概要:私のやつです。クエリの打ち方から、アプリケーションへの組み込み方までを説明します。
  5. スコアを用いたライブの予習セットリスト自動生成の試み
    著者:遠山 賢寿
    概要:非常に多く増えてしまったアイマス楽曲、シンデレラガールズだけでも200曲近いので、ライブ前の予習を効率化するために、セットリストの自動生成を試み、その成果を説明します。

組版には"なかひこくん"さんにしてもらいました。markdownで書けるフォーマットから中身の最終デザインまでおり、いわゆる出版社の"編集さん"+αの仕事をしていただき、非常に助かりました。ありがとうございました。

UE4で使える"つよい"mosquittoライブラリ

github.com

なんとBP上で扱えるらしい(GitHub説明画像より)

そもそもMosquittoって広く知られているソフトウェアかよくわからない(自分も最近知った)なので、まずはそこから

Mosquitto(MQTT)とは

MosquittoはMQTTというメッセージングプロトコルを、EclipseC++オープンソース実装したものです。

mosquitto.org

C++なので、UE4に組み込めるってわけですね。

んで、そのプロトコルであるMQTT(Message Queue Telemetry Transport)ですが、IBMが1990年代後半に開発した、信頼性の低いネットワーク上で動く低性能のデバイスで実現する軽量で柔軟なプロトコルです。

www.ibm.com

MQTT概要

それが公開された現在は、Publish/Subscribeの単一のメッセージに対して多数のクライアントが受信できる形をとっています。そのために、Brokerと呼ばれるサーバー役を立てる必要があります。
クライアントはBrokerに接続し、必要であれば接続後の任意のタイミングでSubscribeをします。この時、「Topic」を指定します。このトピックはメッセージに付けられるタグのようなもので、タグとは違い階層構造を取れることです。また、複数指定することもできます。
接続したクライアントがメッセージをpublishしたい時は、メッセージと共に上記のTopicをBrokerに送信します。すると、そのTopicをSubscribeしている全てのクライアントはそのメッセージをBrokerから受信します。

Topicで区別するだけなので、接続するデバイスの組み合わせごとにソケット通信を立てる必要がなく、雑に送受信できるのが良いですね。Brokerが必要ですが....(PublicBrokerというものが建っており、それを利用することもできる。Publicなので不特定多数の人間がつないでるけど...)

UnrealMosquitto

表題のやつです。
Broker機能は無いですが、クライアント機能は実装されており、BPからも振る舞いを実装できます。
個人的には受信時の振る舞いをBPで雑に実装できるのがアツいですね。なにかしらのデバイスからの情報をUE4でカッチョイイ感じに可視化したい時とかは使えるんじゃないでしょうか。どうせデバイスのログは軽量な別ソフトでしょうし。そのネットワークにMQTTで簡単にjoinできるのはアツい。熱盛っ!

ちょっと重要な内容ですが、余談を。
実は現在の状態だと4.20でビルドできなかったりShippingできなかったりと諸々問題があるのでPullRequestを出させていただきました。もしこれから使われる方がいましたら、そのへんにご気をつけください。

おわり

MQTTで気軽にjoinして積極的にUE4でビジュアライズしていこう💪
MQTTに表面上似たものとしてAdvanced Message Queuing Protocol(AMQP)があります。こちらはその中にも種類が分かれており、中にはサーバー役の必要ないZeroMQもあります。

im@sparqlのドキュメントみたいなの書いてる

im@sparql.doc

タイトル通りです。

以前から、im@sparqlが気になってはいるのもののSPARQLとかわっかんねぇな?というお話をいただいており、どげんかせんといかんと思いながら放置していましたが、IM@S Engineer Talksでちょっと話題になったこともあり使命感を感じて開設しました。

内容

Getting Started

  1. im@sparqlとは
    im@sparqlの思想みたいなのを書いた、よくある意識高いページ。
    一番最初にありますが、im@sparqlのあとがきみたいなものです。
  2. 触れてみる
    im@sparqlを使う上で欠かせない要素のSPARQLを解説する部分。
    データベースの大枠に触れる、未経験者には難解なクエリですが、次項以降のサンプルクエリを読み解けるように解説しました。
  3. 使ってみる
    データベースの中身を一切知らない状態から、千早さんのプロフィールを取得するまでの流れを3STEPで解説しています。
    SPARQLのクエリの組み方が分かれば幸いです。
  4. 組み込んでみる
    完成形のWebページを例に、実際にオープンデータベースとしてWebページから活用する方法を解説しています。
    Http通信でJSONが取得できるので、そのへんに慣れてる人には退屈な内容です。
  5. 貢献する
    GitHubに公開されているim@sparqlのデータベースの中身を解説しています。
    中身が読めればクエリも効率的に立てやすくなるでしょう。
    また、データベースに足りない情報を補うのを手伝っていただければ幸いです。

Query Samples
クエリ集みたいなのも置いていければ...
まだどういう風に置くか未定。Gist.GitHubをただただ貼れば良い?

締め

これをきっかけに、im@sparqlを活用していただければと思います。
それと、活用した何かを作った時、もし良かったらに報告してもらえると嬉しくなります。

こいついっつもim@sparqlの話してんな?

IoT(Idol of Thing)でRasPiに千早さんもどきを宿らせる

f:id:crssnky:20180710221717p:plain
はい。
そんなことはみなさんご存知でしょうね。

今年から一人暮らしなので、お部屋ではやりたい放題なのでは?!と思い、1年以上買って寝かせてたRasPi3を取り出しました。
イマイチ使いみちが見つから無かったのですが、ここらでいっちょRasPiならではのことに挑戦していきます。

注意:技術の説明じゃないので、こんなアイデアどう?ってスタンスで見てください

作りたいのはこちら f:id:crssnky:20180710222151p:plain
こんな感じでですね、自宅に入ったら「おかえりなさい」と声をかけてもらえるシステムですね。

センサー

センサーはドーム型の人感センサー、
"HC-SR501"
を使います。(Amazonとか秋月でご参照ください...)
f:id:crssnky:20180711225930j:plain
こんな感じで自室ドアに貼り付けます。1Kなので自室ドアで良いんです。
こいつには、電源・GND・信号の3つの端子があります。単純でありがたいですね。
また、センサーが反応してから次にアクティブになるまでの間隔と、反応強度を変更する可変抵抗も付いています。
ご自分の気分で調整してください。

配線

諸々の配置の関係で、RasPi3は逆側の壁際に設置してます。
そのため、5m近い長さの線が必要になりました。
自作するしかねぇ! f:id:crssnky:20180711231709j:plain
というわけで、某電気街で買ってきました。圧着ペンチはAmazonだけど。
"エンジニア 精密圧着ペンチ オープンバレル端子用 PA-20"

頑張ることもなく、3色の線が完成です。
f:id:crssnky:20180711232229j:plain
配線しましゅ。 f:id:crssnky:20180711232432j:plain
これでハードウェアはOKですね。

プログラム構成

後々の機能拡張を見据え、WebからRasPiを制御したいと思い、
I/Oが制御できる環境を探しました。
それがこの、Pythonで動くWebフレームワーク「bottle.py」です。
売り文句として、

  • 軽い
  • 早い
  • 単一ファイルのimport(pipしなくてもいい)(pip版もある)
  • 依存関係ない

らしいです。 これを使ってWebのViewerからI/Oの制御までを行います。
今回で言えばこんな感じ f:id:crssnky:20180714002244p:plain
ってなんの説明にもなってない画像ですね。
とりあえず、Pythonのコード内の時間とかで制御する時の変数をWebから書き換えるってことを今回はやらせていってると思ってもらえれば。

f:id:crssnky:20180714013108p:plain
これ実際のコードです。汚いけど見られてもまずいものはないはず。
テンプレートエンジンだったり、CSSなどのファイルがキッチリロードできるようにだったり、http通信のモジュールだったりをimportしています。
また、時間による動作はapschedulerBackgroundSchedulerを使っています。これにより、cron的な日時に合わせて動作を行うことができます。

書いてはいなかったですが、起床アラームの機能も付与しており、"Alerm"系で表しています。
AlermConf, WelcomeBacktimeConfでは、現在設定されている時間を渡しています。
見た目はこんな感じ f:id:crssnky:20180714015049p:plain
RasPiは良いですね。AppleBonjourが入っていれば、ローカルのRasPiに対してraspbery.localでIPから代替できますから。
それは置いといて、こんな感じでViewerの方も作りました。
自分しか使わないので、CSSも無しです。
渡された現在設定の時間を表示し、代わりに新たに設定したいものを渡せるようにしています。
Python側でPushされた更新したい時間を受け取り、内部変数を書き換えてスケジューラーを更新することで完成します。

というわけでできたものがこちら