diff --git a/assembly.py b/assembly.py
index d30c384..a25bcd3 100644
--- a/assembly.py
+++ b/assembly.py
@@ -1553,6 +1553,77 @@ class AsmRelationGroup(AsmBase):
         obj.purgeTouched()
         return obj
 
+    @staticmethod
+    def gotoRelationOfConstraint(obj,subname):
+        sub = Part.splitSubname(subname)[0].split('.')
+        sobj = obj.getSubObject(subname,retType=1)
+        if isTypeOf(sobj,AsmElementLink):
+            sobj = sobj.parent.Object
+            sub = sub[:-2]
+        else:
+            sub = sub[:-1]
+        if not isTypeOf(sobj,AsmConstraint):
+            return
+        sub[-2] = '3'
+        sub[-1] = ''
+        sub = '.'.join(sub)
+        subs = []
+        relationGroup = sobj.Proxy.getAssembly().getRelationGroup(True)
+        for relation in relationGroup.Proxy.getRelations().values():
+            for o in relation.Group:
+                if isTypeOf(o,AsmRelation):
+                    found = False
+                    for child in o.Group:
+                        if child == sobj:
+                            subs.append('{}{}.{}.{}.'.format(
+                                sub,relation.Name,o.Name,child.Name))
+                            found = True
+                            break
+                    if found:
+                        continue
+                elif o == sobj:
+                    subs.append('{}{}.{}.'.format(sub,relation.Name,o.Name))
+
+        if subs:
+            FreeCADGui.Selection.pushSelStack()
+            FreeCADGui.Selection.clearSelection()
+            FreeCADGui.Selection.addSelection(obj,subs)
+            FreeCADGui.Selection.pushSelStack()
+            FreeCADGui.runCommand('Std_TreeSelection')
+
+    @staticmethod
+    def gotoRelation(moveInfo):
+        if not moveInfo:
+            return
+        info = moveInfo.ElementInfo
+        if info.Subname:
+            subs = moveInfo.SelSubname[:-len(info.Subname)]
+        else:
+            subs = moveInfo.SelSubname
+        subs = subs.split('.')
+        relationGroup = resolveAssembly(info.Parent).getRelationGroup()
+        if isinstance(info.Part,tuple):
+            part = info.Part[0]
+        else:
+            part = info.Part
+        relation = relationGroup.Proxy.findRelation(part)
+        if not relation:
+            return
+        if isinstance(info.Part,tuple):
+            if len(subs)<4:
+                subs.append('')
+            subs[-4] = '3'
+            subs[-3] = relation.Name
+            subs[-2] = relation.Group[info.Part[1]].Name
+        else:
+            subs[-3] = '3'
+            subs[-2] = relation.Name
+        FreeCADGui.Selection.pushSelStack()
+        FreeCADGui.Selection.clearSelection()
+        FreeCADGui.Selection.addSelection(moveInfo.SelObj,'.'.join(subs))
+        FreeCADGui.Selection.pushSelStack()
+        FreeCADGui.runCommand('Std_TreeSelection')
+
 
 class ViewProviderAsmRelationGroup(ViewProviderAsmBase):
     _iconName = 'Assembly_Assembly_Relation_Tree.svg'
@@ -1587,6 +1658,18 @@ class AsmRelation(AsmBase):
         obj.setPropertyStatus('Group','Hidden')
         super(AsmRelation,self).attach(obj)
 
+    def getSubObject(self,obj,subname,retType,mat,transform,depth):
+        if not subname or subname[0]==';':
+            return False
+        idx = subname.find('.')
+        if idx<0:
+            return False
+        name = subname[:idx]
+        for o in obj.Group:
+            if o.Name == name:
+                return o.getSubObject(subname[idx+1:],
+                        retType,mat,transform,depth+1)
+
     def getAssembly(self):
         return self.parent.getAssembly()
 
diff --git a/gui.py b/gui.py
index 9bee924..2153c92 100644
--- a/gui.py
+++ b/gui.py
@@ -231,31 +231,48 @@ class AsmCmdMove(AsmCmdBase):
     _id = 2
     _menuText = 'Move part'
     _iconName = 'Assembly_Move.svg'
-    _useCenterballDragger = True
     _accel = 'A, M'
+    _moveInfo = None
 
     @classmethod
     def Activated(cls):
         from . import mover
-        mover.movePart(cls._useCenterballDragger)
+        mover.movePart(True,cls._moveInfo)
+
+    @classmethod
+    def canMove(cls):
+        from . import mover
+        cls._moveInfo = None
+        cls._moveInfo = mover.getMovingElementInfo()
+        mover.checkFixedPart(cls._moveInfo.ElementInfo)
+        return True
 
     @classmethod
     def checkActive(cls):
-        from . import mover
-        cls._active = mover.canMovePart()
+        cls._active = logger.catchTrace('',cls.canMove)
 
     @classmethod
     def onClearSelection(cls):
         cls._active = False
+        cls._moveInfo = None
 
-class AsmCmdAxialMove(AsmCmdMove):
+class AsmCmdAxialMove(AsmCmdBase):
     _id = 3
     _menuText = 'Axial move part'
     _iconName = 'Assembly_AxialMove.svg'
     _useCenterballDragger = False
     _accel = 'A, A'
 
