サイボウズLiveで行っていた研究進捗管理をScrapboxに移行

結論から先に書くと,以下に移行しました。

  • 研究進捗報告: Scrapbox
  • スケジュール管理: Googleカレンダー

サイボウズLiveが2019年4月でサービスを終了しました。本研究室では研究進捗管理をサイボウズLiveで行っていて,特に以下2つをフル活用していました。

  • 掲示板機能: 学生各個人の研究進捗報告。学生1名につき1つのトピックを立て,それに学生が報告,教員がコメント,という順で進捗を報告していく。
    • 良かった点:
      • 画像のインライン埋め込みができる。報告書として議論しやすい。
      • 動画も簡単に貼れる。
      • ソースコードはシンタックスハイライトされて見やすい上に,デフォルトでは畳まれていて見たい時だけ展開できるので,議論がしやすい(サイボウズさん側のハッカー魂を感じられる)。
        プログラミング必須な研究室ではかなり重要な機能。

      • 学生にとっては,自分以外の学生の報告も見ることができるため,報告の良し悪しの相互学習になる。また,進み具合の相互発奮につながる。
      • APIがあるため(充実というほどではないが),オートメーション可能。
    • もう少し機能が欲しかった点(無料なので本当に十分なのですが,あえて言えば):
      • バックアップ機能。HTMLでの書き出しができないので,年度を締めくくって整理するのが厳しかった。(自作して対処していました)
  • カレンダー機能: ミーティングをいつにするか,卒論の〆切はいつか等を管理。また,就職活動等で欠席する日を報告。
    • 良かった点:
      • 予定当日にメールが届くのでうっかりが少なくなる。
      • 「Cc予定」という機能があり,自分の予定を誰と共有するかの範囲を指定できるので,表示が煩雑になりすぎない。
      • スマホ専用アプリがあったため,スマホのUIに則った通知や操作ができる。
    • もう少し機能が欲しかった点(無料なので本当に十分なのですが,あえて言えば):
      • APIの充実。予定の登録は本質的に面倒。例えば定例の会議とかは登録を自動化したい。(これも結局Selenium+Rubyで自作して対処していました)

その他,今年度に新しく購入した書籍や,関連研究のニュースなどをまとめていて,非常に便利に使わせて頂いていました。
しかしサービス終了とのことで,上記の「良かった点」をできるだけ持ち越せるようなグループウェア等を探しました。
いろいろなものを試してみて前述の通りの環境に移行したわけですが,理由は以下の通りです。

Scrapboxの良い点,および今までできていたことができなくなったのをどう対処しているか:

  • ソースコードがシンタックスハイライトされる。たたみ/展開はできないが,別ページへのリンクが極めて簡単なのでソースコードだけページを分けてしまえば良い。
    ちなみにArduinoのソースコード(拡張子.ino)も簡単ではあるがシンタックスハイライトされる(サイボウズLiveはそこまではできなかったので投稿時に拡張子を.cppに変えていた)。

  • 画像は簡単に貼れる。(Gyazoを通じてだが,それは意識する必要は全くない)
  • 動画は貼れないが,リンクを貼るのは簡単なので,Googleドライブに動画を置いてそれにリンクを貼れば問題ない(後述のように,Googleアカウントは全員持っている)。
  • 1研究テーマ(1個人)につき1プロジェクトという風にすれば,だいたい今までと同じ使い勝手になり,かつ,各プロジェクトに全員を所属させれば他学生の報告も参照できる。
    ただしプロジェクトをまたいだリンクや検索はできない。Scrapboxはリンクが機能のキモであり発想支援が素晴らしいので,どうするか検討中。

  • プロジェクトはPrivateにもできる。
  • ログインにはGoogleアカウントが必要だが,本学ではGmailを契約しているため,全員がGoogleアカウントを持っている。
  • バックアップは,プロジェクト単位でJSONでエクスポートできる。また自動定期バックアップ機能もある。
    HTMLで書き出せたりできるわけではないが,JSONでエクスポートしたものをコンバートするプログラムを書けば,インライン画像埋め込みも含めて簡単にできそう。

