diff --git a/rocolib/__main__.py b/rocolib/__main__.py
index d00adae95801fad51b7bfce019df138935f3d0ab..32c397df2f6e1e1c86ab2d47226055a938769d74 100644
--- a/rocolib/__main__.py
+++ b/rocolib/__main__.py
@@ -15,7 +15,12 @@ def test(component, params, thickness, outdir=None, display=False):
     f = getComponent(component)
     if params is not None:
         for p in params:
-            f.setParameter(p[0], eval(str(p[1])))
+            try:
+                v = eval(str(p[1]))
+            except NameError:
+                # Using a string as a dimensions parameter
+                v = str(p[1])
+            f.setParameter(p[0], v)
     if thickness is None:
         t = 0
         j = None
@@ -39,7 +44,7 @@ def test(component, params, thickness, outdir=None, display=False):
         app.layout = html
         app.run_server(debug=True)
 
-if __name__ == '__main__':
+def cli_argparse():
     LOG_LEVELS = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
     DEFAULT_LOG_LEVEL = "WARNING"
 
@@ -136,3 +141,6 @@ if __name__ == '__main__':
     if not acted:
         parser.print_help(sys.stderr)
         sys.exit(1)
+
+if __name__ == '__main__':
+    cli_argparse()
diff --git a/rocolib/api/components/Component.py b/rocolib/api/components/Component.py
index d5ca60d6bad3567aadf2468f8749731ceb8d1091..b94d56c7e8bfc6364b717c53ddbc7f00aa895b74 100644
--- a/rocolib/api/components/Component.py
+++ b/rocolib/api/components/Component.py
@@ -278,10 +278,10 @@ class Component(Parameterized):
 
         fromPort = self.getInterfaces(*fromInterface)
         toPort = self.getInterfaces(*toInterface)
-        if fromPort.canMate(toPort):
+        if fromPort.canMate(toPort) or toPort.canMate(fromPort):
             self.connections.setdefault(name, [fromInterface, toInterface, kwargs])
         else:
-            raise AttributeError(f"{fromInterface} cannot connect to {toInterface} according to getMate")
+            raise AttributeError(f"{fromInterface} ({fromPort} : {type(fromPort)}) cannot connect to {toInterface} ({toPort} : {type(toPort)}) according to getMate")
 
     def delConnection(self, name):
       self.connections.pop(name)
diff --git a/rocolib/api/composables/graph/Face.py b/rocolib/api/composables/graph/Face.py
index 9be77bb764f586e3d41468dd1833095a0572f0d6..78b5579d7e69fb7f1d876a026e2d262d5fa7756a 100644
--- a/rocolib/api/composables/graph/Face.py
+++ b/rocolib/api/composables/graph/Face.py
@@ -220,8 +220,11 @@ class Face(object):
   def addDecoration(self, pts):
     self.decorations.append(pts)
 
-  def addFace(self, face, transform):
+  def addFace(self, face, transform, copyDecorations=False):
     self.joinedFaces.append((face, transform))
+    if copyDecorations:
+      for d in self.decorations:
+        face.addDecoration(d)
 
   def preTransform(self, edge):
     index = self.edges.index(edge)
diff --git a/rocolib/api/composables/graph/Graph.py b/rocolib/api/composables/graph/Graph.py
index 5f11f921b3f034ad8fbcdf56bcc501510771b4c3..e8830da8118a31593586ce8550d3ef90b449394f 100644
--- a/rocolib/api/composables/graph/Graph.py
+++ b/rocolib/api/composables/graph/Graph.py
@@ -117,13 +117,14 @@ class Graph():
         self.addFace(toFace, prefix)
         self.mergeFace(fromFace, toFace.name, transform)
 
-    def mergeFace(self, fromFaceName, toFaceName, transform=None):
+    def mergeFace(self, fromFaceName, toFaceName, transform=None, offset=(0,0), copyDecorations=False):
         fromFace = self.getFace(fromFaceName)
         toFace = self.getFace(toFaceName)
+        toFace.transform(origin=offset)
         if transform is None:
                 transform = np.eye(4)
-        fromFace.addFace(toFace, transform)
-        toFace.addFace(fromFace, np.inv(transform))
+        fromFace.addFace(toFace, transform, copyDecorations)
+        toFace.addFace(fromFace, np.inv(transform), copyDecorations)
 
     def attachEdge(self, fromEdge, newFace, newEdge, prefix=None, root=False, angle=0, edgeType=None, joints=None):
         # XXX should set angle from a face, not absolute angle of the face
