未分類

無料RPAで「ソリティア」に挑んでみた 業務自動化でゲームも自動化できるか

ニュース
» 2019年03月03日 22時30分 公開

カードゲーム「ソリティア」を業務ソフトに見立て、RPAによる自動化でクリアできるか試してみた。

[井上輝一,ITmedia]


 この1週間、記者は「ソリティアおじさん」になっていた。


1週間ほど社内でソリティアをするおじさんになっていた

 巷には今、「働き方改革」とともに「RPA」という言葉が台頭し始めている。RPAは「ロボティック・プロセス・オートメーション」のことで、普段の業務を自動化してくれるソフトだという。

 こんな説明がなされているが、これまでプログラミングに触れてきた人にとってはやや疑問が浮かぶのではないだろうか。「Excelマクロやバッチと何が違うのか」と。

 例えば、RPAの動作説明でよくあるのは「ファイルをゴミ箱に捨てる」という操作だ。RPAソフトがファイルをゴミ箱にドラッグ&ドロップするという操作だが、ファイルを削除するのが目的なら、Windowsであれば「del hogehoge.txt」と書いたバッチファイルを実行すれば済む話だ。「del *.txt」とすればフォルダ内のテキストファイルを一網打尽に消すこともできる。

 Webブラウザの操作であれば、「Node.js」や「Selenium」などですでに自動化しているという人もいるだろう。記者の場合はそこまではしていないが、ブックマークレットで簡易的に操作の一部を自動化していたりもする。

 このように、「ファイル操作ならバッチでいい」「ブラウザ操作ならSeleniumでいい」「Excelやスプレットシートならそれぞれのマクロでいい」となると、一体どこでRPAとやらを活用できるのかと疑問に思ってしまうかもしれない。

 そこで記者は考えた。Windows PCに標準で付属しているおなじみのトランプゲーム「ソリティア」を自動化しようと。

 ソリティアのようなスタンドアローンのゲームにはバッチ操作もブラウザ操作も適用できない。自社向けに独自開発した業務ソフトも、APIが用意されていたりしない限りは、ソリティアと同様の状況といえるだろう。

 RPAソフトの中でもスタンドアローン型と呼ばれるものは典型的に、デスクトップにあるものを画像として認識し、認識したものに対してクリックやテキスト入力など各種操作を行う。

 できれば業務ソフトの自動化をお見せしたいところではあるが、そもそもその業務ソフトが何であるかという説明がなければよく分からない上、それを一部でも公開することは会社の機密に触れる恐れもある。

 そこで、多くの人がよく知っていて、かつ業務ソフトと同様の性質を兼ね備えたソリティアを使って、RPAでできることを説明していこうというのが本記事の趣旨である。

 会社で他のメンバーが記事を執筆・編集する中、23型のディスプレイに大きくソリティアを表示する記者は、傍目には「業務中にソリティアをして時間をつぶしているおじさん」に見えていたかもしれないが、こういう理由だったので許してほしい。

無料で使えるオープンソースRPAソフト「SikuliX」

 今回、RPAには無料で利用できるオープンソース開発のRPAソフト「SikuliX」(バージョン1.1.3)を用いる。


SikuliXのUI

 SikuliXは米マサチューセッツ工科大学のユーザーインタフェースデザイングループが2009年から開発を主導し、オープンソースの画像処理ライブラリ「OpenCV」を利用してデスクトップ上のあらゆるものを自動化することを目的に作られている。

 ソフト自体の開発言語はJavaで、Windows、Mac、Linux上で動作する。SikuliXは自動化する内容を記述するためのIDE(統合開発環境)でもあり、記述言語にはデフォルトでPython(Jython)の他、Ruby(JRuby)、JavaScriptをサポートするとしている。

※Jython、JRuby:PythonやRubyの文法で書かれたコードを、Java仮想マシン上で実行する実装のこと。

カードを移動させてみる

 プログラミングを理解しなくても、例えばある物体をある場所へドラッグ&ドロップするという動作であれば、マウスを動かすだけで実装できる。

 SikuliXが立ち上がった画面を見ると、左カラムにある「マウスの操作」という項の中に「dragDrop([カメラマーク], [カメラマーク])」という関数があるので、これをクリックする。


