March 21, 2019, 04:18:07 PM
Robotforum | Industrial Robots Community

 BGLOGIC code that I have found useful

Author Topic:  BGLOGIC code that I have found useful  (Read 63589 times)

0 Members and 1 Guest are viewing this topic.

December 16, 2010, 08:35:19 PM
Read 63589 times
Offline

flatcurve


So, I've only been using BGLOGIC for a couple months now. In my opinion, this is something that FANUC should teach in their advanced TPP class, because it's extremely useful. If it wasn't for the suggestion of somebody here, I never would have discovered this feature on my own. I guess they expect people to read their manual cover to cover, but there isn't enough coffee in the world to keep me awake if I tried that. I've managed to take a lot of heat off of our PLC programmer, and I've already developed a few routines that I've found almost universally useful.

So as a way of saying thanks, here are a couple code snippets I thought I'd share.

One shots are used when you only want something to happen for one scan of the program. This can be used to replace macros that are triggered by inputs. Why would you want to do that? Well, input macros don't work in T1 or T2.

One Shot Method A
F[1]=(OFF)
IF (DI[1] AND !F[2]),F[1]=(ON)
F[2]=(DI[1])
Now F[1] can be used at any point to test for a one shot condition before the end of the BG program

One Shot Method B
IF (DI[1] AND !F[1]),...
(Repeat above IF instruction when needed before next line)
F[1]=(DI[1])

One Shot Output Toggle
This is handy for using a single input (like a push button or sensor) to toggle an output on and off
IF (DI[1] AND !F[1]),DO[1]=(!DO[1])
F[1]=(DI[1])

Output Strobe
We put three color stack lights on our controllers, and I use this routine to make the yellow light flash when I turn on F[1]
IF (F[1] AND !F[3]),F[2]=PULSE,0.2sec
IF (F[1] AND !F[2]),F[3]=PULSE,0.2sec
IF (!F[1]),F[2]=(OFF)
IF (!F[1]),F[3]=(OFF)
DO[1:Light]=(F[2])

If anybody wants to add, feel free!

Today at 04:18:07 PM
Reply #1

Advertisement

Guest

June 27, 2011, 08:49:01 AM
Reply #1

pepioto

Guest
I work with fanuc M410 ib and i can´t do this instruction with ROBOGUIDE soft where can i download or buy the BGLOGIC?
And if you can showme pictures that it makes useful with a simulation it will be cool.

Thanxs

June 28, 2011, 03:06:45 PM
Reply #2
Offline

robodog


i use back ground logic alot ansd i dont think you would be able to do it with roboguide because it is mixed logic, (non motion). but then again i have never used roboguide i do all of my programming at the TP. I found it very useful to take the place of karel which i hate!!! soo much easier just to open up your BGlogic progrqam and edit it right there at the TP instead of having to compile and recompile...   ect
« Last Edit: September 19, 2011, 12:06:49 PM by robodog »

July 14, 2011, 01:30:18 PM
Reply #3
Offline

flatcurve


It does work with roboguide, however it has caused a few crashes in my experience. Since I predominantly use it to monitor discrete i/o, I usually don't bother running it in simulation.

September 15, 2011, 10:25:44 AM
Reply #4
Offline

Robot FANKU


One Shot Method A[/b]
F[1]=(OFF)
IF (DI[1] AND !F[2]),F[1]=(ON)
F[2]=(DI[1])
Now F[1] can be used at any point to test for a one shot condition before the end of the BG program

One Shot Method B
IF (DI[1] AND !F[1]),...
(Repeat above IF instruction when needed before next line)
F[1]=(DI[1])

One Shot Output Toggle
This is handy for using a single input (like a push button or sensor) to toggle an output on and off
IF (DI[1] AND !F[1]),DO[1]=(!DO[1])
F[1]=(DI[1])

Output Strobe
We put three color stack lights on our controllers, and I use this routine to make the yellow light flash when I turn on F[1]
IF (F[1] AND !F[3]),F[2]=PULSE,0.2sec
IF (F[1] AND !F[2]),F[3]=PULSE,0.2sec
IF (!F[1]),F[2]=(OFF)
IF (!F[1]),F[3]=(OFF)
DO[1:Light]=(F[2])

ho flat can you clearly explain i am little bit confused about this logic..... :waffen100:    thanks in advance  :icon_smile:

