新型機ヤバス
今日はバイト先の伊丹まで行ってきました。Pascal君はプログラミング演習3でちょっとがんばってしまったため、発表会に駆り出される羽目になり、本来なら私もTAという立場上行くべきではあるのですが、しょーご一人で行かせるわけにも行かないので私としょーごの二人で行くことにしました。
今日の話は、バイト先の製品である金属板に文字を彫るための機械を制御するソフトウェアを以前納品したのですが、その機械の新型プロトタイプが出来ているので、それに併せてソフトウェアを対応させてほしい、という依頼の話を聞く……予定でした。
以前のソフトはブラックがその殆どを作っていて、ソースは引き継いだのですが、拡張が度重なるごとにソースの構造が汚くなっていて、製作者がもう次の拡張は拡張せずに1から作り直したほうが早い、とまで聞いていました。
さっそく新型機を見せてもらったのですが、LEDディスプレイなどが搭載されており、ビジュアル的に良くなったのではないかと思います。そして現場の人から4つほど修正してほしい点を聞きました。
- 文字の大きさのデフォルト値が以前は0になっていたが、今回から0はエラーとすることにしたのでデフォルトを1に変えてほしい。
- 処理スピードの問題上、今までは10個のデータを刻印機に送るたびに、2秒のスリープ時間を設けていたが、これを1個1個につき10〜20ms程度の待ち時間にしてほしい。
- 刻印のピストン部分を制御で動かす際に、向こうから作業完了の応答がある前に位置座標を取得する命令が出されるため、通信エラーが起こる。ちゃんと刻印機側からのACK応答を待ってから、位置座表を取得する命令を送ってほしい。
- 過去のソフトウェアのセーブデータと互換性が取れるようにしてほしい
なるほど、それでは早速検討してみます、と思って今日の仕事は意外と早く終わったな……と思ったのですが、この場で修正してほしいとのこと。それ以前に開発環境持ってきてないのですが……
結局バイト先から開発環境を借り、修正に入ることにしました。
1つ目の修正はそんなに難しくありませんでした。ブラックのソースも言うほど汚くはなく、該当箇所を簡単に見つけることができたのでちょっと直すだけで完了しました。他の部分への影響も心配だったのですが、そんなに酷くはなさそうです。
2つ目の修正は、とりあえず単純にSleep命令を発行してみたのですが、何故かエラー。話を聞くと、新型機は機能は増えたにもかかわらず、CPUの処理能力はダウンという意味不明な製品仕様となっていて、以前のように大量にバッファを送るとエラーを出してしまうらしい。
しかも、旧型機との互換性もとる必要があり、こいつは一定以上のバッファを送った後は何秒か待機しておかなければ、バッファを処理しきれずエラーを出してしまう。
……まったくどいつもこいつも。orz
結局現場の人との話し合いの結果、1命令ごとに10msずつ待機しつつ、かつ10個単位で2秒待機させる仕様になりました。結果送信にかかる時間が従来ソフトの2倍になりましたが、あまり使わない機能なのでエラーを出させるよりそっちのほうがマシという理屈の元、このような仕様になってしまいました。
3つ目の修正は停止命令を発行したときに、刻印機がACKパケットを待たずに座標取得を行うのが問題とのことなので、座標取得を行う前にwhile文を使ってACKパケットを待って見ることにしました。
……しかしACKパケットはいつまで経っても飛んでこないため、無限ループ……。
はじめは条件式が間違えていた程度の問題だったので、修正しては無限ループ、修正しては無限ループの繰り返しだったのですが、最終的に紐解くとトンでもない問題が残っていました。
この停止命令は刻印ピストンの移動命令を発行した後、停止する際に発行されるのですが、新型機はたまにこの停止命令を無視する。 それどころか、停止命令が発行される前の移動中に刻印ピストンが刻印できる境界外に行ってしまった時に、ACKパケットではなくNACKパケットを返すのだが、これをソフト側で検出できる術がない。そもそも製造側にとって使用者が素人であるほど境界外にピストンをはみ出させてしまうが、この処理自体が想定の範囲外らしい。
……というか、刻印機側のファームで対応してくれると非常に助かるんですけどね…orz
……そんな意見を現場の人と交えつつ、結局ACKパケットが戻ってくる時間にタイムアウト値を設け、その間に応答がなければ強引に次の処理に進むことにした。新型機もプロトタイプの段階なので、色々問題があるのだろう。
最後にデータファイルに互換性を取る、という話だったのだがこれが一番ややこしかった。そもそも私たちがこのソフトを作る前は別の人がソフトウェアを作っていたらしいのだが、この人が居なくなってしまったため、私たちに話が回ってきたので、ソフトウェアの仕様=プログラムという状態。現在のデータファイルはテキストデータに対して、過去のデータはバイナリファイルとなっている。
それだけでも厄介なのだが、さらに頭を悩ませることに、過去のデータと現在のデータの有効な設定値が違う。orz
昔の刻印機ならば、これを全て読み込んでも問題はなかったのだが、新型機は厳密な値のチェックをするようになったため、読み込もうとするとエラーを出すということがしばしばあった。
結局旧データで新データに収まりきらない有効範囲は切り詰めても良い、という話で決着がつき、なんとか折り合いがついたのでした。
しかし、いざテストする段になってやはりエラーが止まらない、修正してはピー、修正してはピー、というエラー音を散々聞いた後、結局原因は何だったかというと
向こうの人が教えてくれた新型機の仕様がそもそも間違っていた。orz
………
……
…
ぉーぃ。orz
旧セーブデータでは刻印できる文字列のサイズが40文字だったのに対して、新型機は32文字までしか入らないと教えてもらっていたので、旧セーブデータで32文字を超える文字列に対しては32文字までに切り詰めるように書いていたのだが、これでもエラー。
間違いと思われる箇所を探しては、向こうの機械にピーと怒られ、また直してはピー、と結局自分のプログラムに間違いは無いと、行き詰まってきたときに、ようやく機械側に問題があるのではないか、と疑い始めたのでした。
文字列を20文字まで削って入れると……。なんとエラーなしで成功。
それなら25文字当たりが怪しいかと入力すると、やはりピー。
それなら24文字……ピー。
21文字なら……?ピー。
もう一度20文字なら……成功。
32文字入るって教えてくれたのは、どこのどいつですか。orz
そりゃないょーorz
結局この件については刻印機側にバグがあるという報告をして、全部の仕事が終わったのは19時半。てっきり実際のユーザーからの意見・要望を聞きに行くだけだと思っていたので、この時間までやることになっていたのは予定外です。
帰りは、しょーごとヨドバシ8階でとんかつを食って帰りました。