class FootstepsPanel(object): def __init__(self, driver, robotModel, jointController, irisDriver): self.driver = driver self.robotModel = robotModel self.jointController = jointController loader = QtUiTools.QUiLoader() uifile = QtCore.QFile(':/ui/ddFootsteps.ui') assert uifile.open(uifile.ReadOnly) self.widget = loader.load(uifile) self.placer = None self.irisDriver = irisDriver self.region_seed_frames = [] self.ui = WidgetDict(self.widget.children()) self.ui.walkingGoalButton.connect("clicked()", self.onNewWalkingGoal) self.ui.walkingPlanButton.connect("clicked()", self.onShowWalkingPlan) self.ui.stopButton.connect("clicked()", self.onStop) self.ui.simulateDrakeButton.connect("clicked()", self.onSimulateDrake) self.ui.haltSimulationDrakeButton.connect("clicked()", self.onHaltSimulationDrake) self.ui.restoreDefaultsButton.connect("clicked()", lambda: self.applyDefaults()) self.ui.showWalkingVolumesCheck.connect("clicked()", self.onShowWalkingVolumes) ### BDI frame logic self.ui.hideBDIButton.setVisible(False) self.ui.showBDIButton.setVisible(False) self.ui.hideBDIButton.connect("clicked()", self.onHideBDIButton) self.ui.showBDIButton.connect("clicked()", self.onShowBDIButton) self.ui.newRegionSeedButton.connect("clicked()", self.onNewRegionSeed) self.ui.autoIRISSegmentationButton.connect("clicked()", self.onAutoIRISSegmentation) self._setupPropertiesPanel() def onShowWalkingVolumes(self): self.driver.show_contact_slices = self.ui.showWalkingVolumesCheck.checked folder = om.findObjectByName('walking volumes') for obj in folder.children(): obj.setProperty('Visible', self.driver.show_contact_slices) def onNewRegionSeed(self): t = self.newWalkingGoalFrame(self.robotModel, distanceForward=0.5) self.irisDriver.newTerrainItem(t) def onAutoIRISSegmentation(self): self.irisDriver.autoIRISSegmentation() def _setupPropertiesPanel(self): propertyNames = self.driver.params.propertyNames() l = QtGui.QGridLayout(self.ui.paramsOneContainer) l.setMargin(0) self.propertiesPanel = PythonQt.dd.ddPropertiesPanel() self.propertiesPanel.setBrowserModeToWidget() l.addWidget(self.propertiesPanel) self.panelConnector = propertyset.PropertyPanelConnector( self.driver.params.properties, self.propertiesPanel, propertyNames[0:15]) l = QtGui.QGridLayout(self.ui.paramsTwoContainer) l.setMargin(0) self.propertiesPanel = PythonQt.dd.ddPropertiesPanel() self.propertiesPanel.setBrowserModeToWidget() l.addWidget(self.propertiesPanel) self.panelConnector = propertyset.PropertyPanelConnector( self.driver.params.properties, self.propertiesPanel, propertyNames[15:]) self.driver.params.properties.connectPropertyChanged( self.onPropertyChanged) def onPropertyChanged(self, propertySet, propertyName): self.driver.updateRequest() if propertyName == 'Defaults': self.applyDefaults() def applyDefaults(self): set_name = self.driver.defaults_map[ self.driver.params.properties.defaults] for k, v in self.driver.default_step_params[set_name].items(): self.driver.params.setProperty(k, v) def newWalkingGoalFrame(self, robotModel, distanceForward=1.0): t = self.driver.getFeetMidPoint(robotModel) t.PreMultiply() t.Translate(distanceForward, 0.0, 0.0) t.PostMultiply() return t def onNewWalkingGoal(self, walkingGoal=None): walkingGoal = walkingGoal or self.newWalkingGoalFrame(self.robotModel) frameObj = vis.updateFrame(walkingGoal, 'walking goal', parent='planning', scale=0.25) frameObj.setProperty('Edit', True) rep = frameObj.widget.GetRepresentation() rep.SetTranslateAxisEnabled(2, False) rep.SetRotateAxisEnabled(0, False) rep.SetRotateAxisEnabled(1, False) frameObj.widget.HandleRotationEnabledOff() if self.placer: self.placer.stop() terrain = om.findObjectByName('HEIGHT_MAP_SCENE') if terrain: pos = np.array(frameObj.transform.GetPosition()) polyData = filterUtils.removeNonFinitePoints(terrain.polyData) if polyData.GetNumberOfPoints(): polyData = segmentation.labelDistanceToLine( polyData, pos, pos + [0, 0, 1]) polyData = segmentation.thresholdPoints( polyData, 'distance_to_line', [0.0, 0.1]) if polyData.GetNumberOfPoints(): pos[2] = np.nanmax( vnp.getNumpyFromVtk(polyData, 'Points')[:, 2]) frameObj.transform.Translate( pos - np.array(frameObj.transform.GetPosition())) d = DebugData() d.addSphere((0, 0, 0), radius=0.03) handle = vis.showPolyData(d.getPolyData(), 'walking goal terrain handle', parent=frameObj, visible=True, color=[1, 1, 0]) handle.actor.SetUserTransform(frameObj.transform) self.placer = PlacerWidget(app.getCurrentRenderView(), handle, terrain) def onFramePropertyModified(propertySet, propertyName): if propertyName == 'Edit': if propertySet.getProperty(propertyName): self.placer.start() else: self.placer.stop() frameObj.properties.connectPropertyChanged(onFramePropertyModified) onFramePropertyModified(frameObj, 'Edit') frameObj.connectFrameModified(self.onWalkingGoalModified) self.onWalkingGoalModified(frameObj) def onWalkingGoalModified(self, frame): om.removeFromObjectModel(om.findObjectByName('footstep widget')) request = self.driver.constructFootstepPlanRequest( self.jointController.q, frame.transform) self.driver.sendFootstepPlanRequest(request) def onExecute(self): self.driver.commitFootstepPlan(self.driver.lastFootstepPlan) def onShowWalkingPlan(self): startPose = self.jointController.getPose('EST_ROBOT_STATE') self.driver.sendWalkingPlanRequest(self.driver.lastFootstepPlan, startPose, waitForResponse=True) def onStop(self): self.driver.sendStopWalking() def onSimulateDrake(self): startPose = self.jointController.getPose('EST_ROBOT_STATE') self.robotModel.setProperty('Visible', False) self.driver.sendWalkingPlanRequest(self.driver.lastFootstepPlan, startPose, waitForResponse=False, req_type='simulate_drake') def onHaltSimulationDrake(self): om.findObjectByName("drake viewer").findChild("robot 1").setProperty( "Visible", False) self.robotModel.setProperty('Visible', True) self.driver.sendHaltSimulationDrakeRequest() ### BDI frame logic def onHideBDIButton(self): self.driver.showBDIPlan = False self.driver.bdiRobotModel.setProperty('Visible', False) folder = om.getOrCreateContainer("BDI footstep plan") om.removeFromObjectModel(folder) folder = om.getOrCreateContainer("BDI adj footstep plan") om.removeFromObjectModel(folder) def onShowBDIButton(self): self.driver.showBDIPlan = True self.driver.bdiRobotModel.setProperty('Visible', True) self.driver.drawBDIFootstepPlan() self.driver.drawBDIFootstepPlanAdjusted()
class TerrainRegionItem(vis.PolyDataItem): def __init__(self, uid, view, seed_pose, irisDriver, existing_region=None): d = DebugData() self.uid = uid vis.PolyDataItem.__init__(self, "IRIS region {:d}".format(uid), d.getPolyData(), view) self.transform = seed_pose d.addSphere((0, 0, 0), radius=0.02) self.seedObj = vis.showPolyData( d.getPolyData(), 'region seed', parent=om.getOrCreateContainer('IRIS region seeds')) self.seedObj.actor.SetUserTransform(self.transform) self.frameObj = vis.showFrame(self.transform, 'region seed frame', scale=0.2, visible=False, parent=self.seedObj) self.frameObj.setProperty('Edit', True) self.frameObj.widget.HandleRotationEnabledOff() terrain = om.findObjectByName('HEIGHT_MAP_SCENE') if terrain: rep = self.frameObj.widget.GetRepresentation() rep.SetTranslateAxisEnabled(2, False) rep.SetRotateAxisEnabled(0, False) rep.SetRotateAxisEnabled(1, False) pos = np.array(self.frameObj.transform.GetPosition()) polyData = filterUtils.removeNonFinitePoints(terrain.polyData) if polyData.GetNumberOfPoints(): polyData = segmentation.labelDistanceToLine( polyData, pos, pos + [0, 0, 1]) polyData = segmentation.thresholdPoints( polyData, 'distance_to_line', [0.0, 0.1]) if polyData.GetNumberOfPoints(): pos[2] = np.nanmax( vnp.getNumpyFromVtk(polyData, 'Points')[:, 2]) self.frameObj.transform.Translate( pos - np.array(self.frameObj.transform.GetPosition())) self.placer = PlacerWidget(view, self.seedObj, terrain) self.placer.start() else: self.frameObj.setProperty('Edit', True) self.frameObj.setProperty('Visible', True) self.driver = irisDriver self.safe_region = None self.addProperty('Visible', True) self.addProperty('Enabled for Walking', True) self.addProperty('Alpha', 1.0) self.addProperty('Color', QtGui.QColor(200, 200, 20)) self.frameObj.connectFrameModified(self.onFrameModified) if existing_region is None: self.onFrameModified(self.frameObj) else: self.setRegion(existing_region) self.setProperty('Alpha', 0.5) self.setProperty('Color', QtGui.QColor(220, 220, 220)) def setRegion(self, safe_region): debug = DebugData() pos = safe_region.point try: xy_verts = safe_region.xy_polytope() if xy_verts.shape[1] == 0: raise QhullError("No points returned") xyz_verts = np.vstack((xy_verts, pos[2] + 0.02 + np.zeros( (1, xy_verts.shape[1])))) xyz_verts = np.hstack((xyz_verts, np.vstack( (xy_verts, pos[2] + 0.015 + np.zeros( (1, xy_verts.shape[1])))))) # print xyz_verts.shape polyData = vnp.getVtkPolyDataFromNumpyPoints(xyz_verts.T.copy()) vol_mesh = filterUtils.computeDelaunay3D(polyData) for j in range(xy_verts.shape[1]): z = pos[2] + 0.005 p1 = np.hstack((xy_verts[:, j], z)) if j < xy_verts.shape[1] - 1: p2 = np.hstack((xy_verts[:, j + 1], z)) else: p2 = np.hstack((xy_verts[:, 0], z)) debug.addLine(p1, p2, color=[.7, .7, .7], radius=0.003) debug.addPolyData(vol_mesh) # self.setPolyData(vol_mesh) self.setPolyData(debug.getPolyData()) self.safe_region = safe_region except QhullError: print( "Could not generate convex hull (polytope is likely unbounded)." ) def onFrameModified(self, frame): self.driver.requestIRISRegion(frame.transform, self.uid) def _onPropertyChanged(self, propertySet, propertyName): vis.PolyDataItem._onPropertyChanged(self, propertySet, propertyName) if propertyName == 'Enabled for Walking': if self.getProperty('Enabled for Walking'): self.setProperty('Alpha', 0.2) else: self.setProperty('Alpha', 0.05) if propertyName == 'Visible': self.seedObj.setProperty('Visible', self.getProperty('Visible')) def onRemoveFromObjectModel(self): om.removeFromObjectModel(self.frameObj) om.removeFromObjectModel(self.seedObj) self.driver.regions.pop(self.uid) vis.PolyDataItem.onRemoveFromObjectModel(self)
class TerrainRegionItem(vis.PolyDataItem): def __init__(self, uid, view, seed_pose, irisDriver, existing_region=None): d = DebugData() self.uid = uid vis.PolyDataItem.__init__(self, "IRIS region {:d}".format(uid), d.getPolyData(), view) self.transform = seed_pose d.addSphere((0,0,0), radius=0.02) self.seedObj = vis.showPolyData(d.getPolyData(), 'region seed', parent=om.getOrCreateContainer('IRIS region seeds')) self.seedObj.actor.SetUserTransform(self.transform) self.frameObj = vis.showFrame(self.transform, 'region seed frame', scale=0.2, visible=False, parent=self.seedObj) self.frameObj.setProperty('Edit', True) self.frameObj.widget.HandleRotationEnabledOff() terrain = om.findObjectByName('HEIGHT_MAP_SCENE') if terrain: rep = self.frameObj.widget.GetRepresentation() rep.SetTranslateAxisEnabled(2, False) rep.SetRotateAxisEnabled(0, False) rep.SetRotateAxisEnabled(1, False) pos = np.array(self.frameObj.transform.GetPosition()) polyData = filterUtils.removeNonFinitePoints(terrain.polyData) if polyData.GetNumberOfPoints(): polyData = segmentation.labelDistanceToLine(polyData, pos, pos+[0,0,1]) polyData = segmentation.thresholdPoints(polyData, 'distance_to_line', [0.0, 0.1]) if polyData.GetNumberOfPoints(): pos[2] = np.nanmax(vnp.getNumpyFromVtk(polyData, 'Points')[:,2]) self.frameObj.transform.Translate(pos - np.array(self.frameObj.transform.GetPosition())) self.placer = PlacerWidget(view, self.seedObj, terrain) self.placer.start() else: self.frameObj.setProperty('Edit', True) self.frameObj.setProperty('Visible', True) self.driver = irisDriver self.safe_region = None self.addProperty('Visible', True) self.addProperty('Enabled for Walking', True) self.addProperty('Alpha', 1.0) self.addProperty('Color', QtGui.QColor(200,200,20)) self.frameObj.connectFrameModified(self.onFrameModified) if existing_region is None: self.onFrameModified(self.frameObj) else: self.setRegion(existing_region) self.setProperty('Alpha', 0.5) self.setProperty('Color', QtGui.QColor(220,220,220)) def setRegion(self, safe_region): debug = DebugData() pos = safe_region.point try: xy_verts = safe_region.xy_polytope() if xy_verts.shape[1] == 0: raise QhullError("No points returned") xyz_verts = np.vstack((xy_verts, pos[2] + 0.02 + np.zeros((1, xy_verts.shape[1])))) xyz_verts = np.hstack((xyz_verts, np.vstack((xy_verts, pos[2] + 0.015 + np.zeros((1, xy_verts.shape[1])))))) # print xyz_verts.shape polyData = vnp.getVtkPolyDataFromNumpyPoints(xyz_verts.T.copy()) vol_mesh = filterUtils.computeDelaunay3D(polyData) for j in range(xy_verts.shape[1]): z = pos[2] + 0.005 p1 = np.hstack((xy_verts[:,j], z)) if j < xy_verts.shape[1] - 1: p2 = np.hstack((xy_verts[:,j+1], z)) else: p2 = np.hstack((xy_verts[:,0], z)) debug.addLine(p1, p2, color=[.7,.7,.7], radius=0.003) debug.addPolyData(vol_mesh) # self.setPolyData(vol_mesh) self.setPolyData(debug.getPolyData()) self.safe_region = safe_region except QhullError: print "Could not generate convex hull (polytope is likely unbounded)." def onFrameModified(self, frame): self.driver.requestIRISRegion(frame.transform, self.uid) def _onPropertyChanged(self, propertySet, propertyName): vis.PolyDataItem._onPropertyChanged(self, propertySet, propertyName) if propertyName == 'Enabled for Walking': if self.getProperty('Enabled for Walking'): self.setProperty('Alpha', 0.2) else: self.setProperty('Alpha', 0.05) if propertyName == 'Visible': self.seedObj.setProperty('Visible', self.getProperty('Visible')) def onRemoveFromObjectModel(self): om.removeFromObjectModel(self.frameObj) om.removeFromObjectModel(self.seedObj) self.driver.regions.pop(self.uid) vis.PolyDataItem.onRemoveFromObjectModel(self)
class FootstepsPanel(object): def __init__(self, driver, robotModel, jointController, irisDriver): self.driver = driver self.robotModel = robotModel self.jointController = jointController loader = QtUiTools.QUiLoader() uifile = QtCore.QFile(':/ui/ddFootsteps.ui') assert uifile.open(uifile.ReadOnly) self.widget = loader.load(uifile) self.placer = None self.irisDriver = irisDriver self.region_seed_frames = [] self.ui = WidgetDict(self.widget.children()) self.ui.walkingGoalButton.connect("clicked()", self.onNewWalkingGoal) self.ui.walkingPlanButton.connect("clicked()", self.onShowWalkingPlan) self.ui.stopButton.connect("clicked()", self.onStop) self.ui.simulateDrakeButton.connect("clicked()", self.onSimulateDrake) self.ui.haltSimulationDrakeButton.connect("clicked()", self.onHaltSimulationDrake) self.ui.restoreDefaultsButton.connect("clicked()", lambda: self.applyDefaults()) self.ui.showWalkingVolumesCheck.connect("clicked()", self.onShowWalkingVolumes) ### BDI frame logic self.ui.hideBDIButton.setVisible(False) self.ui.showBDIButton.setVisible(False) self.ui.hideBDIButton.connect("clicked()", self.onHideBDIButton) self.ui.showBDIButton.connect("clicked()", self.onShowBDIButton) self.ui.newRegionSeedButton.connect("clicked()", self.onNewRegionSeed) self.ui.autoIRISSegmentationButton.connect("clicked()", self.onAutoIRISSegmentation) self._setupPropertiesPanel() def onShowWalkingVolumes(self): self.driver.show_contact_slices = self.ui.showWalkingVolumesCheck.checked folder = om.findObjectByName('walking volumes') for obj in folder.children(): obj.setProperty('Visible', self.driver.show_contact_slices) def onNewRegionSeed(self): t = self.newWalkingGoalFrame(self.robotModel, distanceForward=0.5) self.irisDriver.newTerrainItem(t) def onAutoIRISSegmentation(self): self.irisDriver.autoIRISSegmentation() def _setupPropertiesPanel(self): l = QtGui.QVBoxLayout(self.ui.paramsContainer) l.setMargin(0) self.propertiesPanel = PythonQt.dd.ddPropertiesPanel() self.propertiesPanel.setBrowserModeToWidget() l.addWidget(self.propertiesPanel) self.panelConnector = propertyset.PropertyPanelConnector(self.driver.params.properties, self.propertiesPanel) self.driver.params.properties.connectPropertyChanged(self.onPropertyChanged) PythonQt.dd.ddGroupBoxHider(self.ui.paramsContainer) def onPropertyChanged(self, propertySet, propertyName): self.driver.updateRequest() if propertyName == 'Defaults': self.applyDefaults() def applyDefaults(self): set_name = self.driver.defaults_map[self.driver.params.properties.defaults] for k, v in self.driver.default_step_params[set_name].iteritems(): self.driver.params.setProperty(k, v) def newWalkingGoalFrame(self, robotModel, distanceForward=1.0): t = self.driver.getFeetMidPoint(robotModel) t.PreMultiply() t.Translate(distanceForward, 0.0, 0.0) t.PostMultiply() return t def onNewWalkingGoal(self, walkingGoal=None): walkingGoal = walkingGoal or self.newWalkingGoalFrame(self.robotModel) frameObj = vis.updateFrame(walkingGoal, 'walking goal', parent='planning', scale=0.25) frameObj.setProperty('Edit', True) rep = frameObj.widget.GetRepresentation() rep.SetTranslateAxisEnabled(2, False) rep.SetRotateAxisEnabled(0, False) rep.SetRotateAxisEnabled(1, False) frameObj.widget.HandleRotationEnabledOff() if self.placer: self.placer.stop() terrain = om.findObjectByName('HEIGHT_MAP_SCENE') if terrain: pos = np.array(frameObj.transform.GetPosition()) polyData = filterUtils.removeNonFinitePoints(terrain.polyData) if polyData.GetNumberOfPoints(): polyData = segmentation.labelDistanceToLine(polyData, pos, pos+[0,0,1]) polyData = segmentation.thresholdPoints(polyData, 'distance_to_line', [0.0, 0.1]) if polyData.GetNumberOfPoints(): pos[2] = np.nanmax(vnp.getNumpyFromVtk(polyData, 'Points')[:,2]) frameObj.transform.Translate(pos - np.array(frameObj.transform.GetPosition())) d = DebugData() d.addSphere((0,0,0), radius=0.03) handle = vis.showPolyData(d.getPolyData(), 'walking goal terrain handle', parent=frameObj, visible=True, color=[1,1,0]) handle.actor.SetUserTransform(frameObj.transform) self.placer = PlacerWidget(app.getCurrentRenderView(), handle, terrain) def onFramePropertyModified(propertySet, propertyName): if propertyName == 'Edit': if propertySet.getProperty(propertyName): self.placer.start() else: self.placer.stop() frameObj.properties.connectPropertyChanged(onFramePropertyModified) onFramePropertyModified(frameObj, 'Edit') frameObj.connectFrameModified(self.onWalkingGoalModified) self.onWalkingGoalModified(frameObj) def onWalkingGoalModified(self, frame): om.removeFromObjectModel(om.findObjectByName('footstep widget')) request = self.driver.constructFootstepPlanRequest(self.jointController.q, frame.transform) self.driver.sendFootstepPlanRequest(request) def onExecute(self): self.driver.commitFootstepPlan(self.driver.lastFootstepPlan) def onShowWalkingPlan(self): startPose = self.jointController.getPose('EST_ROBOT_STATE') self.driver.sendWalkingPlanRequest(self.driver.lastFootstepPlan, startPose, waitForResponse=True) def onStop(self): self.driver.sendStopWalking() def onSimulateDrake(self): startPose = self.jointController.getPose('EST_ROBOT_STATE') self.robotModel.setProperty('Visible', False); self.driver.sendWalkingPlanRequest(self.driver.lastFootstepPlan, startPose, waitForResponse=False, req_type='simulate_drake') def onHaltSimulationDrake(self): om.findObjectByName("drake viewer").findChild("robot 1").setProperty("Visible", False) self.robotModel.setProperty('Visible', True); self.driver.sendHaltSimulationDrakeRequest() ### BDI frame logic def onHideBDIButton(self): self.driver.showBDIPlan = False self.driver.bdiRobotModel.setProperty('Visible', False) folder = om.getOrCreateContainer("BDI footstep plan") om.removeFromObjectModel(folder) folder = om.getOrCreateContainer("BDI adj footstep plan") om.removeFromObjectModel(folder) def onShowBDIButton(self): self.driver.showBDIPlan = True self.driver.bdiRobotModel.setProperty('Visible', True) self.driver.drawBDIFootstepPlan() self.driver.drawBDIFootstepPlanAdjusted()