PLCの蛇? 簡単!

こんにちは、ハランジャー!



最近、「産業用プログラミング」のトピックが十分に扱われていないという不満がありました。 私はそれを修正しようとします。

わかりやすくするために、シーメンスs7-300ファミリーのコントローラー用の古典的なヘビの書き方を考えます。



画像



面白くなったら-猫へようこそ。

警告-アセンブラーのような言語の写真と多くのコード!



プログラム全体は組織ブロックOB1で実行され、2つの機能ブロックFB10およびFB11で構成されます。これらの機能ブロックにはインスタンスデータブロックDB10および11があります。







競技場自体の10x10セルは、10x10バイトの2次元配列です。







私たちの蛇の働きのために、小さな問題を解決する必要があります-時間内に生じる正確な衝動が必要です。 「Blinking Beats」を使用できます。これはコントローラーの組み込み機能ですが、マーカーと構造を持つ独自のパルスジェネレーターFB10を作成します。



一時変数OB1には多くの興味深いものがありますが、今回は前回のプログラムサイクルの時間が必要です。 この間、コントローラーは発言した内容をすべて「ダイジェスト」し、出力に値を発行してから入力を読み取ります。 それはかなり高い精度で測定され、私たちはそれを信じています。







累積時間が長くなるか等しくなるとすぐに、パルスが生成され(1サイクルのみ動作します)、それから1000を引きます(突然1000を少し超えるため、ゼロにすることは不可能です)。勢い。







これらのパルスから、5秒などの大量のデータを追加するのは非常に簡単です。







数分、数時間もできますが、それは別の話です。



同じエッジ変数を2回使用することはできません。プログラムロジックでエラーをキャッチするのは非常に困難です。



今では、ヘビ自体の機能ブロックの番です。







入力変数は、左、右、上、下、および開始コマンドです。

コントローラーとディスクリート入力モジュールが手元にある場合、これらの変数入力に入力を掛けることができます。これらの入力にはボタンを固定せずに取り付けます。 本格的なスロットマシンを入手してください。 特別な欲求があれば、電球でアレイを作ることができますが、このためにすぐに解雇されます=)



最初の例は、左移動コマンドです。







提出した場合、右に移動することはありません。これはこのサイクルでのみ発生します。その後、以前のコマンドをすべてリセットし、左に移動することを発表します。



次に、ゲームが開始されると、配列を解放します
#snake.start

FP#frnts.pos5

Jcn完了

R#snake.gameover

L 0

T#ルーパー

OPN「大規模」

LAR1 P#0.0

ループ:L #looper

L 100

> = I

Jc完了

L 0

