brumbrum
Challenge 2
Speed Runs: optimising truck payload and cycle speeds
Description
Challenge Statement
At the Cowal Gold Mine, trucks transport ore over many km’s from the open pit. The more ore they take, the slower they move. Can you optimise for speed and tonnage?
Background
The Cowal operation is an open pit mining operation with production from a number of different areas within a large, single pit. As a result of the general site configuration and layout, haul distances, in particular for waste disposal, is the longest of all open pit operations across the company. Material is typically hauled for a 4km distance at a 1:10 incline and thereafter another 1-3km on a reasonably flat surface to the crusher, stockpiles or waste rock dumps depending on material type. A fleet monitoring system (MineStar) is installed and fully operational with a significant amount of individual truck cycle data available. Mining is carried out with a company-owned fleet of mining equipment that includes 2 x Liebherr 994 backhoe excavators, 1 x Hitachi 3600 Excavator and 16 x Cat 789 dump trucks. The Challenge
The key question remains: What is the optimum payload vs haul speed trade-off and how does that change with increases to the depth of the pit and haulage distances to future waste dump locations? The Opportunity
At present the operating philosophy is to “light load” trucks to ensure they reach at least second gear on the way out on the ramp. Payloads are controlled, however given the haul distance required, every tonne counts. If the optimum cycle speeds and payload can be determined, there is potential to improve productivity and reduce costs across the haulage fleet. Considerations
Critical areas to consider include:
For any given haulage cycle, can payload be “calibrated” to a specific location using historical VIMS data?
In excess of two years VIMS data is available for analysis that could be “mined” to establish the optimum trade-off!
Can payload optimisation be done in real time and displayed to the operator?
Data Summary
TBC Mentors
Ryan Kare - Lead Mentor
Elam Athimoolam
import pandas
import json
pitconf = pandas.read_excel('/home/wcmckee/data/Truck_Spec.xlsx', sheetname='SiteInfo', index_col='Parameter')
rimpulldata = pandas.read_excel('/home/wcmckee/data/Truck_Spec.xlsx', sheetname='Rimpull')
print(rimpulldata)
rimpulldata
def createtruckspec(truckid, trucktype, emptyweight, maxoperatingweight):
return({'truckid' : truckid, 'TruckType' : trucktype, 'EmptyWeight' : emptyweight, 'maxoperatingweight' : maxoperatingweight})
createtruckspec(450, "789C", 114114, 317514.85)
@app.route('/getruckspec')
def getruckspec():
# give it truck id and returns back stats about that truck.
# todo: return back truck segment details also.
#localhost:5555/getruckspec?truckid=410
#returns back:
#{"EmptyWeight": 124114, "MaxOperatingWeight": 317514.85, "TruckType": "789C"}
truckid = request.args.get('truckid')
#truckid = request.args.get("truckid")
return(jsonify({'truckid' : truckid, 'EmptyWeight' : truckdicspec['EmptyWeight'][truckid],
'MaxOperatingWeight' : truckdicspec['MaxOperatingWeight'][truckid], 'TruckType' : truckdicspec['TruckType'][truckid]}))
with open('/home/wcmckee/rimpulldata.json', 'w') as rimwr:
rimwr.write(rimpulldata.to_json())
with open('/home/wcmckee/rimpulldata.json', 'r') as rimrd:
rimrda = (rimrd.read())
forjs = json.loads(rimrda)
forjs['Speed (km)']['12']
forjs['Force (kgf)']['12']
def lookrimid(rimid):
return({ 'speed' : forjs['Speed (km)'][str(rimid)], 'force' : forjs['Force (kgf)'][str(rimid)], 'id' : rimid})
lookrimid(12)
with open('/home/wcmckee/rimpulldata.json', 'r') as rimrd:
rimjsconv = (rimrd.read())
forjs = json.loads(rimjsconv)
forjs['Force (kgf)']
lookrimid(12)
print(forjs['Speed (km)'])
rimrda
for putf in pitconf.values:
print(putf)
print(pitconf)
import json
with open('/home/wcmckee/pitconfig.json', 'w') as pitw:
pitw.write(pitconf.to_json())
with open('/home/wcmckee/pitconfig.json', 'r') as pitr:
pitjs = pitr.read()
pitlo = json.loads(pitjs)
print(pitlo)
pitlo.keys()
for pitl in pitlo.values():
print(pitl['1'])
truk= pandas.read_excel('/home/wcmckee/data/Truck_Spec.xlsx', index_col='Truckid')
print(truk)
with open('/home/wcmckee/truckspec.json', 'w') as truc:
truc.write(truk.to_json())
cat /home/wcmckee/truckspec.json
with open('/home/wcmckee/truckspec.json', 'r') as truatm:
tread = truatm.read()
#print(truatm.read())
truckdicspec = json.loads(tread)
truckdicspec
truckdicspec['TruckType']['418']
def gettruck(truckid):
with open('/home/wcmckee/truckspec.json', 'r') as truatm:
tread = truatm.read()
truckdicspec = json.loads(tread)
return({'EmptyWeight' : truckdicspec['EmptyWeight'][truckid],
'MaxOperatingWeight' : truckdicspec['MaxOperatingWeight'][truckid], 'TruckType' : truckdicspec['TruckType'][truckid]})
gettruck('410')
import json
tred = json.loads(trurd.read())
#create database of trucks from existing file.
somedict = dict()
somedict.update({truk['Truck ID'] : dict({'test' : 'this is test'})})
for truk['Truck ID'] in truk:
print(truk['Truck ID'])
truk.values
truk.keys()
with open('/home/wcmckee/truckspec.json', 'r') as trurd:
#print(trurd.read())
tred = json.loads(trurd.read())
print(tred)
import sqlite3
connid = sqlite3.connect('identity.db')
connid
c = connid.cursor()
def createdb(nameofdb):
connid = sqlite3.connect('{}.db'.format(nameofdb))
c.execute('''CREATE TABLE truckspec
(truckid, trucktype, emptyweight, maxgrossoperatingweight)''')
c = connid.cursor()
c.close()
return(nameofdb)
createdb('testing')
createdb('truckspec')
c.execute('''CREATE TABLE truckspec
(truckid, trucktype, emptyweight, maxgrossoperatingweight)''')
def createtruk(truckid, trucktype, emptyweight, maxgrossoperatingweight):
connid = sqlite3.connect('truckspec.db')
c = connid.cursor()
c.execute("INSERT INTO truckspec VALUES ('{}','{}','{}', '{}')".format(truckid, trucktype, emptyweight, maxgrossoperatingweight))
connid.commit()
connid.close()
return({truckid : dict({'trucktype' : trucktype, 'emptyweight' : emptyweight,
'maxgrossoperatingweight' : maxgrossoperatingweight})})
def select_all_tasks():
"""
Query all rows in the tasks table
:param conn: the Connection object
:return:
"""
connid = sqlite3.connect('truckspec.db')
cur = connid.cursor()
cur.execute("SELECT * truckspec;")
rows = cur.fetchall()
for row in rows:
print(row)
select_all_tasks()
createtruk(420, '789C', 124114, 317514.85)
createtruk(421, '789C', 114114, 317514.85)
cat /home/wcmckee/truckspec.json
truk.to_json()
truk.sort_values(by='Truck ID')
an api on truck spec
{401 : dict({'type' : '789c', 'emptyweight' : 124114, 'maxweight' : 317514.85})}
forohon = ({401 : dict({'type' : '789c', 'emptyweight' : 124114, 'maxweight' : 317514.85})})
forohon
tru.loc[tru['Truck'] == 'TRH404']
tulo = tru.loc('TRH404')
tulo.name
print(tulo())
roadsegdata = {'Road-segment-data' : dict({'Truck' : 'ID of the 16 CAT trucks',
'Description - CR' : 'Grade the truck needs to climb',
'Payload' : 'Weight in kg excluding truck weight.',
'Start velocity' : 'Force the truck starts the grade in km/hr.',
'End velocity' : 'Force the truck exits the grade in km/hr.',
'EfhLength' : 'Not valid as it is an old measure of distance.',
'Target duration' : 'Optimal time for the truck to cover the grade in seconds.',
'Duration calculated' : 'Actual time for the truck to cover the grade in seconds.',
'Slope length' : 'Slope length(curvature distance) in meters.',
'Rise height' : 'Measure of the slope in meters.',
'StartWayPoint X,Y,Z' : 'Starting location of the grade',
'EndWayPoint X,Y,Z' : 'Ending location of the grade.'})}
print(roadsegdata)
truckcycledict = {'Truck cycle' : dict({'Date' : 'Date the data was recorded.',
'Source stage' : 'Stage the truck starts from.',
'Source bench' : 'Bench the truck starts from.',
'Destination name' : 'Unloading dump.',
'Truck' : 'ID of the 16 CAT trucks',
'Travelling empty duration' : 'Travelling time in seconds when the truck is empty. (return time duration',
'Travelling full duration' : 'Travelling time in seconds when the truck is loaded.',
'Payload' : 'Weight in kg excluding truck weight.',
'Full slope length' : 'Distance in meters from bench to dump location.',
'Empty slope length' : 'Return distance in meters.',
'Inpit ramp length' : 'Distance from the bench to the exit of the pit in meters.',
'Inpit ramp grade' : 'Inclination angle of the in-pit grade in %',
'Dump ramp length' : 'Distance from the exit of pit to the dump location.',
'Dump ramp grade' : 'Inclination angle after the exit of pit to the dump location in %.'})}
trucyc = truckcycledict['Truck cycle']
print(trucyc)
for truc in trucyc:
print(truc)
truckcycledict.update(roadsegdata)
truckcy = json.dumps(truckcycledict)
with open('/home/wcmckee/truckscycroad.json', 'w') as t:
t.write(truckcy)
with open('/home/wcmckee/truckscycroad.json', 'r') as r:
#print(r.read())
decjs = json.loads(r.read())
print({410 : dict({'Truck' : 410, 'Payload' : 100, })})
print(decjs['Road-segment-data'])
print(decjs['Truck cycle'])
cat /home/wcmckee/truckscycroad.json
for trucy in truckcycledict['Road-segment-data']:
print({trucy : dict({'example' : 'l33t', 'Description' : 'this is an example'})})
def createlocation(truck, longitude, latitude):
return({'truck' : truck, 'longitude' : longitude, 'latitude' : latitude})
import pandas
descri = pandas.read_excel('/home/wcmckee/data/Road Segment Data.xlsx')
dropcol = descri.drop('Unnamed: 0', axis=1)
with open('/home/wcmckee/roadsegdatatest.json', 'w') as roaddrop:
roaddrop.write(dropcol.to_json())
with open('/home/wcmckee/roadsegdatatest.json', 'r') as roard:
roadjsconv = roard.read()
import json
roadjslod = json.loads(roadjsconv)
import getpass
getpass.getuser()
for paka in roadjslod.keys():
print(roadjslod[paka]['127'])
startdict ={'StartWaypoint' : dict({'x' : int(samptru['StartWaypointCoordsX']),
'y' : int(samptru['StartWaypointCoordsY']),
'z' : int(samptru['StartWaypointCoordsZ']),
'velocity' : int(samptru['StartVelocity'])})}
startdict
def xyz(startx, starty, startz, startvelo, endx, endy, endz, endvelo):
return({'startwaypoint' : dict({'x' : startx,
'y' : starty,
'z' : startz,
'velocity' : startvelo}),
'endwaypoint' : dict({'x' : endx, 'y' : endy, 'z' : endz,
'velocity' : endvelo})})
xyz(86545, 36238, 1097, 13, 86578, 36354, 1097, 13)
endist = {'EndWaypoint' : dict({'x' : int(samptru['EndWaypointCoordsX']),
'y' : int(samptru['EndWaypointCoordsY']),
'z' : int(samptru['StartWaypointCoordsZ']),
'velocity' : int(samptru['EndVelocity'])})}
startdict.update(endist)
{'stats' : dict({'Description-CR' : samptru['Description-CR']})}
samdes = samptru['Description-CR']
import requests
reqge = requests.get('https://geocode.xyz/51.50354,-0.12768')
rejs = (reqge.json)
print(str(rejs))
print(dict({'truck' : truck, dict({'startwaypoint' : {'longitude' : int(samptru['StartWaypointCoordsX'], 'latitude' : int(samptru['StartWaypointCoordsY']))}}
print ({'truck' : 402, dict({'startwaypoint' : dict({'longitude' : 1, 'latitude' : 3})})
{'startwaypoint' : dict({'longitude' : 1, 'latitude' : 3})}
trukxlc = pandas.read_excel('/home/wcmckee/data/Scenario1.xlsx')
print(trukxlc['Destination 1'])
trukcyc = pandas.read_csv('/home/wcmckee/data/Truck Cycle.csv', index_col='Truck')
for trkey in trukcyc.keys():
trk = (trkey.replace(' ', '-'))
print(trk.lower())
import json
import random
print(truckdicspec)
with open('/home/wcmckee/truckspec.json', 'r') as truatm:
tread = truatm.read()
truckdicspec = json.loads(tread)
truckid = random.choice(truckdicspec)
truits = trukcyc.iteritems()
somedict = dict()
somedict
somelis = list()
for tru in truits:
#print(tru)
somelis.append(tru)
#somedict.update({tru : tru})
for somel in somelis:
print(somel)
for somel in somelis:
print(somel)
import random
random.choice()
def createtruckcyc(date, sourcestage, sourcebench, destinationname,
travellingemptyduration, travellingfullduration, payload,
fullslopelength, emptyslopelength, inpitramplength,
inpitrampgrade, dumpramplength, dumprampgrade):
return (dict({'date' : date, 'sourcestage' : sourcebench, 'sourcebench' : sourcebench,
'destinationname' : destinationname,
'travellingemptyduration' : travellingemptyduration,
'travellingfullduration' : travellingfullduration,
'payload' : payload, 'fullslopelength' : fullslopelength,
'emptyslopelength' : emptyslopelength,
'inpitramplength' : inpitramplength,
'inpitrampgrade' : inpitrampgrade, 'dumpramplength' : dumpramplength,
'dumprampgrade' : dumprampgrade}))
import arrow
timnow = arrow.now()
print(timnow)
str(timnow.date())
'9.34%', 336.00, '8.33%'
createtruckcyc('01/01/2017', 'Stage G', '920', 'MW_PRIME', 0.0, 1009, 179.7, 3888.21, 3888.21,
42.94, 3108.02, '9.34%', 336.00, '8.33%')
trjs = trukcyc.to_json
with open('/home/wcmckee/truckdetail.json', 'w') as truckdet:
truckdet.write(trjs)
trukd = pandas.read_json('/home/wcmckee/truckdetail.json')
trukcyc.to_json
trujsn = (trukcyc.to_json)
trujsn
trujsn
with open('/home/wcmckee/truckinfo.json', 'w') as truwri:
truwri.write(str(trujsn))
cat /home/wcmckee/truckinfo.json
import arrow
def mkblogpost(blogpath, postname, tagblog):
raw = arrow.now()
fultim = raw.datetime
if postname + '.md' not in os.listdir(blogpath + '/posts'):
with open(blogpath + '/posts/' + postname + '.meta', 'w') as daympo:
daympo.write('.. title: {}\n.. slug: {}\n.. date: {}\n.. tags: {}\n.. link:\n.. description:\n.. type: text'.format(postname, postname, fultim, tagblog))
with open(blogpath + '/posts/' + postname + '.md', 'w') as daymark:
for toar in os.listdir(blogpath + '/galleries/' + raw.strftime("%Y") + '/' + raw.strftime("%m") + '/' + raw.strftime('%d')):
daymark.write('\n\n'.format(toar.replace('.png', ''), '/galleries/' + raw.strftime("%Y") + '/' + raw.strftime("%m") + '/' + raw.strftime('%d') + '/', toar))
print(trukcyc['Destination name'])
from flask import Flask, request, jsonify
import json
import getpass
myusr = getpass.getuser()
homepath = '/home/{}'.format(myusr)
app = Flask(__name__)
with open('{}/truckspec.json'.format(homepath), 'r') as truatm:
#opens the truck spec json file.
tread = truatm.read()
truckdicspec = json.loads(tread)
with open('{}/roadsegdatatest.json'.format(homepath), 'r') as roard:
#opens the road seg data
roadjsconv = roard.read()
roadjslod = json.loads(roadjsconv)
@app.route('/getruckspec')
def getruckspec():
# give it truck id and returns back stats about that truck.
# todo: return back truck segment details also.
#localhost:5555/getruckspec?truckid=410
#returns back:
#{"EmptyWeight": 124114, "MaxOperatingWeight": 317514.85, "TruckType": "789C"}
truckid = request.args.get('truckid')
#truckid = request.args.get("truckid")
return(jsonify({'EmptyWeight' : truckdicspec['EmptyWeight'][truckid],
'MaxOperatingWeight' : truckdicspec['MaxOperatingWeight'][truckid], 'TruckType' : truckdicspec['TruckType'][truckid]}))
@app.route('/getroadsegid')
def getroadsegid():
#localhost:5555/getroadsegid?segid=95
#give it id and return back road segiment details.
'''
returns back: {
"Description-CR": "GRD25-GRD26",
"DurationCalculated": 28.0,
"EfhLength": 157.9984208252,
"EndVelocity": 21.9239999982,
"EndWaypointCoordsX": 85976.84,
"EndWaypointCoordsY": 36378.8,
"EndWaypointCoordsZ_Q-CR": 885.02,
"LoadStateDirection_D-CR": "Reverse traversal full",
"Payload": 170900,
"RiseHeight": 0.15,
"SlopeLength": 148.8954144547,
"StartVelocity": 13.3919999989,
"StartWaypointCoordsX": 85987.63,
"StartWaypointCoordsY": 36257.25,
"StartWaypointCoordsZ": 885.05,
"TargetDuration": 11,
"Truck": "TRH405"
}
'''
segid = request.args.get('segid')
newdict = dict()
for paka in roadjslod.keys():
newdict.update({paka : roadjslod[paka][segid]})
return(jsonify(newdict))
#return('everything worked')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5555)
from flask import Flask, request, jsonify
import json
import getpass
myusr = getpass.getuser()
homepath = '/home/{}'.format(myusr)
app = Flask(__name__)
with open('{}/truckspec.json'.format(homepath), 'r') as truatm:
#opens the truck spec json file.
tread = truatm.read()
truckdicspec = json.loads(tread)
with open('{}/roadsegdatatest.json'.format(homepath), 'r') as roard:
#opens the road seg data
roadjsconv = roard.read()
roadjslod = json.loads(roadjsconv)
@app.route('/getruckspec')
def getruckspec():
# give it truck id and returns back stats about that truck.
# todo: return back truck segment details also.
#localhost:5555/getruckspec?truckid=410
#returns back:
#{"EmptyWeight": 124114, "MaxOperatingWeight": 317514.85, "TruckType": "789C"}
truckid = request.args.get('truckid')
#truckid = request.args.get("truckid")
return(jsonify({'EmptyWeight' : truckdicspec['EmptyWeight'][truckid],
'MaxOperatingWeight' : truckdicspec['MaxOperatingWeight'][truckid], 'TruckType' : truckdicspec['TruckType'][truckid]}))
@app.route('/getroadsegid')
def getroadsegid():
#localhost:5555/getroadsegid?segid=95
#give it id and return back road segiment details.
'''
returns back: {
"Description-CR": "GRD25-GRD26",
"DurationCalculated": 28.0,
"EfhLength": 157.9984208252,
"EndVelocity": 21.9239999982,
"EndWaypointCoordsX": 85976.84,
"EndWaypointCoordsY": 36378.8,
"EndWaypointCoordsZ_Q-CR": 885.02,
"LoadStateDirection_D-CR": "Reverse traversal full",
"Payload": 170900,
"RiseHeight": 0.15,
"SlopeLength": 148.8954144547,
"StartVelocity": 13.3919999989,
"StartWaypointCoordsX": 85987.63,
"StartWaypointCoordsY": 36257.25,
"StartWaypointCoordsZ": 885.05,
"TargetDuration": 11,
"Truck": "TRH405"
}
'''
segid = request.args.get('segid')
newdict = dict()
for paka in roadjslod.keys():
newdict.update({paka : roadjslod[paka][segid]})
return(jsonify(newdict))
#return('everything worked')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5555)
Comments
Comments powered by Disqus