左カラムにある「マウスの操作」という項の中に「dragDrop([カメラマーク], [カメラマーク])」という関数があるので、これをクリック

 すると右のテキストエリアに「dragDrop([カメラマーク], [カメラマーク])」と入力され、このカメラマークをクリックするとスクリーンキャプチャモードに移行する。

 ここで動かしたい物体として、例えばハートの4を矩形で指定する。次に、2つ目のカメラマークをクリックして、動かす先であるクラブの5を指定する。このようにすると、マウスで指定したエリアがテキストエリアに変数として画像のまま表示されるため、自分が関数にどんな画像を渡したかを直感的に理解できる。


ハートの4をクラブの5へ移動させてみる

 これで実行ボタンを押せば、マウスカーソルが勝手に動き出し、ハートの4をクラブの5へ勝手に移動させてくれる。

 さらに山札をめくる(クリックする)という命令をしてみよう。

 左カラム「マウスの動作」から「click([カメラマーク])」をマウスでクリックし、テキストエリアに入力された関数のカメラマークをクリックし、キャプチャモードからカード裏面の絵柄を矩形選択する。これだけだ。

 テキストエリアで先ほど指定した画像変数にマウスオーバーしてみると分かるのだが、この変数は実際には文字列であり、スクリーン上の位置情報は入っていない

 よって、これらの関数はマウスカーソルの軌跡をなぞって動いているわけではなく、文字列から参照した画像(png)ファイルに一致する位置をスクリーン上から探索しているのだ。

 つまり、「ハートの4をクラブの5に移動しろ」という命令は、カードの位置が変わっても有効ということだ。


