Posted on

Boeing Automated Honeycomb Repair System | Cal State Los Angeles

The requirements for an Automated Honeycomb Repair System was set forth by Boeing’s Defense, Space and Security division, where honeycomb panels are heavily used on satellite structures in space, government, and military communication applications. This was a joint senior project by students at Cal State Los Angeles and The Boeing Company.

The requirements were to design an automated repair system which would repair dents and damages on honeycomb panels in an automated fashion such that it would speed up the current “manual repair” of honeycomb panels which currently take an approximated 3-4 hours to repair a single dent.

The basic concept of the process is to drill out the top face-sheet of the honeycomb with a 1/4″ drill, core pick an inner diameter of 1″ under the drilled top face-sheet to the bottom face-sheet, vacuum debris, and finally foam fill the core-picked void / affected area.

To achieve the aforementioned process, the mechanical sub-system consists of a ball-screw driven Y and Z axis and a rotary A axis for performing a tool change turret style and which also makes angled entry of a custom core-picker tool possible, which was also custom designed by our team for the actual core-picking task.

The electrical sub-system consists of a single Arduino Due for complete machine control and automation driving: 3 Stepper Motors & Drives, a Servo Motor + Drive, 6 Solenoid Valves, Full 20×4 LCD Display for Status updates throughout the process, Full Color RGBW LED Strip for visual status feedback, 8 Relays, also Input devices include: 4 optical homing sensors, one for each axis, tool touch plate input, probe input, and finally start + stop inputs.

All possible noise generating devices such as power supplies and motor drives were placed far away from logic level devices such as the control microprocessor / Arduino. This was initially designed with that in mind as can be seen in the Solid-works model layout.

From Solid-works model on the left to realization on the right, the figure above shows the actual machine after fabrication. The entire machine automation process brought down the manual repair time of 4-6 hours to roughly 10 minutes.

Below is a time-lapse of the entire process of the Automated Repair Machine Process.

The video begins with all the user-replaceable tools being “tool-touched” or measured for any change due to wear or replacement, as they will not be exactly placed into location via human hands, this applies to the drill bit, probe, and custom core-picking tool. Next the face of the honeycomb panel is measured via a probe, and drilling of the face sheet is performed. After drilling, the bottom face-sheet is measured to make sure the next process of core picking does not puncture the bottom face sheet when clearing the inner honeycomb core. Using those measured distances from top to bottom face-sheet, the core picking process is performed, pay attention to the fine motor movements required for the custom angled tool to make entry and exit the previously drilled hole. Next the vacuum clears all the debris in the core picked void space, and finally foam is filled into the affected area, completing the repair process, the machine waits for another dent and start button press to begin its process again.

Senior Team Members: Allen Analian (EE), Jeffrey T. Iwasaki (ME), Jonathan Sanabria (ME), Gino Kiettisak (ME), Carlos A. Sanchez (ME), Alberto M. Cortes (EE)

Acknowledgments: Special Thanks to the Boeing Company & Cal State Los Angeles for the opportunity, Theodore (Ted) Nye (Senior Design Director), Teofilo El-Masri, Cameron Massey, Jose Armenta, Jonathan Fish (Boeing Liaisons).

Posted on

ESP8266 NodeMCU – Toggle Button & Slider – Remote Node.js Server Example

After looking all over for bits and pieces of how to properly get a Remote Node.js Server to communicate with a ESP8266 or ESP32 NodeMCU, I was finally able to get everything working properly. With so many libraries of the same variant of implementing a Socket.io client on a NodeMCU, it was very confusing when functions had the same or very similar names and arguments.

I wanted a way to remotely control a device with a button toggle switch (LED, Mosfet, Relay etc) and a range slider to control brightness of an LED, Triac etc with a web based interface on a NodeMCU, communicating to a centralized web server.

Here is an example of how I was able to achieve it with fairly great results. Hopefully this helps others in trying to achieve the same results. For more buttons and sliders their values can be stored in 2 arrays one for switch state values and another for dimmer pwm values, both with a corresponding id to each button or slider.

