Robotic Arm Videos

In spring 2009 I worked on contract project to build prototype software to plug in an electric vehicle charging connector into the socket on the vehicle.  The hardware consisted of a 3-DOF robotic arm with a mid-range Logitech web camera mounted on the end effector.  The algorithm scanned the camera image for a high-visibility target of known shape and size, computed the 3-d position in space relative to the end-effector and the inverse-kinematics to perform the plug-in action.

https://drive.google.com/file/d/0B2LAwxoQeIZiMTIwQjEwNTRFMjlDMkY2OTowLjM/view?usp=sharing

https://drive.google.com/file/d/0B2LAwxoQeIZiMTIwQjEwNTRFMjlDMkY2OTowLjI/view?usp=sharing

 

 

US Patent – System and method for detecting vehicle proximity in an electrical vehicle supply equipment

US9440549B2 – System and method for detecting vehicle proximity in an electrical vehicle supply equipment – Google Patents

A system and method is provided for detecting vehicle proximity in an electric vehicle supply equipment (EVSE). A sensor may be configured to detect a presence of a vehicle within a predetermined distance of the EVSE. A processor may be configured to determine that the vehicle is in proximity of the EVSE in response to the sensor detecting the presence of the vehicle.

US Patent: System and Method for Remote Payment for an Electric Vehicle Charging Station

US20140164196A1 – System and Method for Remote Payment for an Electric Vehicle Charging Station – Google Patents

A system and method is provided for billing transactions associated with an electric vehicle charging station (EVCS). A server may receive a station identifier associated with the EVCS from a computing device. The station identifier may be retrieved by decoding a code at the computing device.

During my tenure at SemaConnect, I’ve contributed to a number of patent applications, a few of which have been granted.

Acknowledgement

A shout out to Nicolas Pinto for the acknowledgement for some contract work I did back in 2009.   https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2775908/

Canesta 3-d imaging camera contest award.

Of note

Amy D. Waterman, Ph.D., Gerhild Williams, Ph.D., Paul S.G. Stein, Ph.D., John Heil, Ph.D., Chengjie Xiong, Ph.D., and more…

Relevant excerpt:

Roman Stanchak and Michael Dixon, graduate students working with Robert Pless, Ph.D., assistant professor of computer science and engineering, in the Media and Machines laboratory, each received a Canesta 3-D imaging camera for their research paper as part of a national contest. Each camera is worth $7,500. …

Using Protocol Buffers, Python and Mako for code generation.

Working on the SemaConnect EV charging station firmware over the past 8-9 years, I’ve written a lot of C code.   While I like C, I do not like writing boilerplate code. It is time-consuming and error-prone.  So I automate.

One strategy that I’ve adopted is using the Protocol Buffer language to specify interfaces, and transforming these into code using the python protobuf extension and  the mako template language.

#!/usr/bin/env python
import sys
import os
import types
from mako.template import Template
from mako.lookup import TemplateLookup
from google.protobuf.descriptor import ServiceDescriptor, EnumDescriptor, FieldDescriptor

def flatten( l ):
return [item for sublist in l for item in sublist]

sys.path.append( os.path.dirname(sys.argv[1]))
pbmod = __import__( os.path.basename(sys.argv[1]).split('.')[0])

# extract services, enums
services=[]
enums=[]
for name, desc in pbmod.__dict__.items():
if type(desc)==ServiceDescriptor:
services.append( desc )
elif str(type(desc)).find('EnumDescriptor')>=0:
enums.append( desc )
elif type(desc)==types.ModuleType and name.endswith('pb2'):
pass

# extract messages
messages = pbmod.DESCRIPTOR.message_types_by_name.values()

# sort message types so that if a depends on b,
# b appears before a in the list
def messages_sorted_by_dependency( msgs ):
sorted_msgs = [msg for msg in msgs]
for i in xrange(len(sorted_msgs)):
for j in xrange(len(sorted_msgs)):
for k in xrange(j, len(sorted_msgs)):
for field in sorted_msgs[j].fields:
if (field.type == FieldDescriptor.TYPE_MESSAGE and
field.message_type.name == sorted_msgs[k].name ):
# swap if a field in j depends on k
tmp = sorted_msgs[j]
sorted_msgs[j] = sorted_msgs[k]
sorted_msgs[k] = tmp
break

return sorted_msgs

messages = messages_sorted_by_dependency( pbmod.DESCRIPTOR.message_types_by_name.values() )

imports=set()
for message in messages:
for field in message.fields:
if field.type==FieldDescriptor.TYPE_MESSAGE:
fpkg = field.message_type.file
if fpkg != pbmod.DESCRIPTOR:
imports.add( fpkg )

outfname = sys.argv[3]
tmpl_fname = sys.argv[2]

mylookup = TemplateLookup(directories=['/'])
tmpl = Template(filename=tmpl_fname, lookup=mylookup)
output = tmpl.render( pbmod=pbmod, descriptor=pbmod.DESCRIPTOR, messages=messages, services=services, enums=enums, imports=imports)
open(outfname,"w").write( output )
print("Wrote " + outfname)
<% # some definitions package = descriptor.package PACKAGE = package.upper() # def fullname(T): return T.full_name.replace('.','_') %>
#ifndef ${PACKAGE}_H
#define ${PACKAGE}_H

%for enum in enums:                                                                                                                                                                                                              
enum ${fullname(enum)}                                                                                                                                                                                                    
{                                                                                                                                                                                                                                
%for enum_value in enum.values:                                                                                                                                                                                                  
    ${package}_${enum_value.name} = ${enum_value.number},                                                                                                                                                                        
%endfor                                                                                                                                                                                                                          
};                                                                                                                                                                                                                               
#define ${fullname(enum)}_MIN ${min(map(lambda x: x.number, enum.values))}                                                                                                                                                       
#define ${fullname(enum)}_MAX ${max(map(lambda x: x.number, enum.values))}                                                                                                                                                       
%endfor  
// END enum types

#endif // ${PACKAGE}_H