-class AsmCmdQuickMove(AsmCmdBase):
+    @classmethod
+    def IsActive(cls):
+        return AsmCmdMove.IsActive()
+
+    @classmethod
+    def Activated(cls):
+        from . import mover
+        mover.movePart(False,AsmCmdMove._moveInfo)
+
+class AsmCmdQuickMove(AsmCmdAxialMove):
     _id = 13
     _menuText = 'Quick move'
     _tooltip = 'Bring an object contained in an assembly to where the mouse\n'\
@@ -269,15 +286,6 @@ class AsmCmdQuickMove(AsmCmdBase):
         from . import mover
         mover.quickMove()
 
-    @classmethod
-    def checkActive(cls):
-        from . import mover
-        cls._active = mover.canMovePart()
-
-    @classmethod
-    def onClearSelection(cls):
-        cls._active = False
-
 class AsmCmdCheckable(AsmCmdBase):
     _id = -2
     _saveParam = False
@@ -465,6 +473,45 @@ class AsmCmdAddWorkplaneGroup(AsmCmdAddWorkplane):
     def Activated(cls,idx=0):
         FreeCADGui.runCommand(cls._cmds[idx])
 
+class AsmCmdGotoRelation(AsmCmdBase):
+    _id = 16
+    _menuText = 'Go to relation'
+    _tooltip = 'Select the corresponding part object in the relation group'
+    _iconName = 'Assembly_GotoRelation.svg'
+    _accel = 'A, R'
+
+    @classmethod
+    def Activated(cls):
+        from .assembly import AsmRelationGroup
+        if AsmCmdMove._moveInfo:
+            AsmRelationGroup.gotoRelation(AsmCmdMove._moveInfo)
+            return
+        sels = FreeCADGui.Selection.getSelectionEx('',0,True)
+        if sels and len(sels[0].SubElementNames)==1:
+            AsmRelationGroup.gotoRelationOfConstraint(
+                    sels[0].Object,sels[0].SubElementNames[0])
+
+    @classmethod
+    def IsActive(cls):
+        if AsmCmdMove._moveInfo:
+            return True
+        if cls._active is None:
+            cls.checkActive()
+        return cls._active
+
+    @classmethod
+    def checkActive(cls):
+        from .assembly import isTypeOf, AsmConstraint, AsmElementLink
+        sels = FreeCADGui.Selection.getSelection('',1,True)
+        if sels and isTypeOf(sels[0],(AsmConstraint,AsmElementLink)):
+            cls._active = True
+        else:
+            cls._active = False
+
+    @classmethod
+    def onSelectionChange(cls,hasSelection):
+        cls._active = None if hasSelection else False
+
 
 class AsmCmdUp(AsmCmdBase):
     _id = 6
diff --git a/mover.py b/mover.py
index c22a785..fbb6aa1 100644
--- a/mover.py
+++ b/mover.py
@@ -210,13 +210,10 @@ class AsmMovingPart(object):
         #   AsmMovingPart.update()
         return self.draggerPlacement
 
-def _checkFixedPart(info):
+def checkFixedPart(info):
     if not gui.AsmCmdManager.LockMover:
         return
-    if isTypeOf(info.Parent,Assembly,True):
-        assembly = info.Parent.getLinkedObject(True).Proxy
-    else:
-        assembly = info.Parent.getAssembly()
+    assembly = resolveAssembly(info.Parent)
     cstrs = assembly.getConstraints()
     parts = assembly.getPartGroup().Group
     if info.Part in Constraint.getFixedParts(None,cstrs,parts):
@@ -258,7 +255,6 @@ def getMovingElementInfo():
     if len(sels[0].SubElementNames)==1:
         info = getElementInfo(ret[0].Assembly,
                 ret[0].Subname, checkPlacement=True)
-        _checkFixedPart(info)
         return MovingPartInfo(SelObj=selObj,
                               SelSubname=selSub,
                               Hierarchy=ret,
@@ -283,22 +279,19 @@ def getMovingElementInfo():
     for r in ret2:
         if assembly == r.Assembly:
             info = getElementInfo(r.Assembly,r.Subname,checkPlacement=True)
-            _checkFixedPart(info)
             return MovingPartInfo(SelObj=selObj,
                             SelSubname=selSub,
                             Hierarchy=ret2,
                             ElementInfo=info)
     raise RuntimeError('not child parent selection')
 
-def canMovePart():
-    return logger.catchTrace('',getMovingElementInfo) is not None
-
-def movePart(useCenterballDragger=None):
-    ret = logger.catch('exception when moving part', getMovingElementInfo)
-    if not ret:
-        return False
-
-    info = ret.ElementInfo
+def movePart(useCenterballDragger=None,moveInfo=None):
+    if not moveInfo:
+        moveInfo = logger.catch(
+                'exception when moving part', getMovingElementInfo)
+        if not moveInfo:
+            return False
+    info = moveInfo.ElementInfo
     doc = FreeCADGui.editDocument()
     if doc:
         doc.resetEdit()
@@ -306,7 +299,7 @@ def movePart(useCenterballDragger=None):
     doc = info.Parent.ViewObject.Document
     if useCenterballDragger is not None:
         vobj.UseCenterballDragger = useCenterballDragger
-    vobj.Proxy._movingPart = AsmMovingPart(ret.Hierarchy,info)
+    vobj.Proxy._movingPart = AsmMovingPart(moveInfo.Hierarchy,info)
     FreeCADGui.Selection.clearSelection()
     return doc.setEdit(vobj,1)