Below is the Server.js file running on the remote Node.js Web Server :


var http = require('http');

var express = require('express');

var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);

app.get('/', function (req, res) {

res.sendFile(__dirname + '/index.html');

});
app.use(express.static(__dirname + '/'));

var server = http.createServer(app);

var io = require('socket.io').listen(server);

server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

// Define/initialize our global vars
var socketCount = 0

var brightness = 0; //static variable to hold the current brightness
var swstate = 0;

io.sockets.on('connection', function(socket){
//console.log(socket.id);
// Socket has connected, increase socket count
socketCount++
// Let all sockets know how many are connected
io.sockets.emit('users connected', socketCount)

socket.emit('swstate', swstate);

socket.on('swstate',function(){
swstate = 1 - swstate;
//console.log(swstate);
io.emit('swstate', swstate);
});

socket.emit('led', {value: brightness}); //send the new client the current brightness

socket.on('led', function (data) { //makes the socket react to 'led' packets by calling this function
brightness = data.value; //updates brightness from the data object
io.sockets.emit('led', {value: brightness}); //sends the updated brightness to all connected clients
});

});

process.on('SIGINT', function() {
//Do things on Script Termination...
console.log('\n Bye!')
process.exit();
});

Start the node.js server script on the remote server using the command in SSH:
forever start -o out.log -e err.log Server.js

Below is the index.html file running in the same directory as the Node.js Script (This page is served by the Node.js http Server) :

<html>
<head>
<title>Node.js Socket.io Testing</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap2/bootstrap-switch.min.css">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.11.3%2Fjquery.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Frangeslider.js%2F2.3.2%2Frangeslider.min.css%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<!--[if IE]>
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fjson3%2F3.3.2%2Fjson3.min.js%22%3E%0A%3Cscript%20src%3D%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fsocket.io%2F2.1.1%2Fsocket.io.dev.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<![endif]-->
<!--[if !IE]><!-->
<!--<![endif]-->
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2Fsocket.io%2Fsocket.io.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fmaxcdn.bootstrapcdn.com%2Fbootstrap%2F3.3.5%2Fjs%2Fbootstrap.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fbootstrap-switch%2F3.3.2%2Fjs%2Fbootstrap-switch.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fgitcdn.github.io%2Fbootstrap-toggle%2F2.2.2%2Fjs%2Fbootstrap-toggle.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Frangeslider.js%2F2.3.2%2Frangeslider.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
 
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0Abody%20%7B%0Amargin-top%3A%2020px%3B%0Amargin-left%3A%2030px%3B%0A%7D%0A%0Ainput%5Btype%3Drange%5D%7B%0A-webkit-appearance%3A%20none%3B%0Awidth%3A%2080%25%3B%0A%7D%0A%0Ainput%5Btype%3Drange%5D%3A%3A-webkit-slider-runnable-track%20%7B%0Aheight%3A%2010px%3B%0Abackground%3A%20%230c75b3%3B%0Aborder%3A%20none%3B%0Aborder-radius%3A%203px%3B%0A%7D%0A%0Ainput%5Btype%3Drange%5D%3A%3A-webkit-slider-thumb%20%7B%0A-webkit-appearance%3A%20none%3B%0Aborder%3A%20none%3B%0Aheight%3A%2032px%3B%0Awidth%3A%2032px%3B%0Aborder-radius%3A%2050%25%3B%0Abackground%3A%20%2314c0dc%3B%0Amargin-top%3A%20-12px%3B%0A%7D%0A%0Ainput%5Btype%3Drange%5D%3Afocus%20%7B%0Aoutline%3A%20none%3B%0A%7D%0A%0Ainput%5Btype%3Drange%5D%3Afocus%3A%3A-webkit-slider-runnable-track%20%7B%0Abackground%3A%20%230c75b3%3B%0A%7D%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="
<style>" title="
<style>" />

