VX7500 Control — (vxlib)

Created on Wed Feb 15 14:58:38 2012

@author: chris

Legal Information: All information contained herein is, and remains the property of Vena Engineering Corporation. This source code contains proprietary information of Vena Engineering Corporation. It is intended solely for the information and use of parties operating and maintaining the equipment provided by Vena Engineering. Such proprietary information may not be used, reproduced, or disclosed to any other parties for any other purpose without the expressed written permission of Vena Engineering Corporation. The intellectual and technical concepts contained herein are proprietary to Vena Engineering Corporation and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from Vena Engineering Corporation.

Example

[source code]

from PyQt4 import QtCore, QtGui
import vpy.vx as vx
import time
import math
import numpy as np
import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure

TITLE = "vx7500 Demo GUI"

class Dialog(QtGui.QDialog):

    def __init__(self):
        super(Dialog, self).__init__()
        self.createMenu()    
        self.setWindowTitle(TITLE)        

        try:
            self.v = vx.Vx(0)
            self.spindle = self.v.mtr['Spindle']
            self.actuator = self.v.mtr['Actuator']
            self.spindle_encoder = self.v.daq['Spindle Encoder']
            self.spindle_velocity = self.v.daq['Spindle Velocity']
            self.actuator_encoder = self.v.daq['Actuator Encoder']
            
            self.spindle_configure()
            self.actuator_configure()
        except:
            QtGui.QMessageBox.critical(None, TITLE,'Fatal Error, check hardware connection',QtGui.QMessageBox.Abort)

        self.createSpindleGroupBox()
        self.createActuatorGroupBox()
        self.createTestGroupBox()
        
        mainLayout = QtGui.QVBoxLayout()
        mainLayout.setMenuBar(self.menuBar)
        mainLayout.addWidget(self.spindleGroupBox)
        mainLayout.addWidget(self.actuatorGroupBox)
        mainLayout.addWidget(self.testGroupBox)
        self.setLayout(mainLayout)
        self.finished.connect(self.on_finished)
    
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_gui)
        self.timer.start(500)
              
    def on_finished(self):
        self.v.close()        
        
    def reenable_timer(self):
        pass
        
    def addButton(self, name, callback, layout, row, col):
        button = QtGui.QPushButton(name)
        button.clicked.connect(callback)
        layout.addWidget(button, row, col)

    def addRangeWidget(self, widget_type, minimum, maximum, value, layout, row, col):
        w = widget_type()
        w.setRange(minimum, maximum)
        w.setValue(value)
        layout.addWidget(w, row, col)
        return w
    
    def addUpdateLabel(self, text, layout, row):
        label = QtGui.QLabel()
        layout.addWidget(QtGui.QLabel(text), row, 0, QtCore.Qt.AlignRight)
        layout.addWidget(label, row, 1, QtCore.Qt.AlignLeft)
        return label

    def createSpindleGroupBox(self):
        self.spindleGroupBox = QtGui.QGroupBox("Spindle Motor")
        layout = QtGui.QGridLayout()        
        layout.addWidget(QtGui.QLabel("RPM:"), 1, 0)
        layout.addWidget(QtGui.QLabel("Time:"), 1, 1)        
        self.spindleMoveSpinBox = self.addRangeWidget(QtGui.QSpinBox, 0, 10000, 0, layout, 2, 0)
        self.spindleTimeSpinBox = self.addRangeWidget(QtGui.QDoubleSpinBox, 0.5, 60.0, 5.0, layout, 2, 1)
        self.addButton('Start', self.spindle_start, layout, 3, 0)
        self.addButton('Stop', self.spindle_stop, layout, 3, 1)
        self.addButton('Reset Motor', self.spindle_reset, layout, 4, 0)
        self.addButton('Turn Off Motor', self.spindle_off, layout, 4, 1) 
        self.spindleEncoderLabel = self.addUpdateLabel('Encoder:', layout, 5)
        self.spindleVelocityLabel = self.addUpdateLabel('RPM:', layout, 6)
        self.spindleGroupBox.setLayout(layout)
        
    def createActuatorGroupBox(self):
        self.actuatorGroupBox = QtGui.QGroupBox("Actuator Motor")
        layout = QtGui.QGridLayout()        
        layout.addWidget(QtGui.QLabel("Radians:"), 1, 0)
        layout.addWidget(QtGui.QLabel("Time:"), 1, 1)        
        self.actuatorMoveSpinBox = self.addRangeWidget(QtGui.QDoubleSpinBox, -math.pi, math.pi, 0.0, layout, 2, 0)
        self.actuatorTimeSpinBox = self.addRangeWidget(QtGui.QDoubleSpinBox, 0.1, 60.0, 1.0, layout, 2, 1)        
        self.addButton('Start', self.actuator_start, layout, 3, 0)
        self.addButton('Stop', self.actuator_stop, layout, 3, 1)
        self.addButton('Reset Motor', self.actuator_reset, layout, 4, 0)
        self.addButton('Turn Off Motor', self.actuator_off, layout, 4, 1)      
        self.actuatorEncoderLabel = self.addUpdateLabel('Encoder:', layout, 5)
        self.actuatorGroupBox.setLayout(layout)
        
    def createTestGroupBox(self):
        self.testGroupBox = QtGui.QGroupBox("Demo Test")
        layout = QtGui.QGridLayout()  
        layout.addWidget(QtGui.QLabel("<b>Be sure that the spindle is spinning before pressing <i>Run</i>.</b>"), 0, 0)
        self.addButton('Run', self.run_test, layout, 1, 0)
        
        self.dpi = 100
        self.fig = Figure((5.0, 4.0), dpi=self.dpi, facecolor='#eaeaea')
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.testGroupBox)
        self.axis1 = self.fig.add_subplot(111)
        self.axis2 = self.axis1.twinx()
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.testGroupBox)
        
        layout.addWidget(self.mpl_toolbar, 2, 0)
        layout.addWidget(self.canvas, 3, 0)   

        self.testGroupBox.setLayout(layout)

    def createMenu(self):
        self.menuBar = QtGui.QMenuBar()
        self.fileMenu = QtGui.QMenu("&File", self)
        self.exitAction = self.fileMenu.addAction("E&xit")
        self.menuBar.addMenu(self.fileMenu)
        self.exitAction.triggered.connect(self.accept)

    def set_variableu32(self, chan, attribute, value):
        print 'Write', attribute, '=', value
        self.v.protocol.writeVariable(chan, attribute, 'FLEX_TYPE_UINT32', value)
        
    def set_variabledbl(self, chan, attribute, value):
        print 'Write', attribute, '=', value
        self.v.protocol.writeVariable(chan, attribute, 'FLEX_TYPE_DOUBLE', value)
        
    def set_config(self, chan, d):
        for key, value in d.iteritems():
            self.set_variableu32(chan, key, value)        

    def spindle_configure(self):
        conf = {'MTR_VAR_COMCURRENT': 18000,
                'MTR_VAR_MAXCURRENT': 8000,
                'MTR_VAR_MAXPOSERROR': 10000,
                'MTR_VAR_POLES': 12,
                'MTR_VAR_ENCCOUNTSPERROTATION': 2048*4
                }
        self.set_config(0, conf)
        
    def spindle_start(self):
        move0 = self.spindleMoveSpinBox.value()
        time0 = self.spindleTimeSpinBox.value()
        self.spindle.start(profile = [(time0, move0)])

    def spindle_stop(self):
        self.spindle.stop()

    def spindle_reset(self):
        self.spindle.power(True)

    def spindle_off(self):
        self.spindle.power(False)

    def actuator_configure(self):
        conf = {'MTR_VAR_TYPE': 2,
                'MTR_VAR_STEPSPERROTATION': 2048*4,
                'MTR_VAR_ENCCOUNTSPERROTATION': 2048*4,
                'MTR_VAR_KP': 50,
                'MTR_VAR_KD': 1,
                'MTR_VAR_KI': 1,
                'MTR_VAR_ILIM': 800,
                'MTR_VAR_MAXCURRENT': 18000,
                'MTR_VAR_MAXPOSERROR': 100,
                'DAQ_VAR_SWITCH_CHANNEL': 2
                }
        self.set_config(1, conf)
        self.set_variabledbl(1,'MTR_VAR_ELECCYCLETIME', 0.00025)
        
    def actuator_start(self):
        move0 = self.actuatorMoveSpinBox.value()
        time0 = self.actuatorTimeSpinBox.value()
        self.actuator.start(profile = [(time0, move0)])

    def actuator_stop(self):
        self.actuator.stop()

    def actuator_reset(self):
        self.actuator.power(True)

    def actuator_off(self):
        self.actuator.power(False)

    def update_gui(self):
        try:
            spindle_enc = self.spindle_encoder.getLastAverage()
            spindle_vel = self.spindle_velocity.getLastAverage()
            #convert clock counts to rpm
            spindle_vel = (3000000000000/spindle_vel)*0.001 if spindle_vel != 0.0 else 0.0
            actuator_enc = self.actuator_encoder.getLastAverage()
            self.spindleEncoderLabel.setText(str(spindle_enc))
            self.spindleVelocityLabel.setText(str(spindle_vel))
            self.actuatorEncoderLabel.setText(str(actuator_enc))            
        except:
            pass
         
    def run_test(self):
        # set up actuator profile
        ramp_position = -0.1
        load_position = -0.28
        profile = [(0.8, load_position),(1.2, load_position),(2.0, ramp_position)]
        self.actuator.start(profile = profile, wait_for_trigger = True)
        
        # set up AE RMS data collection
        ae_rms = self.v.daq['AE RMS']
        ae_rms.start(2.0, wait_for_trigger = True)

        # set up Actuator Encoder data collection
        self.spindle_velocity.start(2.0, wait_for_trigger = True)
        self.actuator_encoder.start(2.0, wait_for_trigger = True)

        # start it
        self.v.trigger()        
    
        # wait for DAQ to finish, motor should also be done
        while ae_rms.collecting or self.actuator_encoder.collecting or self.spindle_velocity.collecting:
            time.sleep(0.1)
        
        ae_rms_data = ae_rms.getData()
        rpm_data = self.spindle_velocity.getData()
        encoder_data = self.actuator_encoder.getData()
        
        x_ae_rms_data = np.linspace(1.0/ae_rms.samprate, 2.0, ae_rms_data.size)
        x_rpm_data = np.linspace(1.0/self.spindle_velocity.samprate, 2.0, rpm_data.size)

        x_encoder_data = np.linspace(1.0/self.actuator_encoder.samprate, 2.0, encoder_data.size)
        
        self.axis1.clear()
        self.axis2.clear()
        self.axis1.plot(x_ae_rms_data, ae_rms_data, 'b')
        self.axis2.plot(x_rpm_data, rpm_data, 'g')
        #self.axis2.plot(x_encoder_data, encoder_data, 'r')
        self.canvas.draw()
        
if __name__ == '__main__':
    
    import sys    
    app = QtGui.QApplication(sys.argv)
    dialog = Dialog()
    sys.exit(dialog.exec_())