diff --git a/rocolib/api/ports/EdgePort.py b/rocolib/api/ports/EdgePort.py
index b4babc965cb6aa94912d080e62d632e3808072e2..7d07f05d9e2a28bb77f554d06cc81bc6e0f28e43 100644
--- a/rocolib/api/ports/EdgePort.py
+++ b/rocolib/api/ports/EdgePort.py
@@ -36,13 +36,14 @@ class EdgePort(Port):
     def toString(self):
         return str(self.getEdges())
 
-
     def attachTo(self, toPort, **kwargs):
         if isinstance(toPort, EdgePort):
             label1 = self.getEdges()
             label2 = toPort.getEdges()
 
-            for i in range(len(label1)):
+            numedges = len(label1)
+
+            for i in range(numedges):
                 newargs = {}
                 for key, value in kwargs.items():
                     if isinstance(value, (list, tuple)):
@@ -50,7 +51,7 @@ class EdgePort(Port):
                     else:
                         newargs[key] = value
                 try:
-                    self.graph.mergeEdge(label1[i], label2[i], **newargs)
+                    self.graph.mergeEdge(label1[i], label2[numedges-i-1], **newargs)
                 except AttributeError:
                     # Edge not found, skipping
                     pass
diff --git a/rocolib/api/ports/FacePort.py b/rocolib/api/ports/FacePort.py
index 808c68c0937af140688ad4b319f008a39d526a57..a857981fa5b0147195cd71a2db4a0b31f8b41524 100644
--- a/rocolib/api/ports/FacePort.py
+++ b/rocolib/api/ports/FacePort.py
@@ -1,5 +1,7 @@
 from rocolib.api.ports import Port
 from rocolib.utils.utils import prefix as prefixString
+from rocolib.utils.numsym import deg2rad
+from rocolib.utils.transforms import RotateX
 
 class FacePort(Port):
   def __init__(self, parent, graph, face):
@@ -39,4 +41,8 @@ class FacePort(Port):
     if isinstance(toPort, FacePort):
       face1 = self.graph.getFace(self.getFaceName())
       face2 = self.graph.getFace(toPort.getFaceName())
-      self.graph.mergeFace(face1.name, face2.name)
+      if kwargs.get("flip"):
+        transform = RotateX(deg2rad(180))
+      else:
+        transform = None
+      self.graph.mergeFace(face1.name, face2.name, transform=transform, offset=kwargs.get("offset", (0,0)), copyDecorations=True)
diff --git a/rocolib/builders/ESPSegBuilder.py b/rocolib/builders/ESPSegBuilder.py
index d545bef8544067cdcc75cb3337f9d22cdca968ae..6ba94f413edce0ccc1fa15ff866b8d29d45f7559 100644
--- a/rocolib/builders/ESPSegBuilder.py
+++ b/rocolib/builders/ESPSegBuilder.py
@@ -43,10 +43,10 @@ c.addConstConstraint(("right","flip"), True)
 
 # connections
 c.addConnection(("brain", "topedge0"),
-                ("right", "botedge0"),
+                ("right", "topedge0"),
                 angle=-90)
 c.addConnection(("brain", "botedge0"),
-                ("left", "topedge0"),
+                ("left", "botedge0"),
                 angle=-90)
 
 # Sheath
@@ -65,7 +65,7 @@ c.addConstraint(("sheathsplit","botlength"), ("driveservo", "width"),
           x[1] - 2*getDim(x[0],'motorheight'), \
           getDim(x[0],'motorheight'))")
 