</head>
<body>
 

<div class="row">
 

<div class="alert alert-info col-md-3 col-md-3" role="alert" id="usersConnected"></div>

 
</div>

 
<strong>Slider Value: </strong><span id="outputText">50</span>
 
<input type="range" id= "inputSlider" min="0" max="1023" value="0" step="1" oninput="showValue(this.value)" />
 
<strong>SW State: </strong><span id="swval"></span>
 
<input type="checkbox" data-toggle="toggle" data-on="Off" data-off="On" id="toggle">
 
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E%0A%0A%2F%2F%20Connect%20to%20our%20node%2Fwebsockets%20server%0Avar%20socket%20%3D%20io.connect('http%3A%2F%2Fwww.domain.com%3A3000')%3B%0A%0Avar%20websocket%20%3D%200%3B%0A%0A%24(%22%23toggle%22).change(function()%7B%0Aif(!websocket)%20%7B%0Aif(%24(%22%23toggle%22).prop(%22checked%22)%20%3D%3D%201)%7B%0Avar%20swstate%20%3D%201%3B%0Asocket.emit('swstate'%2C%20swstate)%3B%0A%7Delse%7B%0Avar%20swstate%20%3D%200%3B%0Asocket.emit('swstate'%2C%20swstate)%3B%0A%7D%0A%7D%20else%20%7Bwebsocket%20%3D%200%3B%7D%0A%7D)%3B%0A%0Asocket.on('swstate'%2C%20function(swstate)%20%7B%0AswValue(swstate)%3B%0Awebsocket%20%3D%201%3B%0Aif(swstate%20%3D%3D%3D%201)%7B%0A%24('%23toggle').bootstrapToggle('on')%3B%7D%0Aelse%7B%0A%24('%23toggle').bootstrapToggle('off')%3B%7D%0A%0A%7D)%3B%0A%2F%2F%20New%20socket%20connected%2C%20display%20new%20count%20on%20page%0Asocket.on('users%20connected'%2C%20function(data)%7B%0A%24('%23usersConnected').html('%3Cstrong%3EUsers%20Connected%3A%3C%2Fstrong%3E%20'%20%2B%20data)%0A%7D)%0A%0Asocket.on('led'%2C%20function%20(data)%20%7B%0Adocument.getElementById(%22inputSlider%22).value%20%3D%20data.value%3B%0Adocument.getElementById(%22outputText%22).innerHTML%20%3D%20data.value%3B%0A%7D)%3B%0A%0Afunction%20showValue(newValue)%0A%7B%0Adocument.getElementById(%22outputText%22).innerHTML%3DnewValue%3B%0Asocket.emit('led'%2C%20%7B%20value%3A%20newValue%20%7D)%3B%0A%7D%0Afunction%20swValue(swstate)%0A%7B%0Adocument.getElementById(%22swval%22).innerHTML%3Dswstate%3B%0A%7D%0A%2F%2F%7D)%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
</body>
</html>

Below is the Code for the ESP8266 NodeMCU programmed on the Arduino IDE (v1.8.5) environment:

#include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch)

//#include <DNSServer.h> //Local DNS Server used for redirecting all requests to the configuration portal
#include <ESP8266WebServer.h> //Local WebServer used to serve the configuration portal
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
#include <ESP8266mDNS.h>
#include <SocketIoClient.h>
#include <ArduinoJson.h>

#define LED 13
// Pin D7 on NodeMCU
#define LEDPWM 12
// Pin D6 on NodeMCU

const char* mdnsName = "esp8266";

// DNS server
const byte DNS_PORT = 53;
DNSServer dnsServer;

ESP8266WebServer webServer(80);

SocketIoClient socket;

void light(const char * payload, size_t length) {
String msg;
//String text = String((char *) &payload[0]);
msg = String((char*)payload);
if(msg=="1"){ digitalWrite(LED,HIGH); Serial.println("LED ON");}else{digitalWrite(LED,LOW); Serial.println("LED OFF");}
Serial.println(msg);
}

