Pythonで機械設計を自動化した話
仕事でとある機械を設計する仕事をしていました。
3年前ぐらいに設計をPythonで自動化した経験について書きます。
入社したときから設計に配属され、ずっと設計をしていました。
内製の多数の設計ツールを駆使して、手作業でひたすら計算して、設計クライテリアを満たす解を探したりして、最終的に2次元CADを作成します。
ツールだけ見るとかなり古臭いです。実際、インターフェースだけは変わったものの、10*n年前から使われているツールが当たり前という環境です。
手作業での作業は楽しくはあり、設計しているという実感を得られるものの、非常に非効率です。
入社当時は長時間残業が当たり前。
設計者は設計以外の雑用にも追われ、設計に取られる時間も限られています。
そんな中で手作業で計算をしているため、設計の最適解は当然のように得られず、もどかしさを感じていました。
設計というのは、ある制約条件下で何らかの最適解を求める作業です。
開発品で初めての製品を設計するならいざ知らず、類似品を多数設計するのであればプログラムで自動化して最適化すべきものです。
入社N年目に当時の課長に自動化を専任でやらせて欲しいと直訴し、専任でやらせてもらえることになりました。
(なぜあっさりやらせてもらえたのかという背景があるのですが、それはまた別の話。)
私の設計業務は基本設計だったので、内製の計算ツールを複数使い、形状を決定して、2次元CADで計画図を作成するのが主な業務です。(他にも雑務的な仕事は数知れず)
概算計画でも、計算慣れしているベテラン勢で1週間ぐらい、そこまで慣れていない若い人では2週間程度がかかるものです。
実際にはこのあとデザインレビューを行い、正式に図面や図書を発行する流れとなり、案件にもよりますが1ヶ月半~2カ月ぐらいかけるのが普通です。
受注の引合いがあったときの見積り設計は期限が短く、数日で概算設計を終わらせる必要がありました。入札に関わる重要なプロセスにも関わらず、あまり検討をしていない設計で応札するということも多かったです。これでは受注も遠ざかるばかりで、これは改善しなければ、という気持ちでした。
具体的な話
さて、どういう設計を手作業でしていたのかを説明していきます。
設計ツールはいろいろあって
のような感じ20個近いツールがあります。
さらにExcelマクロから呼び出すDLLもあります。
GUIと書いているものは、GUIはフロントエンドだけで、実際にはサーバのFortranプログラムを呼び出しています。
具体的にはGUIから入力テキストファイルを出力し、それをサーバにアップロードし、Fortranプログラムを走らせ、出力されたテキストファイルをダウンロードしています。
Excelシートでの計算ツールや、Excelのマクロを使ったツールがあるのは、他の設計現場でもよくあるのではないでしょうか?
実際の設計では例えば以下のような作業をします。
- 計算ツールAの出力から数値をぬきだし、計算ツールBに入力する
- 計算ツールCの出力のある数値が制約以下になるような入力を探す
サーバのプログラムを走らせたり、Excelを使ったりと設計ツールが多岐に渡りますが、これらを自動的に走らせるのはPythonが向いています。C++とかに手を出すと死亡します。
既存の設計プログラムには一切手を加えず、Pythonでプログラム間の操作を仲介するような方針にしました。
Excelの操作の自動化
Excelの操作にはPythonのwin32comモジュールを使いました。
他にも色々なモジュールがあるようですが、特に比較検討をしたわけではないので、今はもっと良いものがあるのかもしれません。
ほとんどExcelマクロのVBAを書くのと同じ感覚で書くことができます。
PythonからExcelマクロを呼び出すこともできます。
Excelファイルを開いて、セルに数字を入力して、マクロを走らせて、数値を読みだして、ファイルを閉じる、といった作業がPythonから出来ます。
なお注意点として、PythonプログラムからExcelを操作している間にExcelを触ると、エラーで終了してしまうのが地味に不便でした。
サーバプログラムの呼び出しの自動化
これは完全に職場固有の問題なので、あまり参考にならないと思います。
多くの設計ツールがFortranプログラムとしてサーバ内にあるため、GUIプログラムからサーバのプログラムを呼び出して、出力をダウンロードするという処理になっていました。
ここをPythonから自動で行うには、主に以下の3つの関数を実装することになります。
- 計算の入力ファイルをファイルに書き出す関数
- 計算を走らせる関数
- 出力ファイルを変数に読みだす関数
計算はftpでアップロード、ダウンロードして、社内ネットワークなのでtelnetで入ってコマンドを叩く方法としました。これらは全てPythonのモジュールでできます。
出力ファイルを読み込むのは、欲しい数値が固定位置にあるとは限らないので、正規表現で読みだすことにしました。Pythonには正規表現が扱えるモジュールが最初から使えるので便利です。
最適化
設計計算をしていると、例えば出力されたある値が最小(最大)になるような入力値を探したいということがあります。
地道にループで書いてもいいのですが、scipy.optimizeという最適化に使えるモジュールがあるため、これが使えそうな処理であれば使うと楽です。
ログ出力
自動化プログラムを開発するうえで、ログ出力をするとデバッグに便利です。途中でエラーで止まったときにどこに不具合があるか特定しやすいです。
デバッグだけではなく、計算過程を出力しておくことで、あとでなぜその設計になったのかが確認できます。
loggingモジュールがあるので、これを使います。ちょっと使い方にコツがいるので調べてね。
ほかにもデバッグとしては、エラーで止まったときに、「import pdb; pdb.pm()」をやったりとか、あやしそうな箇所で「pdb.set_trace()」したりとかが有効です。
ログの一種としてグラフで経過をわかるようにもしました。matplotlibというグラフを表示するモジュールがあるため、非常に簡単にグラフを表示することができます。
AutoCADの作図の自動化
AutoCADでの作図にはAcadRemoconというフリーソフトを用いました。これはActiveX DLLで、AutoCADに作図コマンドを送ることができます。このActiveX DLLをPythonから呼び出すことで、AutoCADに作図コマンドを送り作図を行うことができます。
私の環境では問題なく動いているのですが、新しいバージョンのWindowsやAutoCADだとサポートされていないようなので、動くかどうかは保証できません。
もしAcadRemoconが使えないような環境であれば、AutoCADの作図コマンドをファイル出力して、ユーザがAutoCADのコマンドウィンドウに貼り付けることで作図できると思います。
作図コマンドで出来ることに限るため、あらゆる作図処理が出来るわけではないと思いますが、線や円弧を作図したり、レイヤーを変えたり、簡単な寸法を入れるぐらいであれば問題なく作図できます。
外部のdxfファイルにある図形を貼り付けるようなこともできます。これはおそらく線分や円弧などのエンティティ毎に貼り付ける操作を実装するしかないはず。少なくとも私はそれ以外は知りません。
このあたりは複雑な処理を行いたければ、AutoCAD.NET等でDLLを開発して、AutoCADからロードすれば出来ますが、資料が少ないのが難点ですね。和書が1冊出てた記憶です。
何が出来たのか
自動化プログラムを開発することで、1週間ほどかかっていた計算が30分ほどで出来るようになりました。
実際のところ、設計自体が複雑でパラメータも多いため、全体を最適化までは出来なかったのですが、全体をワンフローで流し、一部のプロセスに限っては最適化することはできました。
副次的な効果として、以下のようなこともできました。
- 設計ルールが明文化されていない箇所が少なからずあり、ルールを決めることができた(というか決めなければ進められなかった)
- 自動化すると計算ミスが無くなった(もちろん最初の検証作業は必要。検証作業で大量のバグが見つかります)
- 自動化すると人の技量による差がなくなる(ベテランも新人も入力が同じなら同じ答えが出てくる)
なぜ開発がうまくいったのか
この手のプロジェクトは失敗がよくあると思います。
今回は開発がうまくいった例なのですが、一番の理由は設計をよく理解している人間がプログラムを書いたことです。
プログラムを動かして結果やインターフェースがイマイチだったときには、すぐに仕様を変更することができます。
これが外注に頼むと仕様を作りこむだけで数カ月、開発に数カ月、それだけかけてプログラムを動かしてみると期待していた結果が出てこないということになっていたはずです。こうなると追加で開発するために数百万がかかってきます。
設計にもよりますが、今回のような複雑な設計の場合、最初から仕様を固めるのは非常に難しいため、開発しながら考え、柔軟に方針転換ができます。新たなアイディアが思いついたときにも、すぐにプログラムを書き手元で試せます。
結論:設計者にプログラムを書かせよう
おしまい。