-c.addConnection(("left", "botedge1"),
+c.addConnection(("left", "topedge1"),
                 ("sheathsplit", "botedge2"),
                 angle=180)
 
@@ -76,7 +76,7 @@ c.addConnection(("right", "botedge1"),
 '''
 
 c.addConnection(("sheathsplit", "topedge0"),
-                ("sheath", "topedge1"))
+                ("sheath", "botedge1"))
 
 # Tail
 c.addSubcomponent("tail", "Tail", inherit=("flapwidth", "tailwidth"), prefix=None)
@@ -85,14 +85,14 @@ c.addConstraint(("tail","height"), *depthfn(["height"], "%s/2.+x[2]"))
 c.addConstraint(("tail","depth"), *depthfn(["battery"], "%s+x[2]"))
 
 c.addConnection(("tail", "topedge"),
-                ("sheath", "botedge1"),
+                ("sheath", "topedge1"),
                 angle=90)
 
 c.addSubcomponent("tailsplit", "SplitEdge")
 c.addConstraint(("tailsplit","toplength"), "width", "(x,)")
 c.addConstraint(("tailsplit","botlength"), ("width", "flapwidth"), "(x[0]*(1-x[1])/2., x[0]*x[1], x[0]*(1-x[1])/2.)")
 
-c.addConnection(("sheath", "botedge3"),
+c.addConnection(("sheath", "topedge3"),
                 ("tailsplit", "topedge0"))
 
 c.addConnection(("tail", "flapedge"),
diff --git a/rocolib/builders/MountedServoBuilder.py b/rocolib/builders/MountedServoBuilder.py
index e1e8fda87d574025130b1e8cf0248460efd56b32..305bfa7bc6639694d6f7d4607c59696368a68d4e 100644
--- a/rocolib/builders/MountedServoBuilder.py
+++ b/rocolib/builders/MountedServoBuilder.py
@@ -9,6 +9,6 @@ c.addSubcomponent("servo", "ServoMotor", inherit=True, prefix=None)
 c.inheritAllInterfaces("mount", prefix=None)
 c.inheritAllInterfaces("servo", prefix=None)
 c.addConnection(("mount", "mount.decoration"),
-                ("servo", "horn"))
+                ("servo", "mount"))
 
 c.toLibrary("MountedServo")
diff --git a/rocolib/builders/WheelBuilder.py b/rocolib/builders/WheelBuilder.py
index 3dd5384055404ddd00d536b01b5f5224ccdd1fde..9ee698fcdf63e5993b80114928af382abf303a67 100644
--- a/rocolib/builders/WheelBuilder.py
+++ b/rocolib/builders/WheelBuilder.py
@@ -8,7 +8,7 @@ c.addSubcomponent("tire", "Tire", inherit="radius tire_thickness".split(), prefi
 
 
 c.inheritAllInterfaces("drive", prefix=None)
-c.addConnection(("drive", "mount"),
+c.addConnection(("drive", "horn"),
                 ("tire", "face"))
 
 c.toLibrary("Wheel")
diff --git a/rocolib/library/ESPSeg.yaml b/rocolib/library/ESPSeg.yaml
index 0c84eb9d1b85634930a8f32bb69daa7ec70dfc30..77254a21aa4fd5f5f3c46944144e1a5739afc904 100644
--- a/rocolib/library/ESPSeg.yaml
+++ b/rocolib/library/ESPSeg.yaml
@@ -3,17 +3,17 @@ connections:
   - - brain
     - topedge0
   - - right
-    - botedge0
+    - topedge0
   - angle: -90
   connection1:
   - - brain
     - botedge0
   - - left
-    - topedge0
+    - botedge0
   - angle: -90
   connection2:
   - - left
-    - botedge1
+    - topedge1
   - - sheathsplit
     - botedge2
   - angle: 180
@@ -21,17 +21,17 @@ connections:
   - - sheathsplit
     - topedge0
   - - sheath
-    - topedge1
+    - botedge1
   - {}
   connection4:
   - - tail
     - topedge
   - - sheath
-    - botedge1
+    - topedge1
   - angle: 90
   connection5:
   - - sheath
-    - botedge3
+    - topedge3
   - - tailsplit
     - topedge0
   - {}
diff --git a/rocolib/library/MountedServo.yaml b/rocolib/library/MountedServo.yaml
index 3a41255ee69f0452b4ae6e4a4b7f373f2b239608..aaaa270f888997a30548a631d78a58d8ed5baa9a 100644
--- a/rocolib/library/MountedServo.yaml
+++ b/rocolib/library/MountedServo.yaml
@@ -3,7 +3,7 @@ connections:
   - - mount
     - mount.decoration
   - - servo
-    - horn
+    - mount
   - {}
 interfaces:
   botedge0:
diff --git a/rocolib/library/ServoMotor.py b/rocolib/library/ServoMotor.py
index 5881e47e4152317542664da196de296caf222703..954d2a97de209b5d2389449824e6c18022b3f4ab 100644
--- a/rocolib/library/ServoMotor.py
+++ b/rocolib/library/ServoMotor.py
@@ -1,6 +1,7 @@
 from rocolib.api.components import FoldedComponent
 from rocolib.api.composables.graph.Face import Rectangle as Shape
 from rocolib.api.ports import AnchorPort
+from rocolib.utils.utils import decorateGraph
 from rocolib.utils.dimensions import getDim
 from rocolib.utils.transforms import Translate, RotateZ
 from rocolib.utils.numsym import dot
@@ -10,16 +11,19 @@ class ServoMotor(FoldedComponent):
   def define(self):
     self.addParameter("angle", 0, paramType="angle", minValue=None, maxValue=None)
     self.addParameter("servo", "fs90r", paramType="dimension")
-    self.addInterface("horn", AnchorPort(self, self.getGraph(), "h", Translate([0,0,0])))
-    self.addFaceInterface("mount", "h")
+    self.addInterface("mount", AnchorPort(self, self.getGraph(), "horn", Translate([0,0,0])))
+    self.addFaceInterface("horn", "horn")
 
   def assemble(self):
     s = self.getParameter("servo")
     a = self.getParameter("angle")
     dz = getDim(s, "hornheight")
+    dy = getDim(s, "motorlength") / 2 - getDim(s, "hornoffset")
 
-    self.addFace(Shape("h", 0, 0))
-    self.setInterface("horn", AnchorPort(self, self.getGraph(), "h", dot(RotateZ(a), Translate([0,0,dz]))))
+    f = Shape("horn", 0, 0)
+    decorateGraph(f, Shape("hole", 1, 1))
+    self.addFace(f)
+    self.setInterface("mount", AnchorPort(self, self.getGraph(), "horn", dot(RotateZ(a), Translate([0,-dy,dz]))))
 
 if __name__ == "__main__":
     ServoMotor.test()
diff --git a/rocolib/library/SimpleRectBeam.py b/rocolib/library/SimpleRectBeam.py
index 841762a26155c9f83ffb9d447bcb85568f30bf42..46b14c2fc6c8f48740a65edda7e4ceb5f6adcb63 100644
--- a/rocolib/library/SimpleRectBeam.py
+++ b/rocolib/library/SimpleRectBeam.py
@@ -10,8 +10,8 @@ class SimpleRectBeam(FoldedComponent):
     self.addParameter("addTabs", True, valueType="bool")
 
     for i in range(4):
-      self.addEdgeInterface("topedge%d" % i, "r%d.e0" % i, ["width", "depth"][i % 2])
-      self.addEdgeInterface("botedge%d" % i, "r%d.e2" % i, ["width", "depth"][i % 2])
+      self.addEdgeInterface("topedge%d" % i, "r%d.e2" % i, ["width", "depth"][i % 2])
+      self.addEdgeInterface("botedge%d" % i, "r%d.e0" % i, ["width", "depth"][i % 2])
       self.addFaceInterface("face%d" % i, "r%d" % i)
     self.addEdgeInterface("slotedge", "r3.e1", "length")
     self.addEdgeInterface("tabedge", "r0.e3", "length")
diff --git a/rocolib/library/Wheel.yaml b/rocolib/library/Wheel.yaml
index ed257d986c91906f882668734584376ecbb92dec..7f2f80227f316a0a8603bf71d8e0b2d849e6bc8f 100644
--- a/rocolib/library/Wheel.yaml
+++ b/rocolib/library/Wheel.yaml
@@ -1,7 +1,7 @@
 connections:
   connection0:
   - - drive
-    - mount
+    - horn
   - - tire
     - face
   - {}
diff --git a/rocolib/utils/dimensions.py b/rocolib/utils/dimensions.py
index f54306ff40c4381180b794abfdea383c02a07366..4d87f57f6335a69363889b7f6f15bd43d22ed6e9 100644
--- a/rocolib/utils/dimensions.py
+++ b/rocolib/utils/dimensions.py
@@ -86,6 +86,17 @@ Should horn be a different object?
 
 '''
 
+dims["ds2g"] = { "type" : "servo",
+    "motorlength"   : 17,
+    "motorwidth"    : 8.5,
+    "motorheight"   : 11,
+    "shoulderlength": 3.5,
+    "hornlength"    : 11,
+    "hornheight"    : 9,
+    "hornoffset"    : 4,
+    "horndepth"     : 1,
+}
+
 dims["s4303r"] = { "type" : "servo",
     "motorlength"   : 31,
     "motorwidth"    : 17,
diff --git a/rocolib/utils/numsym.py b/rocolib/utils/numsym.py
index 920417cdcbf13d939c473f07882bb8f0421fdac5..18a97ba5d3ef99208fffeda64d1f0a057f2f79b8 100644
--- a/rocolib/utils/numsym.py
+++ b/rocolib/utils/numsym.py
@@ -19,7 +19,7 @@ def cumsum(iterable):
 
 # Numpy mods
 def numpy_rows(x):
-    return x.shape[0]
+    return numpy.array(x)
   
 def numpy_N(x):
     return x
@@ -79,9 +79,6 @@ def sympy_difference(pts1, pts2):
 def sympy_dex(pts1, pts2, tol):
     return sympy_difference(pts1, pts2) > tol
 
-def sympy_rows(x):
-    return x.rows
-
 def sympy_pi():
     return sympy.pi
 
diff --git a/setup.py b/setup.py
index 20bcdf0b4d0b6249944d0c91638363899130a6ea..c17117ffeb993ef68fb85d51ff2441a0b73e8dbb 100644
--- a/setup.py
+++ b/setup.py
@@ -52,4 +52,9 @@ setup(
         'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)',
         'Programming Language :: Python :: 3',
     ],
+    entry_points={
+        'console_scripts': [
+            'roco = rocolib.__main__:cli_argparse',
+        ]
+    },
 )