c0プログラム教科書

c0プログラムはケーブルの幾何設計を目的としたもので、 いわゆるCAD (Computer Aided Design) システムの一つです。 普通のCADプログラムは、 座標等の幾何学的なパラメータをオペレータが入力しますが、 c0では人間にもわかる言語で記述した構造データを入力し、 プログラムがこれを解析して幾何学的配置を決定します。

このメカニズムは、c等のプログラミング言語と本質的に同じもので、 言語の設計や解析には、コンパイラの理論が使われています。 プログラムそのものは、筆者の仕事と個人的趣味の一つとして書いたもので、 長年、自分自身と自分が経営する会社でも使われてきました。 (注1)

以下の説明ではUnix正規表現(regular expression) を含む伝統的な記法を使います。(注2)

1. 概要

c0プログラムには3つの起動法があります。

  c0 [option] file	# 製図
  c0 [option] < file	# 画像データを作成
  c0			# 対話型動作
最初の構文はもっとも基本的なもので、 ケーブルの仕様を記述した file を読んで仕様書を作成します。 option の指定により作図方法や出力形式を選べます。

二番目の構文は印刷や表示用の画像データを作成するもので、 file に含まれる構造記述に基づいた作図だけを行います。

最後の構文はケーブル設計時の検討段階で使うもので、 構造データやコマンドを対話的に処理します。

描画ウィンドウはc0終了後にも残りますが、 描画ウィンドウの中でキーボ−ドの Escq を押せば消えます。

2. 入力ファイル形式

入力ファイルはコメント部制御部マクロ定義部構造記述部文書部から構成され、 下記の形式になります。 構造記述部以外は省略可能です。