void lightpwm(const char * payload, size_t length) {

DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(4) + 100);

//String text = String((char *) &payload[0]);
//String msg2 = String((char*)payload);

JsonObject& root = jsonBuffer.parseObject(String((char*)payload));
int pwmval = root["value"];
//Serial.println("PWM LED");
analogWrite(LEDPWM, pwmval);
}

String responseHTML = ""
"<!DOCTYPE html><html><head><title>Hello World!</title></head><body>"
"

<h1>Hello World!</h1>


All requests are redirected here.

</body></html>";

//flag for saving data
bool shouldSaveConfig = false;

void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
Serial.println(myWiFiManager->getConfigPortalSSID());
}

//callback notifying us of the need to save config
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;
}

void setup() {
// put your setup code here, to run once:
pinMode(LED, OUTPUT);
pinMode(LEDPWM, OUTPUT);
digitalWrite(LED, LOW);
Serial.begin(115200);
WiFiManager wifiManager;
//reset settings - for testing
//wifiManager.resetSettings();
wifiManager.setConfigPortalTimeout(360);
wifiManager.setDebugOutput(false);

wifiManager.setAPCallback(configModeCallback);
//WiFiManager.setHostname(mdnsName);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if(!wifiManager.autoConnect("Allen_LED", "1234pass")) {
Serial.println("failed to connect and hit timeout");
//reset and try again, or maybe put it to deep sleep
ESP.reset();
delay(1000);
}
wifiManager.setSaveConfigCallback(saveConfigCallback);

//if you get here you have connected to the WiFi
Serial.println("Connected!... YES!");
Serial.println("Local IP is: ");
Serial.println(WiFi.localIP());
WiFi.hostname(mdnsName);
if (!MDNS.begin(mdnsName, WiFi.localIP())) {
// Start the mDNS responder for esp8266.local
Serial.println("Error setting up MDNS responder!");
}
Serial.println("mDNS responder started");
// Add service to MDNS-SD
MDNS.addService("http", "tcp", 80);
MDNS.addServiceTxt("http", "tcp", "url", "http://esp8266.local");

socket.begin("www.domain.com", 3000, "/socket.io/?transport=websocket");
//socket.on("event", event);
socket.on("swstate", light);
socket.on("led", lightpwm);

// HTTP Basic Authorization (optional)
//webSocket.setAuthorization("username", "password");

//socket.emit("plainString", "\"this is a plain string\"");
//socket.emit("swstate", "1");

// replay to all requests with same HTML
webServer.onNotFound([]() {
webServer.send(200, "text/html", responseHTML);
});
webServer.begin();
}

void loop() {
// put your main code here, to run repeatedly:
dnsServer.processNextRequest();
webServer.handleClient();
socket.loop();
}

The end result will look like the screenshot below where the Button Switch controls Pin D7 on the NodeMCU, and the Slider will create a PWM Dimmer on Pin D6, which you can connect an LED to see the brightness level correspond to the slider in just about real-time. One side note: Make sure you replace domain.com in all the code above to reflect where your node.js server is running, localhost, ip, domain, hostname etc.

Posted on

Banquet & Hospitality Facility Lighting

How LED Lighting / Entertainment & Specialty Lighting Affects Banquet Halls?

Banquet Facility & Hospitality Clients today are noticing things like lighting, its an important aspect that was previously overlooked in the banquet & hospitality industry.

For example in a banquet facility, there is only so much a DJ or lighting company can do via mobile or rental service besides up-lighting walls and moving lights around the stage, or around the dance floor area.

That’s why it’s important a banquet or hospitality facility considers things such as lighting in new building construction or when revamping existing systems.

If your always asking yourself how to fix banquet hall lighting, a lighting company specializing in entertainment lighting is probably your best bet.
At Allen Productions, we understand the newest trends in lighting as electrical engineers from both the customers point of view and also technical standpoint.