Googleカレンダーの良い点,および今までできていたことができなくなったのをどう対処しているか:

  • 複数のカレンダーを重ね合わせることができるので,自分の予定と研究室の予定は色などで区別できる。
  • スマホのUIがある。スマホのホーム画面にも貼れる。通知もしてくれる。
  • PCのブラウザでのUIはやや見づらいが,拡張によりややカスタマイズはできる。
  • Googleアカウントが必要だが,前述のように全員持っている。

ということで,かなり満足のいく移行ができています。
たまたま学生が全員Googleアカウントを持っているなどの特殊事情はあるので参考にはあまりならないかも知れませんが,書いてみました。

なお,その他に以下のグループウェアなどを検討しました。
以下の感想は個人の主観であり間違いも含んでいると思います。
また,研究進捗報告に適しているかも私にとっては重要です。

  • サイボウズOffice
    30日間無料を試してみたが,掲示板機能はサイボウズLiveよりも貧弱に思える。
    ソースコードを文中に挿入することもできない。
    (添付はできるが,展開ができずダウンロードになる)

  • R-Group
    クラウド型,容量無制限,利用人数無制限。
    試用してみようとユーザ登録したがメールが来ないので試用できなかった。

  • ZOHO Connect
    UIが学生に厳しそう。Taskの使い方がよくわからない。

  • GROUP SESSION
    オープンソース。画面がややモダンではないか。
    掲示板が,文->ソース->図->文… みたいな文中埋め込みができない。

  • SHIRASAGI
    デモサイトがあるが,グループウェアとしてどう使うのかがよくわからなかった。

  • Stock
    「ノート」機能はドラッグ&ドロップでどんどんファイルをくっつけていけるが,投稿ごとにわかれるわけではないので使っていくとどんどん長大なノートになってしまう(と,前のを誤操作で消してしまいそう)。

  • iQube
    無料だと30MBなのでちょっと厳しい。

  • Office 365
    掲示板機能はあるが,ちょっと面倒そうな印象。
    ソースコードも貼れないっぽい。

OpenGLが使えない環境でも3Dプリンタのスライサが使いたい(MesaによるOpenGLのソフトウェアエミュレーション)

3Dプリンタでは,3Dモデルをスライサというソフトウェアでスライスする必要があります。スライサは大抵の場合「どんな向きでプリントするか」等も調節できるため,一種の3Dビューアにもなっており,このためOpenGLを要求されることがあります。

本研究室の3Dプリンタ「QiDi X-Smart」付属のスライサ「QiDi Print」でもやはりOpenGLを要求されます。このため,リモートデスクトップや,非力なノートPC等でQiDi Printを起動すると,

Could not probe OpenGL. This program requires OpenGL 2.0 or higher.
Please check your video card drivers.

のように言われてしまい起動できません。しかし,そんなに凝った調節をしたいことはあまりないので,どうにか起動させてスライスだけしたいことも多いと思います。こんなときの解決法として,OpenGLをソフトウェアでエミュレーションしてしまうという方法があります。方法は非常に簡単です。

具体的には,まず普通に QiDiInstall 4.2.16.exe をインストールします (C:\Program Files\QiDi 4.2 に入る)。
次に
http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-mesa-18.3.4-1-any.pkg.tar.xz
をダウンロードし,7zip等でxz,tarの順に伸長していくと,mingw64\bin\opengl32.dll があるのでこれを
C:\Program Files\QiDi 4.2
にコピーします (QiDiPrint.exe のある場所)。

これだけです。意外にも軽く,普通に実用になります。
これはたまたまQiDi Printの例ですが,他のスライサやその他の3D関係にも応用可能だと思います。

OpenCVでCAP_PROP_FRAME_WIDTHが効かないカメラをEWCLIBの併用で何とかする

OpenCV (C++) でWebカメラからのキャプチャ解像度を変更したい場合,本来は以下のようにすれば良いはずです。

cv::VideoCapture vc;
vc.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
vc.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);

しかし,このAPIはカメラによっては効果がないことが良くあります。特にLogicoolのカメラでは16:9のキャプチャをしようと思っても無視されてしまう傾向にある気がします。長年未解決な問題です。
(Windowsでの問題。LinuxやMacでは違うかも知れません)

この問題については,EWCLIB を併用するのが良いようです。キャプチャ部分を他のライブラリに頼る方法は EWCLIB 以外にもいくつかあるようですが,EWCLIB には以下のようなメリットがあります。

  • ヘッダのみなので導入が簡単。
  • Visual Studioのバージョンを殆ど選ばない1
  • x64向けにも簡単にビルドできる。