T DBB [AR1、P#0.0]

+ AR1 P#1.0

L 1

L#ルーパー

+私

T#ルーパー

ジュループ

完了:NOP 0



0から99番目の要素までゼロで埋めるだけで解放されます。 事実、STLでは間接アドレス指定で2次元配列を扱うことができないため、この配列を0から99番目の要素までの1次元要素として表します。



最初に、蛇の頭を要素9.5に直接アドレッシングして転送し、長さを2にし、クロールするコマンドを与え、ゲームオーバーをリセットし、競技場のランダムなポイントに食べ物を投げ出すコマンドを与えます。



ゲーム開始
#snake.start

FP#frnts.pos6

Jcn strt

LP#95.0

T #coordinate

L 5

T "大規模" .x [9] .y [5]

L 2

T#tail_cut.lenght

S#move.up

R#snake.gameover

S#random.set_food

strt:NOP 0



次に、ヘビの餌を生成する必要があります。 告白すると、生成アルゴリズム自体は、最初のGoogleリンクの1つである「plc for good」サイトで見張られていました。



これは、コントローラーがシステム時間のミリ秒をカウントするという事実から成ります。 この数を取得し、ランダムな数に追加し、超過分を破棄すると、0から特定の値までの擬似乱数ジェネレーターが取得されます。



さらに、XとYがランダムに抜けた場合、それらを取得して配列要素の数を計算します。 Xに沿った各ステップは、要素の次の行、つまり10に移動する必要があることを意味し、Yに沿った各ステップは、0要素から1移動することを意味します。



その結果、配列要素X [4] Y [7]は、1次元配列の47番目の要素になります。 私たちは彼にステータス7-食べ物を与えます。



要素がビジーの場合、ジェネレーターを再起動します。



食品発生器
#random.set_food

FP#frnts.pos7

JCNフード

repl:CALL "TIME_TCK"

RET_VAL:=#random.tick

L#random.tick

AD DW#16#1F

T#random.rot

L#random.tick

L#random.rot

RLD

L#random.tick

XOD

ABS

L 10

MOD

T#random.x

CALL TIME_TCK

RET_VAL:=#random.tick

L#random.tick

XOD DW#16#1E12F

T#random.rot

L#random.tick

L#random.rot

RLD

L#random.tick

XOD

ABS

L 10

MOD

T#random.y

L 0

T#ルーパー

LAR1 P#0.0

posx:L#ルーパー

L#random.x

> = I

Jc next

LP#10.0

+ AR1

L 1

L#ルーパー

+私

T#ルーパー

ジュポス

次:L 0

T#ルーパー

花束:L#ルーパー

L#random.y

> = I

JC poss

LP#1.0

+ AR1

L 1

L#ルーパー

+私

T#ルーパー

ジュ・ポージー

poss:OPN "massive"

L DBB [AR1、P#0.0]

L 0

== I

JCN REPL

L 7

T DBB [AR1、P#0.0]

食品:R#snake.omnomnom

R#random.set_food



食物の排出が成功すると、ヘビは動き始めます。左への動きに基づいたアルゴリズムを考えてください。



左に移動
「db_pulsegen」.two_sec_pls

#move.left

JCN ext1

OPN「大規模」

LAR1 #coordinate

Tar1

LP#10.0

MOD

LP#0.0

== D

JCN ok_1

S#snake.gameover

ジュグモフ

ok_1:TAR1

LP#1.0

-D

Lar1

OPN「大規模」

L DBB [AR1、P#0.0]

L 0

== I

JC NUL1

L DBB [AR1、P#0.0]

L 7

== I

Jc eat1

セット

S#snake.gameover

ジュグモフ

eat1:SET

S#snake.omnomnom

L#tail_cut.lenght

L 1

+私

T#tail_cut.lenght

nul1:L 3

T DBB [AR1、P#0.0]

TAR1 #coordinate

ext1:NOP 0



このアルゴリズムでは、すぐにいくつかのチェックを実行します。 10で割る-残り-現在の要素の行の数を取得します。 左に移動すると、ゼロ要素になり、ゲームの終わりになります。







移動の仕方で食物以外のものがある場合、同じことが起こります。 あなたが食べ物につまずいたら-あなたがちょうど食べたビットをコック、それはジェネレータを起動し、テールを1だけ伸ばします。



次は最後のアルゴリズム-テールカッターです。 彼は最後の座標を基準にして、この座標でコマンドを読み取り、蛇の頭から尾まで逆の順序で進みます。 セルが長さを超える場合-値をゼロにして削除します



尾を切る
#snake.start

AN#tail_cut.uncut

「db_pulsegen」.two_sec_pls

JCN NOP

L 0

T#ルーパー

L#座標

T#tail_cut.tmp_coordinate

lpct:L#ルーパー

L#tail_cut.lenght

>私

Jcカット

L#tail_cut.tmp_coordinate

Lar1

OPN「大規模」

L DBB [AR1、P#0.0]

L 3

== I

Jc m_lf

L DBB [AR1、P#0.0]

L 4

== I

Jc m_rt

L DBB [AR1、P#0.0]

L 5

== I

Jc m_up

L DBB [AR1、P#0.0]

L 6

== I

Jc m_dn

ジュノプ

m_lf:L#tail_cut.tmp_coordinate

LP#1.0

+ D

T#tail_cut.tmp_coordinate

L#ルーパー

L 1

+私

T#ルーパー

Ju LPCT

m_rt:L#tail_cut.tmp_coordinate

LP#1.0

-D

T#tail_cut.tmp_coordinate

L#ルーパー

L 1

+私

T#ルーパー

Ju LPCT

m_up:L#tail_cut.tmp_coordinate

LP#10.0

+ D

T#tail_cut.tmp_coordinate

L#ルーパー

L 1

+私

T#ルーパー

Ju LPCT

m_dn:L#tail_cut.tmp_coordinate

LP#10.0

-D

T#tail_cut.tmp_coordinate

L#ルーパー

L 1

+私

T#ルーパー

Ju LPCT

カット:L#tail_cut.tmp_coordinate

Lar1

OPN「大規模」

L 0

T DBB [AR1、P#0.0]

nop:NOP 0



記事の終わりに達したすべての人にあなたの注意をありがとう。



プロジェクトをダウンロードするためのリンク



All Articles