[^// "comment_line"$]
..
[^% "control_line"$]
..
[^#"integer" "macro_definition"$]
..
^"cable_construction"$
..
[[^$]
[^"description_line"$
..
^'.'$
]]
ファイル先頭の "//" で始まる "comment_line" (コメント行) は無視されます。必要がなければ省略できます。

次の % で始まる "control_line" (制御行) は作図や出力画像の形式を指定します。

続いて先頭が # の直後に数字(マクロ番号が続く "macro_definition" (マクロ定義行) 行はマクロ定義行で、 空白に続く文字列の最初から行末までが、その内容になります。 (例 - "#1 7/.12*.8)

その後の "cable_construction" (構造記述部) がケーブルの構造を記述する部分で、複数行に分けて書くことができますが、 このプログラム固有の文法と言語を使います。

最後の "description_line" (文書部) は文字による自由な記述に使える部分で、 BOM(部品表)、仕様、注記事項などの描画に使います。

例えば、BOM(部品表)の自動描画をやめて、部品表の場所に表示させるとか、 いろいろな使いかたができます。 BOMは製図(drafting)用語で Bills of materials (部品表) を意味します。

この部分に . だけしか書かれていない行 (^'.'$) が出てくると、 文書部の終りと見做しますので、これ以降の行は全て無視されます。 . がなければ最後まで文書部と見做します。

3. ケーブル構造データの記述

ケーブル構造データは、 このプログラムのために開発したケーブル記述言語(cable description language)で、 人間にとっても読み易く、 しかもコンピュータで解析できるように設計されています。

ケーブル(cable)はフィラメント(filament) をまとめて(laid together)取扱を容易にしたものというのが妥当な定義で、 電線の場合、フィラメントとしては銅線などの導体、補強や充填材に使う繊維製品、 プラスチックやガラスで作ったモノフィラメントなどが使われ、 集める方法としては集合、撚、横巻、編組、接着、押出といった加工技術を使います。

このプログラムの設計では、 ケーブルを構成する単一材料をエレメント(element/要素)と呼び、 エレメントを同心円状に集めた構造をコア(core/芯)と呼んでいます。 コア自体を同心円状に集めたものもコアになりますから、 構造から見たケーブルは自分の定義自体に自分自身を使うしかないという 再帰的(recursive)構造です。

3.1. 用語と表記法

以下の説明では、コンピュータ言語の説明で良く使われる記号のいくつかを使用します。

  [ ]	   で囲まれた部分は省略可能です。
  ..       は、必要に応じて繰り返しが可能であることをあらわします。
  a|b|c    は、 a か b か c のいずれかを使用すべきであることをあらわします。
  文字 '|' はor(または)の意味になります。
*, +, -, (, ), [, ], ^ などの演算子は被覆、結合、配置 、繰り返しをあらわす記号で、その前後に空白があってもなくても、 独立した記号として扱われます。 この種の記号は、コンピュータの分野では、token(トークン)と呼ばれています。 外径など構造を表す数値、 材料記号などの単語(word)は空白文字で区切って、 他の文字と区別がつくようにしなければなりません。 構造記述を複数行にわけて書く場合は *, +, -, (, ), [, ], ^といった token 直前で改行してください。

数値の直前につける英文字をprefix(プレフィックス/接頭語)、 数値の直後につける英文字をpostfix(ポストフィックス/接尾語) と呼んでいます。 これらは数値に特別な意味を与えたり通常とは違う意味を与えるために使用します。

3.2. エレメント

エレメント(element)は、ケーブルを構成する、 これ以上分解できない最も基本的な要素です。

3.2.1. 1次元円形エレメント

  [t]数値[t] [材料記号 [材料記述]]
数値の前に置かれた文字をプレフィックス(prefix)、 後に置かれた文字をポストフィックス(postfix)と呼びと呼びますが、 これらは数値の意味を限定します。

プレフィックス t は被覆材料がチューブ構造(tubing)か 充実構造(full extruded)かの区別に使う場合と、 導体材料が繊維を芯にした横巻構造であることを示すために使う 場合があります。

ポストフィックス t があれば厚さ(thickness)、 なければ外径(diameter)です。

ポストフィックス? の場合は円を点線で描画して、 サブアセンブリなど他の図面を見なければならない時などに使います。

材料記号は自由に決めることができますが、 社会的・慣習的に使われているものを優先すべきで、 次のような記号が良く使われます。

  A:	銅線 (annealed copper)
  TA:	錫メッキ軟銅線 (tinned copper)
  PVC:	塩化ビニル樹脂 (polyvinyl chloride)
  PE:	ポリエチレン樹脂 (polyethylene)
  CPE:	発泡ポリエチレン樹脂 (expanded polyethylene)
  XLPE:	架橋ポリエチレン樹脂 (cross linked polyethylene)
  PU:	ポリウレタン樹脂 (polyurethane)
  TPE:	熱可塑性エラストマー (thermoplastic elastomers)
例えば、
  0.18 A	直径 0.18mm の軟銅線
  0.6t PVC	厚さ 0.6mm のPVC被覆
材料記述には、空白文字を含んでいてもかまいません。 材料計算等、作図システム以外では書き方が厳密に規定される場合があります。

すべてのエレメント記述で、 材料記述の中では "//" 以降行末までがコメントとして無視されます。

なお、この版では材料記述は解析対象にしていません。 仕様書に必要な記述にも使えますし、 技術計算、原価計算、生産管理情報などの機能を組み込む場合にも使えます。

3.2.2. 2次元エレメント

  [e]数値x数値 [材料記号 [材料記述]]
プレフィックス e は、外形が楕円形であることをあらわします。 数値の途中の置かれた文字 x が意味する内容は分脈によって異なり、 円形ケーブルで使われた場合はチューブ、 フラットケーブルのコア(core)で使われた場合はweb(ウェブ)を意味します。 また、フラットケーブル全体の被覆だと楕円形のジャケットになります。 例えば、
  2x3		内径 2mm 外径 3mm のチューブ
  3x.5t		内径 3mm 厚さ 0.5mm のチューブ
  ?x.5t		厚さ 0.5mm のチューブ
  [1-3x0.2-1]	幅 3mm 厚さ 0.2mm のウェブ
  [1^3]*5x3	楕円形ジャケット
被覆材としてのチューブは内径を ? で指定すると、 その時点のコア径と解釈します。

3.3. 集合記述子 '/'

集合記述子 '/'は、エレメントを最小外径の円形配列にまとめます。

  素線数/素線径		集合導体, 横巻
  t数値/素線径		繊維上に素線を横巻した導体
  p数値/素線径		鋼線上に素線を横巻した導体
  打数/持数/素線径	編組
  群数/素線径/素線数	ロープより導体
集合記述子 / をひとつだけ含む構造は、 コア材として使われた場合は集合構造(bunching)、 被覆材として使われた場合は横巻構造(serving)と解されます。 作図を目的とした記述では、素線数、群数、打数、 持数等を省略することが可能で、 その場合、数値の代わりに文字 ? を使います。 例えば、
  12/0.18 A	直径 0.18mm 軟銅線 12 本より集合線
  .. * 45/0.12 A	直径 0.12mm 軟銅線 45 本の横巻
  .. * ?/0.10 A	直径 0.10mm 軟銅線 による横巻
集合記述子 / を2つ含む構造は、 コア材として使われた場合はロープより(lope_lay)構造、 被覆材として使われた場合は、編組構造(braid)と解されます。 例えば、
  7/19/.2 A		直径 0.2mm 軟銅線 19 本より 7 群のロープ撚
  .. * 16/3/.12 A	直径 0.12mm 3 本持ち 16 打の編組
  .. * ?/?/0.14 A	直径 0.14mm 軟銅線 による編組

3.4. 被覆演算子 '*'

被覆演算子 * はエレメント上の被覆(covering)をあらわします。 例えば、

  7/.12 TA * 0.8 PVC
  7/.12 TA * 0.8 PVC * ?/.12 TA * .33t PVC
最初の例は 0.12mm 7 本の集合線に 0.8mm 径の PVC 被覆、 二つ目は、その上に 0.12mm 錫メッキ銅線の横巻をして、 最後に 0.8mm 厚の PVC ジャケットをかぶせた構造です。

被覆ではエレメントの中心位置は変化しません。 これがコアの構造的な意味です。

3.5. 撚合わせ演算子 '( .. )' と配列演算子 '+', '-'

撚合わせ演算子 ( .. ) は、 エレメントを指定された配列順で外接円が最小になるように配置します。 エレメントの配列順と配置位置は、 配列演算子 +- で指定しますが、 + で結合されたエレメントは外接円に接して配置され、 - で結合されたエレメントは、内接円に接して配置されます。 例えば、

  (13 + 6 + 7 + 5)
  (8 + 8 + 8 - 3 + 5 + 5 + 4)
  ((1^2) + 2 + 2)
2つ目の例では、外径 3mm のエレメントは、 隣の 8mm と 5mm のエレメントの内側に配置されます。 3つ目の例では、外径 1mmm のツイステッドペアと、 外径 1 mm のエレメントを円形にまとめています。 撚合わせ演算子を使うときは、 最も太いエレメントを最初に書くようにしてください。

3.6. 繰り返し演算子 '^'

繰り返し演算子 ^ は直前のエレメントを、 指定された数値だけ繰り返す省略記法です。 例えば、

  (7/.12 TA * 1.0 PVC ^ 3) * ?/.12 TA * .7t PVC
はシールドとジャケットを持つ3心ケーブルになります。

3.7. 外周配列演算子 '*( .. )'

外周配列演算子 *() の対は指定された順序でエレメントをコアの外周に配置します。 例えば、

  (7/.18 * 1) *(7/.18 * 1 ^ 6)
  (1^3)*(1^12)*.8t

3.8. フラット配列演算子 '[ .. ]'

フラット配列演算子 [] の対は、 指定された順序でエレメントを直線上に並べます。 例えば、

  [7/.16 TA * 0.95 PVC ^ 10]
は、10心のフラットケーブルです。フラット配列で、結合演算子 - を使うと、 ウェブをあらわします。例えば、
  [1 - 1x0.2 + 1 - 1x0.2 + 1]
は、外径 1mm のエレメント3つを、幅 1mm 高さ 0.1mm のウェブで結合します。 -+ にするとチューブと解されますので注意してください。

3.9. フィラー(介在)記述子 '%'

介在(filler)はケーブルのコア間の隙間(gap)を埋めるエレメントで、 繊維やモノフィラメント、チューブなどが使われますが、 ここでは繊維を使った介在だけを考えています。

コア集合の内側の隙間を埋めるのが内介在(inner filler)で、

  -%
と記述、 コア集合の外側を埋める外介在(outer filler)は
  +%
と記述します。

例えば、

  (12/.18 * 1.5 ^ 5 - %) * .8t
は、内介在の5心ケーブルになります。

3.10. 位置指定子 '&'

  &element
位置指定子 & は、 添え線(drain wire)のような場所を取らないエレメントの位置指定に使います。 作図上では、単なるマーカーを表示します。 例えば、
  7/.12 TA * .8 PE * .3t CPVC & 7/.12 TA * .4t PVC
は、0.3mm 厚の導電性 PVC 被覆層に 7/.12 TA より線を併用するといった場合に使えますが、 この場合は 7/.12 TA を作図することもできます。

細い標識糸を入れる場合などは & を使うほうがよいでしょう。

3.11. マクロ置換 macro processor

マクロ置換は文字列の置換機能ですが、 同じ構造を複数の場所で書かなければならないとき、 記述を簡単で見通しのよいものにする目的で使います。 例えば、

  #1 7/.12 * .8
  #2 12/.12 * 1.0
  (#1+#2^2)*?/.12*.6t
先頭が「#」で始まる行はマクロ定義行として解釈され、 # に続く数字がマクロ番号になります。 マクロ番号が連続している必要はありませんが、 0 番品番表示に予約されていて、 仕様書の製品名として表示されます。

最初の空白以降行末までの文字列が内容と解釈され、 構造記述中に # に続く番号が出て来ると、 その番号の定義済マクロの内容で置き換えられます。

マクロの後方参照はできませんが、 マクロ定義中で定義済みマクロを使うことはできます。

通常はケーブル記述中で行の先頭にマクロ展開の # を書く必要はないのですが、 どうしても書きたいときは、先頭に空白文字 ' ' を入れて、 その後に # を続ければ対応できます。

3.12. コメント

材料記述中では // 以降行末まではコメントとして無視されます。

4. 作図機能

作図機能は下記の4つに分かれていて、それぞれの選択と組み合わせにより、 かなり自由な図面が作れます。

断面図はケーブル断面を描画するものですが、 全要素を描画する全体図と、 ケーブル全体の被覆だけを描画して、 サブアセンブリ(Sub-asy)を点線円とサブアセンブリ番号で描画する 組立図が選べます。

バルーン全要素につける場合と、 ケーブルの全体被覆と 組立部品としてのコア単位に付与する方法を選べます。 後者は要素数が多くバルーンが重なってしまう場合に使います。

BOMはバルーンに合わせて作図データから自動生成する方法と、 Descriptionを使って自由に作成する方法が選べます。

Descriptionは自由な記述ができるテキストデータで、 部品表、規格や検査項目、仕様、細部の説明などに使います。

5. 制御行オプション control line option

c0が読み込む入力ファイルの % で始まる制御行(control lin)では下記の記述ができます。

  winW,H	window の幅を W dot, 高さを H dot にする (初期値は 640x800)
  offX,Y	描画中心を (X,Y) に移動 (初期値は 0.15,0.45)
  magR		図面の拡大率を R にする (R は正実数 初期値は 0.0)
  -bal		バルーンを描かない (初期値は描く)
  -bom		バルーンと部品表を描かない (初期値は描く)
  crop		周囲の余分な空白を切り取る
  od		O.D. (overall diameter) を描画する
  png		出力画像を PNG 形式にする
  gif		出力画像を GIF 形式にする
  tif		出力画像を TIF 形式にする
  xwd		出力画像を XWD 形式にする (初期値)
  asy		組立図を描画(サブコアを点線で描く)
  Asy		詳細組立図を描画(サブコアを詳細に描く)
  N		部品図 (N = 1, 2, 3, ...)

表示画像のサイズ(window)はドット単位で -win300,400 と指定すれば、 幅 300 dot、高さ 400 dot の画像になります。

オフセット(off)は画面中心を(0,0)として、 そこからの移動量をウインドウ底辺の長さを 1 とした規格値で指定します。 画面が長方形の場合は底辺に接する正方形です。 ケーブルの描画中心位置の初期値は画面右上の (0.15,0.45) ですが、 「c0 < data」で起動した場合は画面中心の (0,0) になります。 オフセットはケーブルの作図位置にのみ作用し、 description_line の文字描画位置には影響を与えません。

拡大率(magnifier)は実寸を何倍に拡大して描画するかを決める値ですが、 ディスプレイの dot pith に依存するため正確ではありません。 0 を指定すると初期値(10.0)になります。

PNG, GIF, TIF 形式の画像は標準出力に出てきますから、 リダイレクト(redirect)でファイルに書き出します。 XWD 以外の画像作成では convert コマンドが使われていますので、 ImageMagic をインストールしておく必要があります。

crop は PNG, GIF, TIF 形式の画像作成でのみ機能し、 X11 表示の場合は無視されます。

asyAsy はケーブル全体のカバリング・エレメントだけにバルーンをつけて、 組立に使った個々の内部コアは単一部品として扱うもので、 いわゆる組立図(assembly drawing)になりますが、 これは全てのエレメントにバルーンをつけると多すぎる場合に使います。

asy の場合は個々の内部コアを点線の円で描き、その中にコア番号を描きますが、 Asy の場合はすべてのエレメントを描画し、 その中心からバルーンの引出線を引きます。

コア番号の数字は指定されたコアの部品図になります。

コア数が非常に多い場合は複数の作図データを用意してください。

6. コマンドライン オプション

c0プログラム起動時のコマンドライン・オプション(command line option) では、下記の指定ができます。

  -winW,H	window の幅を W dot, 高さを H dot にする (初期値は 640x800)
  -offX,Y	オフセットを (X, Y) にする (初期値は 0.15,0.45)
  -magR		描画倍率を指定 (R は正実数 0,1,2,..)
  -png		出力画像を PNG 形式にする
  -gif		出力画像を GIF 形式にする
  -tif		出力画像を TIF 形式にする
  -xwd		出力画像を GIF 形式にする
  -magM		描画倍率を M にする (R は正実数 初期値は 0.0)
  -crop		周囲の余分な空白を切り取る (初期値は切り取らない)
  -bal		バルーンを描かない (初期値は描く)
  -bom		バルーンと部品表を描かない (初期値は描く)
  -notes	"description_line" を描かない (初期値は描く)
  -od		O.D.(overall diameter/外径) を描画する
  -asy		組立図
  -Asy		詳細組立図
  -N		部品図 (N はコア番号)
  -lang		表記を英語にする (初期値は EUC-JP)

7. 対話モードのコマンド

対話モートで起動した場合は、 > のプロンプトを出して、利用者の指示を待ちますが、 下記のコマンドを受け付けます。

  -b		BOM を表示しない
  +b		BOM を表示する (初期値)
  f [file]	構造データを file から読み込む
  mR		描画倍率を R にする (R は実数、初期値は 0 ないし 10)
  p[a|A|N]	描画する
		  a - アセンブリ図面を描画
		  A - 詳細アセンブリ図面を描画
		  N - 部品図面を描画 (N はコア番号/正整数値)
		      N を 0 にすると標準図面に戻る
  q		終了
  S file	外側の余分な空白部分を削除して "s file" を実行
  s file	画像データをファイルに書き込む
  :[a|e|f|d|m]	内部データを表示 (デバッグ用)
		  a - asytab[]
		  e - elmtab[]
		  f - figtab[]
		  d - densitytab[]
		  m - 原材料テーブルを表示
		  特定のデータを指定しない場合は原材料テーブル以外の全て
  ! comand	/bin/sh を起動して command を実行

これ以外の入力データはケーブル記述と見做して、構文を解析し作図します。 ケーブル構造の記述では *, (, ), +, -, [, ], ^token直前で改行できますので、 構造データの入力終了を理解させるために、 キーを続けて2度押してください。 プログラムを終了する場合は q キーか Ctrl-D (EOF - End Of File) を押します。

簡単な配置確認、寸法計算、材料計算などは対話型で起動するのが良いと思いますが、 作業データを残す場合は他のウインドウでエディタを起動してデータを作成しながら、 対話型で起動した cf コマンドでそれを読んで確認すると効率的です。 "f file" の2度目以降の読み込みでは file を省略することができます。

画像をファイルに出力する場合は、 ファイル名に拡張子 .gif .png .tif .xwd が付加されていれば そのフォーマットで出力します。

8. CL0 (Cable description Language-0) の構文

CL0 の基本的な構文を yacc の BNF で定義すると次のようになります。

実際のプログラムでは構文解析の各段階でのアクションや、 エラー処理のための構文が追加されますから、 もっと複雑になります。

%token FIRSTTOKEN
%token ELEMENT '(' ')' '[' ']'
%left  '+' '-' '*'
%right '^' '&'
%token LASTTOKEN
%%
cable	:  /* nothing */
	| core
	| flat
	;
core	: ELEMENT
	| core '*' ELEMENT
	| core '*' '(' core ')'
	| core '+' ELEMENT
	| core '+' '(' core ')'
	| core '-' ELEMENT
	| core '-' '(' core ')'
	| core '^' NUM
	| core '&' ELEMENT
	| '(' core ')'
	;
flat	: '[' core ']'
	| flat '*' ELEMENT
	;
%%

9. 注

9.1 注1 - c0の言語と構文解析

このプログラムの歴史は長く、 最初に書き始めた 1977 年版では再帰降下型(recursive descend parser)構文解析を使う LL(1) 文法で設計しました。 その後Unixが使える時代になった時点で個人用については、 yacc(1) を使うように書き換えた LALR(1)文法になっています。

言語と構文はケーブル固有の再帰的構造と製造整備の性格を反映していて、 私自身はCL0(Cable description Language-0)と呼んでいました。 この CL0 言語を解析して描画する最初のプログラムをc0と呼んだため、 今でも同じ名前を使っています。

実際に仕事で使っていたバージョンは原価計算や電気設計などの機能や、 日程計画、資材計画などの生産管理が必要とするデータを生成する ポストプロセサなどを含むのですが、 こういった部分は各社固有の手法になりますから、 この公開版ではすべて削除して、 独自の機能を追加しやすいように整理しました。

9.2 注2 - この解説の記法

  ^ - 行の先頭を意味する
  $ - 行末を意味する
  'c'- ASCII 1 文字
  ".." - '"' で囲まれた部分は空白を含む一連の文字例
  [ .. ] - '[' と ']' で囲まれた部分は省略可能
  .. - 直前のフォーマットが続いてもよいという意味

平林 浩一 2019-01