カードの移動と、山札のクリックの命令を実行すると、自動でハートの4がクラブの5に移動し、山札が開かれた

 このように、簡単な操作であれば、特にPythonなどプログラミングを意識しなくても作れる。そしてPythonは特別な宣言(C言語でいう「#include <stdio.h>」や「int main(void)」など)がなくても動くので、Python流のif文やfor文を書けば簡単な条件分岐や繰り返し処理が簡潔に書ける。

 記者はJava開発経験がほんの少しあって、Pythonは書いたことがないという程度のスキルだったが、Tabによるインデントにさえ気を付ければかなり平易に書けるという印象だった。

 Pythonを書くに当たっては、『スラスラわかるPython』(翔泳社)、SikuliXには『オープンソースで作る! RPAシステム開発入門 設計・開発から構築・運用まで』(翔泳社)を参考にした。

ソリティアはクリアできるか

 今回、ソリティアの中でも代名詞的な「クロンダイク」の初級レベルに挑戦した。

 ゲームの条件としては、場札のカードは赤と黒を数字順に乗せていき、山札は1枚ずつめくるというもの。人間が挑めば、カード配置的にそもそもクリア不可能でなければまずクリアできるくらいの難易度だ。

 これくらいであれば、定型業務のように、そこまで複雑化した条件分岐でなくてもクリアできるのではないか。そう思って挑戦することにしたが、先に結果を言うと、丸2日で実装にチャレンジしてみてそれなりの複雑なプログラミングになった上、クリアには至らなかった


RPAソフトによる操作だけで最終的にここまで進んだが、クリアには至らなかった

 どんな方法で解こうとしたか、どこでハマってしまったのかをここから説明していく。おそらく画像認識ベースのRPAであれば他のソフトでも当てはまる部分はあると思うので、業務効率化などの参考になったら幸いだ。

実装方針

 まず解き方としては、最短で解くようなことは考えず、とにかくゲームが展開することを優先した。

 基本的な方針は、

(1)山札を開いてカードを特定する

(2)初回試行のみ、場札のそれぞれの山にある開かれたカードを特定する

(3)右上の組札置き場に送れるカードがあれば送る

(4)場札の山から他の山へカードを移動できれば移動する

(5)(1)に戻って繰り返す

 という繰り返しで解くことにした。


Copyright © ITmedia, Inc. All Rights Reserved.

ニュース
» 2019年03月03日 22時30分 公開

[井上輝一,ITmedia]


SikuliXでプログラミングする際にまず学ぶこと

 SikuliXの使い方を詳しく解説する日本語のサイトはあまりない。前述した参考書にも、関数の使い方など多くの説明はない。こういうときには英語でも、公式ドキュメントを読むのが一番だ。

 公式ドキュメントには、「全てのチャプターに目を通すか、関心あるコンテンツだけ読むか、あるいはRegionクラス、Matchクラス、Screenクラスの説明を読め」(意訳)と書いてある。記者は最後の3クラスの説明をまず読むことにした。

 この中でも、Regionクラスの理解が最も重要だ。なぜなら、MatchクラスもScreenクラスもRegionクラスの性質を全て受け継いでおり(継承)、Regionでできることはこの2つのクラスでもできるからだ。

 Regionは先ほど紹介したdragDrop()やclick()などを関数に持つ、SikuliXの中心的なクラスだ。

 例えば、

hoge_region = Region(0,0,100,200)
Regionインスタンスの絶対座標による初期化

 と、Region()に左上からのX座標、Y座標、幅、高さ(ピクセル)を与えてインスタンスを作成することで、スクリーン上の調べたい領域を設定できる。

 調べたい領域を設定するのは、スクリーン上の全ての領域で画像一致を探索すると、時間がかかったり、予想外の物体を誤認識してしまったりするためだ。

 そして、

match_obj = hoge_region.find("foo.png")

 のようにfind()関数を用いると、foo.pngの画像に一致する物体をhoge_regionから探索し、発見できた場合はその位置・サイズ情報を持ったMatchインスタンスを返す。なお、探索に失敗した場合はFindFailedエラー例外を出すため、try-exceptで例外処理をするべきだ。

 ここで得たMatchインスタンスをdragDrop()関数などに与えることで、物体の操作ができる。

 Regionインスタンスの初期化は、全てを手で入力しなくても、SikuliX IDE上部にある「Region」というボタンをクリックしてキャプチャモードから矩形を指定すれば位置・サイズ情報を自動入力してくれる。

 気を付けてほしいのは、この方法では絶対座標による指定になるということだ。例えばフルHDの画面ではうまく動いているとしても、HDやWQHDなど別の解像度になってしまうと思った場所に領域設定できないということもありえる。

 他の解像度のスクリーンにも対応させることを考えるなら、得た絶対座標とスクリーンの解像度から相対座標を計算しておくか、あるいはRegionの初期化に絶対座標ではなく、スクリーン全体からfindしたMatchインスタンスを与えるなどの工夫が必要だ。

SikuliX IDEでも書けないことはないが……

 変数や配列の宣言、関数・クラス定義、条件分岐の入れ子などをしていると、コードもそれなりの行数になってくる。

 少ない行数の簡潔なコードであればSikuliX IDE上でのコーディングでもあまり違和感はないのだが、長く複雑になってくると話は別だ。

 SikuliX IDEには変数を画像で見せる仕組みこそあれ、一般的によく使われているIDEやエディタのような、構造の折りたたみ、コード補完、リファクタリングなどの機能はない。

 こうしたモダンな環境で快適なプログラミングをしたいのであれば、一般的によく使われているPython対応IDE・エディタでコーディングしていった方がいいだろう。

 記者の場合は、コードを追加して実行・デバッグする作業はSikuliXで、複雑になったコードの編集は「Visual Studio Code」で、というように使い分けた。

ハマりどころその1 ループする回数

 2日間でクリアに至らなかった原因の一つには、1回当たりの実行に時間がかかりすぎてしまったということがある。

 時間がかかってしまったのは、forループの回数を考慮しきれなかったからだ。

 トランプのカードは52枚あるため、目の前にある1枚のカードが何であるか調べようとすると、最大52回の画像一致を試さなくてはいけない。

 find()関数のタイムアウト時間はデフォルトで3秒、スキャンレートは3回/秒となっている。このまま1枚のカードを特定しようとforループしてしまうと、最大で52枚×3秒/枚=156秒かかることになってしまう。

 タイムアウトとスキャンレートは自分で設定できるため、短く、早く設定して短縮化を試みたが、そもそもカード1枚に最大52回ループをかけるという実装が良くなかった。

 今後考えられる改善策としては、数字部分に画像一致ではなくOCRをかけて(SikuliXにはOCR機能も備わっている)数字を認識し、認識した数字のうちどのマーク(スペード、ハート、ダイヤ、クラブ)なのか4回ループして認識する、などが考えられる。あるいは、公式ドキュメントを読み込んだり、フォーラムに質問したりすればもっと良い解法が見つかるかもしれない。

ハマりどころその2 「類似度」のワナ

 最終的にクリアに至らなかったのは、どちらかといえばこちらが直接的な原因だ。

 find()関数は、画像と画像の「類似度」、つまりどれだけ似ているかを求めている。類似度は0〜0.99で表され、0.99が完全一致だ。

 デフォルトの設定では、0.7以上の類似度であれば「一致」としてMatchインスタンスを返すのだが、トランプのカードに関していえば、類似度0.7では例えばスペードの8がスペードの6と認識されてしまうなど、誤認識が多発してしまう。


類似度0.7で「スペードの4」と一致する場所を探すと、他の場所にも一致してしまう

 一致とする類似度は変えられるため、類似度を上げていけば基本的にこうした誤認識は避けられる。


類似度0.91まで上げるとスペードの4のみに一致した

 しかし、それにしても困ったのが「ハートの5」と「ハートの6」だった。類似度0.97の設定でも、ハートの6をハートの5と誤認識してしまう。

 類似度0.98の設定でようやくこの2枚を区別できるようになるのだが、今度は他のカードで「本来同じなのに一致してくれない」、つまり認識できないという事態が発生する。

 この「あちらを立てればこちらが立たぬ」というにっちもさっちもいかない状況に陥り、ゲームクリアに至れなかったのだ。

 実は、類似度の設定は全て一律に変える以外にも、画像別に設定することもできたため、これでうまく調整すればこの事態は防げたのかもしれない。

 しかし、だいぶコーディングを進めてからその仕様に気付いたため、個別の類似度設定を十分に試す時間がなかった。

ソリティアはかなり「非定型業務」だった

 業務ソフトの定型業務に見立てて解き始めたソリティアだったが、実際にやってみるとカード分類の試行回数と条件分岐の複雑さ、画像認識の設定の難しさが立ちはだかることが分かった。

 これらの理由から、ソリティアはRPAが最も得意とする「定型業務」というよりは「非定型業務」に相当するといえる。

 そして、こうした作業にRPAを適用するとしても、条件分岐やループ回数の考え方など、プログラミングスキルが要求されることも分かった。

 SikuliXだから特にスキルが要求されたのであって、他の有償のRPAソフトであればもう少し状況は違うのかもしれない。

 だが、仮にコーディングを必要とせず、GUIによる操作だけで完結するRPAソフトだったとしても、問題を解くに当たって試行にかかる時間や条件分岐、例外処理といったプログラミングの素養は必須になるだろう。

 今回、ソリティアのクリアには失敗してしまったが、例えば同じ場所を何度もクリックやドラッグ&ドロップするような定型作業であれば、このSikuliXでも十分自動化できることは分かっていただけたのではないだろうか。

 ほとんどのRPAソフトが有料の中、SikuliXは完全に無料だ。公式ドキュメントが日本語非対応だったりハードルはあるにせよ、「自分の環境でRPAソフトを使うとどんなことができるのか」と試してみるのにはいいだろう。無料RPAソフトは他にもあり、有償ソフトを導入する前の参考にするのもよさそうだ。

 記者が遭遇したハマりどころも含め、本記事が作業自動化の参考になれば幸いだ。


Copyright © ITmedia, Inc. All Rights Reserved.

Source: IT総合情報

Most Popular

To Top
%d人のブロガーが「いいね」をつけました。