デメリットもありますが2それほど根本的なものでもありません。導入は以下のようにします。

Windows 10 + Visual Studio Professional 2015 で動作確認しています。

qedit.hを用意する

EWCLIBには別途Windows SDKの「qedit.h」が必要です。これは以下のように用意できます3

  1. Microsoft Windows Software Development Kit Update for Windows Vistaのページで [DOWNLOAD] をクリックして 6.1.6000.16384.10.WindowsSDK_Vista_Feb2007Update_rtm.DVD.Rel.iso をダウンロードします。
  2. 上記isoファイルをマウントします。例えばWindows10の場合はダブルクリックすればドライブレターが割り振られてマウントされます。
  3. マウントされたドライブの Setup フォルダ内の WinSDKBuild-SDK_DirectShow_BLD_Common-common.0.cab を探します。qedit.h はこの cab ファイル内にあります。
  4. cab ファイルを伸長できるツールで上記 cab ファイルを伸長します。Windows 10 の場合はダブルクリックすればフォルダのように扱えます。
  5. qedit_h.99023124_2CFC_4698_80A9_F84FC02DCB6C を探して,任意のフォルダにコピーし,qedit.h にリネームします。
Visual Studioから使えるようにする

ewclib.h と qedit.h を任意のフォルダにおいて,自作プロジェクト等から「追加のインクルードディレクトリ」等を設定します。
私はプロジェクト内に置いて相対パスで指定するようにしています。

なお .lib は無いので「追加のライブラリディレクトリ」等を設定する必要はありません。

OpenCV と併用するので OpenCV の設定も必要です。EWCLIB 2.5 と OpenCV 3.4.2 の併用で特に問題はありませんでした。

サンプルコードその1

640×360 という,16:9 の解像度でキャプチャする例です。
CAP_PROP_FRAME_WIDTH での設定ではこの解像度はうまくいかないのですが,このコードだときちんと 640×360 でのキャプチャになります。

#include <opencv2/opencv.hpp>
#include "ewclib.h"

#ifdef _DEBUG
#pragma comment(lib, "opencv_world342d.lib")
#else
#pragma comment(lib, "opencv_world342.lib")
#endif

int main(void)
{
    const int cameraID = 0;
    const int width = 640;
    const int height = 360;

    int ret = EWC_Open(cameraID, width, height, 30, cameraID, MEDIASUBTYPE_RGB24);
    if (ret != 0) {
        fprintf(stderr, "EWC_Open failed.(%d: %d x %d)\n", cameraID, width, height);
        std::exit(1);
    }
    EWC_SetValue(cameraID, EWC_FOCUS, 0.0);
    cv::Mat_<cv::Vec3b> camera = cv::Mat_<cv::Vec3b>(height, width);

    cv::namedWindow("camera", CV_WINDOW_AUTOSIZE);
    for (;;) {
        EWC_GetImage(0, camera.data);
        cv::imshow("camera", camera);
        if (cv::waitKey(1) == 0x1b) { // ESC
            break;
        }
    }

    EWC_Close(cameraID);

    return 0;
}
サンプルコードその2

Logicool の C615 の詳細ページによると,このカメラは以下の解像度でビデオキャプチャできるとあります。

[4:3 SD] 320×240,640×480
[16:9 W] 360P,480P,720P,1080P

以下のコードは,これらの解像度で順にキャプチャをしていく例です。
なお,16:9の方の480Pというのは良くわかりませんでした(以下のコードに854×480を追加してみてもEWC_Open()が失敗します)。

#include <opencv2/opencv.hpp>
#include <vector>
#include <string>
#include "ewclib.h"

#ifdef _DEBUG
#pragma comment(lib, "opencv_world342d.lib")
#else
#pragma comment(lib, "opencv_world342.lib")
#endif