September 15, 2011, 03:52:02 PM
Reply #5
Offline

flatcurve


Background Logic programs are scan routine programs that constantly run in the background. They are executed one line at a time, from start to finish, repeatedly. If you know anything about PLC programming, they are very similar to the way those programs are structured and run. You can only use assignment statements in background logic programs. This means that you can not use motion instructions, branching statements (jump, label, call, run, etc...), timers, WAIT instructions or macros.

So basically you are limited to setting registers, I/O and system variables. And the only conditional statement you can use is the mixed logic IF statement: IF (...)

All of this is to keep the program simple so that it can be executed quickly. In my experience, if you're dealing with less than 16 inputs and 16 outputs, background logic is a good way to avoid using a PLC in the workcell if you don't have to. Anything more than that would probably be better suited to either the PMC option or a PLC. For me, the primary way I use it is to set up run conditions that must be met before the robot can be operated in automatic.

A "one shot" is probably the most valuable tool you can use when doing this sort of programming. Remember that this program is repeatedly scanning (looping) in the background. We use a one shot to make something happen for only one scan. For example, let's say we have a button connected to an input (DI[1]). Every time we push the button, we want to add 1 to the value of a register (R[1]).

IF (DI[1), R[1]=R[1]+1

The problem with this code though is that the program is repeating every 8ms. Unless you have very quick hands, it's likely that the button will be held down for more than one scan of the program, resulting in more than 1 being added the the register. So to fix it, we have to use a one shot:

F[1]=(OFF)
IF (DI[1] AND !F[2]),F[1]=(ON)
F[2]=(DI[1])
IF (F[1]), R[1]=R[1]+1

And here's how it works scan by scan:

First scan with DI[1] on:
F[1]=(OFF)  ;We always turn this flag off at the start of the cycle
IF (DI[1] AND !F[2]),F[1]=(ON)  ;If DI[1] is on, and F[2] is off, we want to turn F[1] on
F[2]=(DI[1]) ;Now we want to set F[2] to the same state as DI[1]. This means that on the next "scan", the condition in the previous line will not be met.
IF (F[1]), R[1]=R[1]+1  ;If we've gotten this far, and we see that F[1] is on, that means we know it's the first scan where we've seen DI[1] on

Second scan with DI[1] on:
F[1]=(OFF) ;Again, this flag gets turned off to avoid repeating any of those assignments again
IF (DI[1] AND !F[2]),F[1]=(ON)  ;This time around F[2] is on, so this condition is not met, and F[1] stays off
F[2]=(DI[1]) ;This holds F[2] on until we see DI[1] turn off.
IF (F[1]), R[1]=R[1]+1 ;This line will not execute

First scan with DI[1] off:
F[1]=(OFF)
IF (DI[1] AND !F[2]),F[1]=(ON) ;DI[1] is off, and F[2] is still on from the last cycle. Condition still not met.
F[2]=(DI[1]) ;Now F[2] is turned off. The next time DI[1] comes on, the above condition will be met again.
IF (F[1]), R[1]=R[1]+1


Basically it all comes down to order of execution. If you put things in the right order, you can do practically anything. Earlier I said that I prefer to use BG Logic with less than 16 inputs and outputs, but I have used it as a cell controller on a system that had 32 inputs and 48 outputs. It controlled everything from the notification lights, an exit conveyor, a couple of pneumatic cylinders, a small printer and another robot. All with background logic. I would have preferred a PLC or even just the PMC option, but the customer beat us up on price and the budget didn't allow it.

Here's a chunk of code from one of the four BG Logic programs running on that system that uses all sorts of one shots and cascading logic:

Code: [Select]
   1:  F[69:PrntMaint]=(!DI[26:PrntrRunPos]) ;
   2:   ;
   3:  !Cycle Printer & Shear ;
   4:  IF (DI[14:LblReelEmpty]),F[19:ReelLockout]=(ON) ;
   5:  IF (DI[15:ManualPrint] AND DI[27:PrntrMaintPos] AND !DI[14:LblReelEmpty]),F[19:ReelLockout]=(OFF) ;
   6:  IF (DI[12:LblShtl_Retr] AND F[9:PrntrInCycle]),F[17:ManTrig]=(OFF) ;
   7:  IF (DI[15:ManualPrint] AND !F[18:ManTrigPB_OS] AND DI[27:PrntrMaintPos] AND !F[19:ReelLockout]),F[17:ManTrig]=(ON) ;
   8:  F[18:ManTrigPB_OS]=(DI[15:ManualPrint]) ;
   9:  IF (F[17:ManTrig] AND F[13:LabelPresent] AND DI[27:PrntrMaintPos] AND !F[9:PrntrInCycle]),DO[16:LblSlideVac]=(OFF) ;
  10:  IF (F[17:ManTrig] AND F[13:LabelPresent] AND DI[27:PrntrMaintPos] AND !F[9:PrntrInCycle]),F[13:LabelPresent]=(OFF) ;
  11:  F[24:AutoPTrigRdy]=(F[23:AutoPTrigAllow] AND DI[26:PrntrRunPos]) ;
  12:  F[12:PrntAutoTrig]=(F[17:ManTrig] OR F[24:AutoPTrigRdy]) ;
  13:  F[10:PrntTrigOS]=(OFF) ;
  14:  IF (F[19:ReelLockout]),F[12:PrntAutoTrig]=(OFF) ;
  15:  IF (!F[10:PrntTrigOS] AND !F[9:PrntrInCycle] AND F[12:PrntAutoTrig] AND DI[12:LblShtl_Retr] AND !F[13:LabelPresent]),F[10:PrntTrigOS]=(ON) ;
  16:  IF (F[10:PrntTrigOS]),F[9:PrntrInCycle]=(ON) ;
  17:  IF (F[9:PrntrInCycle] AND F[10:PrntTrigOS]),F[14:TrigPrntr]=(ON) ;
  18:  IF (F[9:PrntrInCycle] AND F[14:TrigPrntr]),F[66:ShearDelay]=PULSE,0.6sec ;
  19:   ;
  20:  IF (F[9:PrntrInCycle] AND F[14:TrigPrntr] AND F[66:ShearDelay]),DO[12:TriggerPrinter]=PULSE,0.3sec ;
  21:   ;
  22:  IF (F[9:PrntrInCycle] AND F[14:TrigPrntr] AND !F[66:ShearDelay]),F[11:PrntFinished]=(ON) ;
  23:  IF (F[9:PrntrInCycle] AND F[14:TrigPrntr] AND !F[66:ShearDelay]),F[14:TrigPrntr]=(OFF) ;
  24:   ;
  25:  IF (F[9:PrntrInCycle] AND F[11:PrntFinished] AND DI[10:ShearOpen] AND !F[15:ShearClosed]),DO[14:CloseShear]=(ON) ;
  26:  IF (F[9:PrntrInCycle] AND F[11:PrntFinished] AND DI[10:ShearOpen] AND !F[15:ShearClosed]),DO[16:LblSlideVac]=(ON) ;
  27:  IF (F[9:PrntrInCycle] AND F[11:PrntFinished] AND DO[14:CloseShear] AND DI[11:ShearClosed] AND !F[15:ShearClosed]),F[15:ShearClosed]=(ON) ;
  28:  IF (F[9:PrntrInCycle] AND F[11:PrntFinished] AND DO[14:CloseShear] AND DI[11:ShearClosed] AND F[15:ShearClosed]),DO[14:CloseShear]=(OFF) ;
  29:  IF (F[9:PrntrInCycle] AND F[11:PrntFinished] AND DI[10:ShearOpen] AND F[15:ShearClosed] AND !F[16:ShearDone]),F[16:ShearDone]=(ON) ;
  30:  IF (F[9:PrntrInCycle] AND F[16:ShearDone] AND DI[12:LblShtl_Retr] AND !DO[15:LblSlideExtend]),DO[15:LblSlideExtend]=(ON) ;
  31:  IF (F[9:PrntrInCycle] AND F[16:ShearDone] AND DI[13:LblShtl_Ext] AND DO[15:LblSlideExtend]),F[13:LabelPresent]=(ON) ;
  32:  IF (F[13:LabelPresent] AND F[9:PrntrInCycle]),F[15:ShearClosed]=(OFF) ;
  33:  IF (F[13:LabelPresent] AND F[9:PrntrInCycle]),F[16:ShearDone]=(OFF) ;
  34:  IF (F[13:LabelPresent] AND F[9:PrntrInCycle]),F[11:PrntFinished]=(OFF) ;
  35:  IF (F[13:LabelPresent] AND F[9:PrntrInCycle]),F[9:PrntrInCycle]=(OFF) ;
  36:  IF (!F[13:LabelPresent] AND !F[9:PrntrInCycle] AND DI[13:LblShtl_Ext]),DO[15:LblSlideExtend]=(OFF) ;

This code basically triggers a printer to print a label, cut the label with a shear, move the cut label with a small slide so that the robot can pick it, and tells the robot that there's a label present. Once the robot picks it, it turns off the label present flag which starts the print cycle again automatically. All of this happens in under a second while the robot is off applying the label. It also has allowances for a manual push button trigger so that the printer can be set up and tested in a maintenance mode. This is the primary reason I used BG Logic instead of a macro. Because BG Logic runs all the time, whether the robot is paused, in automatic, or in teach mode. This means maintenance personnel don't need to mess with the teach pendant as much. From a support standpoint, I prefer that whenever possible.

Like I said, you can do anything with it.

October 18, 2011, 03:34:57 PM
Reply #6
Offline

zhouchunzhang012



Today at 04:18:07 PM
Reply #7

Advertisement

Guest

October 31, 2011, 10:32:09 PM
Reply #7
Online

Sergei Troizky


Changing the startup default Joint jogging coordinates to World:

 IF (!F[1:BOOT DONE]),$JCR_GRP[1].$JOG_COORD=(2) ;
 F[1:BOOT DONE]=(ON)
« Last Edit: June 06, 2014, 11:57:15 PM by Sergei Troizky »

April 03, 2013, 03:54:37 AM
Reply #8
Offline

Robo1


Hello Flatcurve,

I read your post and really interesting to use it on one of our application.  However, i'm having couple of questions.  Hope you can guide me through this process.

1.  Is BG Logic written in the TP program?
2.  I would like to accomplish the logic below, could you help with the code how it should be written?

If input 1 OFF and input 2 OFF don't do anything
If Input 1 ON and Input 2 OFF then turn on output 1 for 500 milisecond
If input 1 Off and input 2 On then ouput 1 stay off.
(They are all Digital I/O)

Thanks in advance for your help.
Thank you,

May 10, 2013, 11:55:16 AM
Reply #9
Offline

andreic


Hi Robo1,

You can setup BGLOGIC from Menu -> Setup -> BGLOGIC where you can choose your BGLOGIC program. 

To accomplish the logic you need:
IF (DI[1] AND !DI[2]),DO[1]=PULSE,0.5sec. Put this in a TP program and add it's name in setup menu.

July 15, 2013, 09:07:00 PM
Reply #10
Offline

DuhbCakes


This will allow you to toggle a digital output from a DCS CPC zone without using safe I/O.  obviously by using a single channel output, it is no longer a safety signal but it is useful for protecting equipment.

:  IF ($DCSS_PSTAT.$STATUS_CPC[1]=0),DO[1:Clear Transfer DCS]=(ON) ;
:  IF ($DCSS_PSTAT.$STATUS_CPC[1]=1),DO[1:Clear Transfer DCS]=(OFF) ;

This will monitor if someone has jogged the robot. i use it for auto recovery. The bit can be cleared by moving to a point in a program, ether in auto or T1.

:  DO[1:Robot Jogged]=($MOR_GRP[1].$JOGGED) ;

September 24, 2013, 06:30:33 PM
Reply #11
Offline

amanmani


Very useful post

I wish to create a user alarm when a certain DI gets on but I am not able to write User alarm in BG logic as I am getting syntax error .
Please help me guys I am a newbie and wish to learn

Thanks in advance !!!!! :help:

December 11, 2013, 03:25:20 AM
Reply #12
Online

Sergei Troizky


STEP mode indicator output:
DO[n]=($SSR.$SINGLESTEP)

December 11, 2013, 02:54:02 PM
Reply #13
Online

Sergei Troizky


One Shot Method A[/b]
F[1]=(OFF)
IF (DI[1] AND !F[2]),F[1]=(ON)
F[2]=(DI[1])
Now F[1] can be used at any point to test for a one shot condition before the end of the BG program

One Shot Method B
IF (DI[1] AND !F[1]),...
(Repeat above IF instruction when needed before next line)
F[1]=(DI[1])

The most simple way to generate one shot is using the PULSE instruction with no time specified.
In BG Logic, this generates a single scan pulse.
Note, that in normal (non background) execution this will generate a pulse of default $DEFPULSE duration.
« Last Edit: December 11, 2013, 02:55:43 PM by Sergei Troizky »

Today at 04:18:07 PM
Reply #14

Advertisement

Guest

December 20, 2013, 05:58:21 PM
Reply #14
Offline

flatcurve



also note that the PULSE command does not work in FAST mode (guaranteed 8msec scan time) so if you need edge detection in a fast bg program, you gotta do it like this:

F[1]=(DI[1] AND !F[2])
F[2]=(DI[1])

May 04, 2014, 05:28:19 PM
Reply #15
Online

Sergei Troizky


Automatically disable/enable UOP when TP is On/Off:
$OPWORK.$UOP_DISABLE=(UO[8:TP_Enabled])
The instruction must be created as Registers ...=(...), not as Miscellaneous>Parameter Name.
The background program must be set (in its Detail) to ignore pause conditions.

July 18, 2014, 10:17:58 AM
Reply #16
Offline

bidzej


As we're talking about scan time for BGLOGIC program - how fast does BGLOGIC for R-30iB work? I'd like to implement a control system for a simple palletizing application using only BGLOGIC (instead of PMC) and I'm afraid that if the program is too long and complex, there may be situations when i. e. a pulsed signal from a sensor is omitted.

I see that it's possible to set the scan time for 8msec, but - if I understand correctly - this limits functionality of BGLOGIC, so I'd like to use standard mode...

July 24, 2014, 10:10:08 PM
Reply #17
Offline

flatcurve


Scan time is still 8msec (12msec on mate controllers) but the amount of items processed per ITP greatly increased in v8 of HandlingTool. (540 vs. 300) An item is data, an operator or an instruction. So the following is a 3 item statement:

F[1]=(DI[1])

Item 1: F[1]
Item 2: =
Item 3: (DI[1])

My general rule of thumb is to use a PLC if I have more than 32 outputs to control. Obviously there's also considerations for what those outputs are doing. But if you think you might have pulsed inputs shorter than your scan time (x2), you should just use a PLC regardless.

July 25, 2014, 06:19:21 AM
Reply #18
Offline

bidzej


Thanks, that expains a lot!  :merci:

December 02, 2014, 12:56:25 PM
Reply #19
Offline

diglo


Tell if a bit is set in a positive integer value:
Example: test 4th bit: 2^(4-1)=8
Code: [Select]
F[1]=((R[1] DIV 8 MOD 2)>0)
Example: test 5th bit: 2^(5-1)=16
Code: [Select]
F[1]=((R[1] DIV 16 MOD 2)>0)To test

Single-instruction timer:
125 is for 1 Second ,because 8ms = 1/125 of a second. Test it against your BGLOGIC scan speed.
Code: [Select]
R[1]=((R[1]+1)  MOD 125 );
 IF (R[1]=0), stuff to do each interval ;


January 05, 2015, 10:01:24 PM
Reply #20
Offline

PSRobotics


Hello,

Since Fanuc Doesn't have A TCP Position output. There is some Bglogic I found that Was able to Output real time TCP position.

There are variables to monitor TCP speeds from the robot though brute force. By wright System Variables to group outputs. keep in mind the robot outputs in MM and can only send an max of one unsigned integer. so what I did was scaled it into CM via*10 and send it over. I ended up not using W.P.R. A small issue is, these values only update when a program is ran, not when being Jogged.

(Although if you wanted to monitor these values and compare them to last time they were update, you can catch maintenance driving the robot around and trying to start it up in a different location :)

 1:   ;
   2:  R[20:X POS OUT]=($SCR_GRP[1].$MCH_POS_X) ;
   3:  R[21:Y POS OUT]=($SCR_GRP[1].$MCH_POS_Y) ;
   4:  R[22:Z POS OUT]=($SCR_GRP[1].$MCH_POS_Z) ;
   5:  R[23:W POS OUT]=($SCR_GRP[1].$MCH_POS_W) ;
   6:  R[24:P POS OUT]=($SCR_GRP[1].$MCH_POS_P) ;
   7:  R[25:R POS OUT]=($SCR_GRP[1].$MCH_POS_R) ;
   8:   ;
   9:  R[20:X POS OUT]=R[20:X POS OUT]*10    ;
  10:  R[21:Y POS OUT]=R[21:Y POS OUT]*10    ;
  11:  R[22:Z POS OUT]=R[22:Z POS OUT]*10    ;
  12:  R[23:W POS OUT]=R[23:W POS OUT]    ;
  13:  R[24:P POS OUT]=R[24:P POS OUT]    ;
  14:  R[25:R POS OUT]=R[25:R POS OUT]    ;
  15:   ;
  16:   ;
  17:  GO[3]=R[20:X POS OUT] ;
  18:  GO[4]=R[21:Y POS OUT] ;
  19:  GO[5]=R[22:Z POS OUT] ;
  20:  GO[6]=R[23:W POS OUT] ;
  21:  GO[7]=R[24:P POS OUT] ;
  22:  GO[8]=R[25:R POS OUT] ;

Today at 04:18:07 PM
Reply #21

Advertisement

Guest

February 13, 2015, 12:43:13 AM
Reply #21
Offline

dmbj



If di[1]=off jump lbl[1]
ualarm[1]
lbl[1]


and I have found this useful, you can use both a remote uop cycle start and the button on the controller.
configure a DI it a Uop I cycle start then...
  IF (DI[12:START]),$REMOTE_CFG.$REMOTE_TYPE=(1)
 IF (SI[6:Cycle start]),$REMOTE_CFG.$REMOTE_TYPE=(2)
« Last Edit: February 13, 2015, 01:04:28 AM by dmbj »

July 11, 2015, 05:40:24 PM
Reply #22
Offline

viox


=0),DO[1:Clear Transfer DCS]=(ON) ;
:  IF ($DCSS_PSTAT.$STATUS_CPC[1]=1),DO[1:Clear Transfer DCS]=(OFF) ;