We think of the future in our projects, for easier expansion and updates. Check out some of our customers and projects on our project portfolio, we cater to some of the top banquet facilities in Southern California, the entertainment capital of the world.

We look forward to further discussing our services with you to determine how we can beautify your venue(s). Contact us today!

Posted on

Wayne Nucleus to Gilbarco Passport POS UPC & Pricebook Conversion

Having worked on a custom application for a petroleum c-store & back office company, we have created a Dresser Wayne Nucleus to Gilbarco Passport POS parsing system for converting the UPC’s, Departments & Pricebook, following the NAXML 3.3 POS standard structure.

We have an ultra fast parser developed to convert:
Nucleus: .DAT files (must contain UPCs) to Passport: ITT, MCT, ILT, CBT, MMT, TaxMaintenance XML files.

How the process works:
Your Wayne / Gilbarco certified & approved technician provides us with the previous POS nucleus .DAT file containing the UPC / PLUs and your current Passport ITT, MCT, TaxMaintenance XML files, we provide the conversion process and generate new ITT, MCT, ILT, CBT, MMT, TaxMaintenance XML files for the Passport system, to your technician and you (in case you need them for your back office system).

Contact us for conversion pricing (now less than $450 per location), one time cost covered until conversion is the way you want, free file analysis, we will beat anyone’s advertised price for price-book conversion!

Posted on

New: Lighting Installation – Metropol Classic Banquet Hall – State of the Art Lighting System

New Lighting Installation – Featuring State of the Art LED Lighting System
Location: Metropol Classic Banquet Hall – Glendale, California
Installation Time Frame: 60 Days

Video of Completed Install Project During a Private Event:

Video During Lighting Programming of Installation:

Test of Slow Movements:

Preparing the Wiring of Installation & Termination:

Posted on

MSD250, MSD575, MSD1200 to LED Retrofit Kits Made For Moving Head Spot Lighting Fixtures 150w to 1200w HID MSD HMI Type

Allen Productions has been working on a New LED Retrofit Kit Designed to Replace MSD / HMI Lamps in Moving Head Spot or Wash Lighting Fixtures 150-Watt to 1200-Watt. If you are a touring company, a rental house, or have a permanently installed rig of moving heads, this retrofit is for you! IT WILL VOID YOUR WARRANTY because it requires a bit of modification of your light fixture to fit the LED module into place, and replacing your existing heavy ballast and igniters in the fixture with an LED ballast.

Posted on

Batman – The Dark Knight Rises – Magnus Rex – July 20 – Bomb Truck Scene Crane

Allen A. Working as Bobs Towing’s Technical Director, we got the opportunity to transport and move around a large “bomb carrying” truck for the Batman “The Dark Knight Rises”, code-name (“Magnus Rex”) Movie Set, which is set to air on July 20th in Theaters near you. Below are some images of the owner of Allen Productions & their crew, and the Bob’s Towing Equipment (Rotator / Crane & Special Equipment) Used. Remember if you just need a Tow or have a need to move large heavy equipment for a movie set, they can handle Any Job! Call 1(800) BobsTow. Allen Productions also has a department for Special Effects, worldwide experts in “Control Electronics” to Special Effects Lighting & High Powered Lasers, to Pyrotechnics for the motion picture, television and entertainment industries including Video Synchronized Effects based on SMTPE & various other industry standard methods of synchronization. Are you a Movie Producer? Have a Technical Need? Problem? Need Help? or Just Want Solutions? We Can Help You! Call Us Today at (562) 242-8479! Be Sure To Ask for Allen!

Special Thanks To Warner Brothers & the other Production Companies Involved! If your company was also a part of this film / scene and would like to be featured on this page please contact us.

 Allen Productions Exclusive Photos Below:
All Rights Reserved! DO NOT COPY ANY PHOTOS WITHOUT WRITTEN PERMISSION!

Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck
Batman - Dark Knight Rises - Bomb Truck
Batman – Dark Knight Rises – Bomb Truck