Example #1
0
void PacketInterface::processPacket(const unsigned char *data, int len)
{
    int32_t ind = 0;
    MC_VALUES values;
    QByteArray bytes;
    QByteArray tmpArray;
    QVector<double> samples;
    mc_configuration mcconf;
    app_configuration appconf;
    double detect_cycle_int_limit;
    double detect_coupling_k;
    QVector<int> detect_hall_table;
    int detect_hall_res;
    double dec_ppm;
    double ppm_last_len;
    double dec_adc;
    double dec_adc_voltage;
    int fw_major;
    int fw_minor;

    unsigned char id = data[0];
    data++;
    len--;

    switch (id) {
    case COMM_FW_VERSION:
        if (len == 2) {
            ind = 0;
            fw_major = data[ind++];
            fw_minor = data[ind++];
        } else {
            fw_major = -1;
            fw_minor = -1;
        }
        emit fwVersionReceived(fw_major, fw_minor);
        break;

    case COMM_ERASE_NEW_APP:
    case COMM_WRITE_NEW_APP_DATA:
        firmwareUploadUpdate(!data[0]);
        break;

    case COMM_GET_VALUES:
        ind = 0;
        values.temp_mos1 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_mos2 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_mos3 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_mos4 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_mos5 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_mos6 = utility::buffer_get_double16(data, 10.0, &ind);
        values.temp_pcb = utility::buffer_get_double16(data, 10.0, &ind);
        values.current_motor = utility::buffer_get_double32(data, 100.0, &ind);
        values.current_in = utility::buffer_get_double32(data, 100.0, &ind);
        values.duty_now = utility::buffer_get_double16(data, 1000.0, &ind);
        values.rpm = utility::buffer_get_double32(data, 1.0, &ind);
        values.v_in = utility::buffer_get_double16(data, 10.0, &ind);
        values.amp_hours = utility::buffer_get_double32(data, 10000.0, &ind);
        values.amp_hours_charged = utility::buffer_get_double32(data, 10000.0, &ind);
        values.watt_hours = utility::buffer_get_double32(data, 10000.0, &ind);
        values.watt_hours_charged = utility::buffer_get_double32(data, 10000.0, &ind);
        values.tachometer = utility::buffer_get_int32(data, &ind);
        values.tachometer_abs = utility::buffer_get_int32(data, &ind);
        values.fault_code = (mc_fault_code)data[ind++];
        values.fault_str = faultToStr(values.fault_code);

        emit valuesReceived(values);
        break;

    case COMM_PRINT:
        tmpArray = QByteArray::fromRawData((char*)data, len);
        tmpArray[len] = '\0';
        emit printReceived(QString::fromLatin1(tmpArray));
        break;

    case COMM_SAMPLE_PRINT:
        for (int i = 0;i < len;i++) {
            bytes.append(data[i]);
        }
        emit samplesReceived(bytes);
        break;

    case COMM_ROTOR_POSITION:
        ind = 0;
        emit rotorPosReceived(utility::buffer_get_double32(data, 100000.0, &ind));
        break;

    case COMM_EXPERIMENT_SAMPLE:
        samples.clear();
        ind = 0;

        while (ind < len) {
            samples.append(utility::buffer_get_double32(data, 10000.0, &ind));
        }

        emit experimentSamplesReceived(samples);
        break;

    case COMM_GET_MCCONF:
        ind = 0;
        mcconf.pwm_mode = (mc_pwm_mode)data[ind++];
        mcconf.comm_mode = (mc_comm_mode)data[ind++];
        mcconf.motor_type = (mc_motor_type)data[ind++];
        mcconf.sensor_mode = (mc_sensor_mode)data[ind++];

        mcconf.l_current_max = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_current_min = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_in_current_max = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_in_current_min = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_abs_current_max = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_min_erpm = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_max_erpm = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_max_erpm_fbrake = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_max_erpm_fbrake_cc = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_min_vin = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_max_vin = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_battery_cut_start = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_battery_cut_end = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_slow_abs_current = data[ind++];
        mcconf.l_rpm_lim_neg_torque = data[ind++];
        mcconf.l_temp_fet_start = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_temp_fet_end = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_temp_motor_start = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_temp_motor_end = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.l_min_duty = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.l_max_duty = utility::buffer_get_double32(data, 1000000.0, &ind);

        mcconf.sl_min_erpm = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_min_erpm_cycle_int_limit = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_max_fullbreak_current_dir_change = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_cycle_int_limit = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_phase_advance_at_br = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_cycle_int_rpm_br = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.sl_bemf_coupling_k = utility::buffer_get_double32(data, 1000.0, &ind);

        memcpy(mcconf.hall_table, data + ind, 8);
        ind += 8;
        mcconf.hall_sl_erpm = utility::buffer_get_double32(data, 1000.0, &ind);

        mcconf.s_pid_kp = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.s_pid_ki = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.s_pid_kd = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.s_pid_min_rpm = utility::buffer_get_double32(data, 1000.0, &ind);

        mcconf.p_pid_kp = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.p_pid_ki = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.p_pid_kd = utility::buffer_get_double32(data, 1000000.0, &ind);

        mcconf.cc_startup_boost_duty = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.cc_min_current = utility::buffer_get_double32(data, 1000.0, &ind);
        mcconf.cc_gain = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.cc_ramp_step_max = utility::buffer_get_double32(data, 1000000.0, &ind);

        mcconf.m_fault_stop_time_ms = utility::buffer_get_int32(data, &ind);
        mcconf.m_duty_ramp_step = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.m_duty_ramp_step_rpm_lim = utility::buffer_get_double32(data, 1000000.0, &ind);
        mcconf.m_current_backoff_gain = utility::buffer_get_double32(data, 1000000.0, &ind);

        mcconf.meta_description = "Configuration loaded from the motor controller.";

        emit mcconfReceived(mcconf);
        break;

    case COMM_GET_APPCONF:
        ind = 0;
        appconf.controller_id = data[ind++];
        appconf.timeout_msec = utility::buffer_get_uint32(data, &ind);
        appconf.timeout_brake_current = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.send_can_status = data[ind++];
        appconf.send_can_status_rate_hz = utility::buffer_get_uint16(data, &ind);

        appconf.app_to_use = (app_use)data[ind++];

        appconf.app_ppm_conf.ctrl_type = (ppm_control_type)data[ind++];
        appconf.app_ppm_conf.pid_max_erpm = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.hyst = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.pulse_start = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.pulse_end = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.median_filter = data[ind++];
        appconf.app_ppm_conf.safe_start = data[ind++];
        appconf.app_ppm_conf.rpm_lim_start = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.rpm_lim_end = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_ppm_conf.multi_esc = data[ind++];
        appconf.app_ppm_conf.tc = data[ind++];
        appconf.app_ppm_conf.tc_max_diff = utility::buffer_get_double32(data, 1000.0, &ind);

        appconf.app_adc_conf.ctrl_type = (adc_control_type)data[ind++];
        appconf.app_adc_conf.hyst = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.voltage_start = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.voltage_end = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.use_filter = data[ind++];
        appconf.app_adc_conf.safe_start = data[ind++];
        appconf.app_adc_conf.cc_button_inverted = data[ind++];
        appconf.app_adc_conf.rev_button_inverted = data[ind++];
        appconf.app_adc_conf.voltage_inverted = data[ind++];
        appconf.app_adc_conf.rpm_lim_start = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.rpm_lim_end = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.multi_esc = data[ind++];
        appconf.app_adc_conf.tc = data[ind++];
        appconf.app_adc_conf.tc_max_diff = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_adc_conf.update_rate_hz = utility::buffer_get_uint16(data, &ind);

        appconf.app_uart_baudrate = utility::buffer_get_uint32(data, &ind);

        appconf.app_chuk_conf.ctrl_type = (chuk_control_type)data[ind++];
        appconf.app_chuk_conf.hyst = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_chuk_conf.rpm_lim_start = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_chuk_conf.rpm_lim_end = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_chuk_conf.ramp_time_pos = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_chuk_conf.ramp_time_neg = utility::buffer_get_double32(data, 1000.0, &ind);
        appconf.app_chuk_conf.multi_esc = data[ind++];
        appconf.app_chuk_conf.tc = data[ind++];
        appconf.app_chuk_conf.tc_max_diff = utility::buffer_get_double32(data, 1000.0, &ind);
        emit appconfReceived(appconf);
        break;

    case COMM_DETECT_MOTOR_PARAM:
        ind = 0;
        detect_cycle_int_limit = utility::buffer_get_double32(data, 1000.0, &ind);
        detect_coupling_k = utility::buffer_get_double32(data, 1000.0, &ind);
        for (int i = 0;i < 8;i++) {
            detect_hall_table.append((const signed char)(data[ind++]));
        }
        detect_hall_res = (const signed char)(data[ind++]);
        emit motorParamReceived(detect_cycle_int_limit, detect_coupling_k, detect_hall_table, detect_hall_res);
        break;

    case COMM_GET_DECODED_PPM:
        ind = 0;
        dec_ppm = utility::buffer_get_double32(data, 1000000.0, &ind);
        ppm_last_len = utility::buffer_get_double32(data, 1000000.0, &ind);
        emit decodedPpmReceived(dec_ppm, ppm_last_len);
        break;

    case COMM_GET_DECODED_ADC:
        ind = 0;
        dec_adc = utility::buffer_get_double32(data, 1000000.0, &ind);
        dec_adc_voltage = utility::buffer_get_double32(data, 1000000.0, &ind);
        emit decodedAdcReceived(dec_adc, dec_adc_voltage);
        break;

    case COMM_GET_DECODED_CHUK:
        ind = 0;
        dec_ppm = utility::buffer_get_double32(data, 1000000.0, &ind);
        emit decodedChukReceived(dec_ppm);
        break;

    case COMM_SET_MCCONF:
        emit ackReceived("MCCONF Write OK");
        break;

    case COMM_SET_APPCONF:
        emit ackReceived("APPCONF Write OK");
        break;

    default:
        break;
    }
}
Example #2
0
Logger::Logger(QObject *parent) :
    QObject(parent)
{
    mPort = new SerialPort(this);
    mPacketInterface = new PacketInterface(this);

    mValueFile = new QFile("Data/BLDC_Values");
    mPrintFile = new QFile("Data/BLDC_Print");

    mValueFile->open(QIODevice::WriteOnly | QIODevice::Text);
    mPrintFile->open(QIODevice::WriteOnly | QIODevice::Text);

    mValueStream = new QTextStream(mValueFile);
    mPrintStream = new QTextStream(mPrintFile);

    mPort->openPort("/dev/ttyACM0");

    // Video
    mVidW = 1280;
    mVidH = 720;
    mVidFps = 25.0;
    mFAudioSamp = 44100;

    mFrameGrabber = new FrameGrabber(mVidW, mVidH, mVidFps, 0, this);
    mFrameGrabber->start(QThread::InheritPriority);
    mPlotter = new FramePlotter(this);
    mPlotter->start(QThread::InheritPriority);

    mCoder = new VideoCoder(mVidW, mVidH, mVidFps, "Data/v_video.avi", this);
    mCoder->start(QThread::InheritPriority);

    // Audio recording
    mTimer = 0;
    mAudio = 0;

    if (QAudioDeviceInfo::availableDevices(QAudio::AudioInput).size() > 0) {
        mAudioFile.setFileName("Data/v_audio.raw");
        mAudioFile.open(QIODevice::WriteOnly | QIODevice::Truncate);

        QAudioFormat format;
        // Set up the desired format, for example:
        format.setSampleRate(mFAudioSamp);
        format.setChannelCount(1);
        format.setSampleSize(8);
        format.setCodec("audio/pcm");
        format.setByteOrder(QAudioFormat::LittleEndian);
        format.setSampleType(QAudioFormat::UnSignedInt);

        QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
        if (!info.isFormatSupported(format)) {
            qWarning() << "Default format not supported, trying to use the nearest.";
            format = info.nearestFormat(format);
        }

        mAudio = new QAudioInput(format, this);
        mAudio->setNotifyInterval(1000 / mVidFps);
        mAudio->start(&mAudioFile);
    } else {
        mTimer = new QTimer(this);
        mTimer->setInterval(1000 / mVidFps);
        mTimer->start();
    }

    mConsoleReader = new ConsoleReader(this);

    connect(mConsoleReader, SIGNAL(textReceived(QString)),
            this, SLOT(consoleLineReceived(QString)));

    connect(mPort, SIGNAL(serial_data_available()),
            this, SLOT(serialDataAvailable()));

    if (mTimer != 0) {
        connect(mTimer, SIGNAL(timeout()), this, SLOT(timerSlot()));
    }

    if (mAudio != 0) {
        connect(mAudio, SIGNAL(notify()),
                this, SLOT(audioNotify()));

        // Lower the volume to avoid clipping. This seems to be passed to
        // pulseaudio.
        mAudio->setVolume(0.1);
    }

    connect(mPacketInterface, SIGNAL(dataToSend(QByteArray&)),
            this, SLOT(packetDataToSend(QByteArray&)));
    connect(mPacketInterface, SIGNAL(valuesReceived(PacketInterface::MC_VALUES)),
            this, SLOT(mcValuesReceived(PacketInterface::MC_VALUES)));
    connect(mPacketInterface, SIGNAL(printReceived(QString)),
            this, SLOT(printReceived(QString)));
    connect(mPacketInterface, SIGNAL(samplesReceived(QByteArray)),
            this, SLOT(samplesReceived(QByteArray)));
    connect(mPacketInterface, SIGNAL(rotorPosReceived(double)),
            this, SLOT(rotorPosReceived(double)));
    connect(mPacketInterface, SIGNAL(experimentSamplesReceived(QVector<double>)),
            this, SLOT(experimentSamplesReceived(QVector<double>)));

    connect(mPlotter, SIGNAL(frameReady(QImage)),
            mCoder, SLOT(setNextFrame(QImage)));
}