int main(void)
{
    const int cameraID = 0;

    const std::vector<cv::Size> capsizes = {
        // 4:3
        cv::Size(320, 240),
        cv::Size(640, 480),
        // 16:9
        cv::Size(640, 360),
        cv::Size(1280, 720),
        cv::Size(1920, 1080)
        // logicool c615 は上記全部OK
    };

    for (auto size : capsizes) {
        int ret = EWC_Open(cameraID, size.width, size.height, 30, cameraID, MEDIASUBTYPE_RGB24);
        if (ret != 0){
            fprintf(stderr, "EWC_Open failed.(%d: %d x %d)\n", cameraID, size.width, size.height);
            std::exit(1);
        }
        EWC_SetValue(cameraID, EWC_FOCUS, 0.0);
        cv::Mat_<cv::Vec3b> camera = cv::Mat_<cv::Vec3b>(size.height, size.width);

        std::string sizestr = std::to_string(size.width) + " x " + std::to_string(size.height);

        cv::namedWindow("camera", CV_WINDOW_AUTOSIZE);
        for (;;) {
            EWC_GetImage(0, camera.data);
            cv::putText(camera, sizestr.c_str(), cv::Point(40, 40), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 255), 2, CV_AA);
            cv::imshow("camera", camera);
            if (cv::waitKey(1) == 0x1b) { // ESCで次の解像度へ
                break;
            }
        }

        EWC_Close(cameraID);
    }

    return 0;
}

チェックマークのみのフォントファイルと,それをPrawnから使う

書類や帳票などをプログラムで自動生成させるようにすると捗ります。

ところで,事務書類では「チェックマーク」が要求されることがたまにあります。
(環境によっては見えないかも知れませんが「✔」のことです(「ゝ」を時計回りに90度回転させたような記号)。)

このような用途に私はRubyとPrawnを使っていますが,PrawnはUnicodeに対応したTrueTypeフォントも非常に簡単に扱えるため,チェックマークが含まっているフォントファイルさえ用意できればあとはそのフォントをPDF::Document::font した上で PDF::Document::draw_text メソッドで簡単に出せます。
このようなフォントとしては,MigMix 1Pなどがあります。

MigMix 1Pは非常に素晴らしいフォントなのですが,帳票によっては雰囲気にそぐわなかったりするため,1枚の帳票の中で他のフォントとMigMix 1P(のチェックマーク)とを切り替えて使ったりしています。ただ,チェックマークのためだけにフォントファイルを同じディレクトリに置いたりするのもちょっとどうかなと思っています1

そこで,「チェックマーク1文字だけが入っているフォントファイル」をMigMix 1Pから作りました2
たぶん需要は私だけだと思いますが,一応以下に置いておきます。
ライセンスは MigMix 1P に準じて,IPAフォントライセンスでお願いします。
migmix-1p-checkmark.ttf (zip)

Prawnで使うときは以下のような感じです3
このスクリプトを実行すると以下のようなPDFが生成されます。test-checkmark.pdf

#!/usr/bin/ruby
require 'prawn'
require 'prawn/measurement_extensions'

Prawn::Document.generate("test-checkmark.pdf",
                         { :page_size => 'A4',
                           :page_layout => :portrait,
                           :margin => 0, }){
  font "migmix-1p-checkmark.ttf"

  # チェックマークが直接入力できる場合はこちら
  draw_text "✔", :at => [10.5.cm, 25.2.cm], :size => 10

  # チェックマークが直接入力できない場合はこちら
  # "✔".codepoints.map{|v| v.to_s(16)} #=> 2714
  draw_text 0x2714.chr("UTF-8"), :at => [10.5.cm, 24.2.cm], :size => 10
}

YaTeXでタイプセット時に.dviと.logを削除する

近年のLaTeX環境においては出力はほぼPDF一択になったため,dviを保存しておく意味はほとんどなくなっているのではないかと思います。

YaTeXを使っている場合に,YaTeXでタイプセットした瞬間についでに .dvi と .log を削除してしまう設定が無いか調べてみたのですが,そういう機能そのものは無いかも知れません(調べが足りないだけかも)。

そこで以下のように現在はしてみています。

まず .emacs (や .emacs.el 等)に以下のように書いておき,

(setq YaTeX-dvipdf-command "~/bin/mydvipdfmx.sh")

さらに,$HOME/bin/mydvipdfmx.sh として以下のようなシェルスクリプトを置きます。

#!/bin/sh

dvipdfmx $1
rm ${1%dvi}.log
rm $1.dvi

echo "DELETED:" "${1%dvi}.log" "$1.dvi"

これで,YaTeXから C-c t d すると,PDF生成と同時に .dvi と .log は削除されます。
自分では latexmk よりもこんな感じの方がしっくりきます。