This will monitor if someone has jogged the robot. i use it for auto recovery. The bit can be cleared by moving to a point in a program, ether in auto or T1.

:  DO[1:Robot Jogged]=($MOR_GRP[1].$JOGGED) ;


Much appreciated! Did not know where the variables where located!

October 28, 2015, 01:34:43 AM
Reply #23
Offline

ME andy


Here is one that I've found useful.

We use multiple consecutive RO's for tool changing, vacuum grippers, ionizers, etc. During development we manually force RO's to verify things. I wanted to make sure an operator could not accidentally drop a tool unless another action was performed first. Basically an interlock.

An operator has to force DO[1]=ON before they can drop a tool using RO[1]=ON. As soon as RO[1] is turned back to OFF after it's been ON, DO[1] resets to OFF and has to be forced again to drop a tool.

RO[1] is the tool change output (ON drops the tool)
DO[1] is the Interlock
DO[2] is a flag used to switch DO[1] OFF

PS. If anyone looking at this knows of a way to streamline this (I'm definitely a beginner) please let me know.

« Last Edit: October 28, 2015, 01:42:36 AM by ME andy »

November 10, 2015, 12:08:53 AM
Reply #24
Online

HawkME


@Me Andy,

Looks good, I use a similar program for tool changers. I prefer to used the mixed logic statement instead of the if, then,end if, because it is less lines of code. Mixed logic is the: If (...). It works like this:

If (!DO[1]), RO[1]=off
If (RO[1]), DO[2]=on
If (RO[1]!=DO[2]), DO[1]=off and DO[2]=off

Same program in 3 lines instead of 10.

Sent from my VS985 4G using Tapatalk



Share via facebook Share via linkedin Share via pinterest Share via reddit Share via twitter

xx
BGLOGIC code questions

Started by Paulfedoniuk on Fanuc Robot Forum

7 Replies
1406 Views
Last post July 05, 2017, 02:01:19 PM
by Paulfedoniuk
xx
BGLOGIC

Started by Skipp on Fanuc Robot Forum

4 Replies
487 Views
Last post November 14, 2018, 06:22:10 PM
by HawkME
question
PLC , BGLogic , or both?

Started by sean.ad on Fanuc Robot Forum

7 Replies
1692 Views
Last post June 28, 2017, 07:17:26 PM
by sean.ad
xx
R J2 BGLogic

Started by mortoch on Fanuc Robot Forum

1 Replies
1137 Views
Last post October 07, 2016, 02:15:05 AM
by ESIELI