void PowerHist::setData(RideItem *_rideItem) { rideItem = _rideItem; RideFile *ride = rideItem->ride(); if (ride) { setTitle(ride->startTime().toString(GC_DATETIME_FORMAT)); static const int maxSize = 4096; // recording interval in minutes dt = ride->recIntSecs() / 60.0; wattsArray.resize(0); wattsZoneArray.resize(0); nmArray.resize(0); hrArray.resize(0); hrZoneArray.resize(0); kphArray.resize(0); cadArray.resize(0); wattsSelectedArray.resize(0); wattsZoneSelectedArray.resize(0); nmSelectedArray.resize(0); hrSelectedArray.resize(0); hrZoneSelectedArray.resize(0); kphSelectedArray.resize(0); cadSelectedArray.resize(0); // unit conversion factor for imperial units for selected parameters double torque_factor = (useMetricUnits ? 1.0 : 0.73756215); double speed_factor = (useMetricUnits ? 1.0 : 0.62137119); foreach(const RideFilePoint *p1, ride->dataPoints()) { bool selected = isSelected(p1, ride->recIntSecs()); // watts array int wattsIndex = int(floor(p1->watts / wattsDelta)); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsArray.size()) wattsArray.resize(wattsIndex + 1); wattsArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsSelectedArray.size()) wattsSelectedArray.resize(wattsIndex + 1); wattsSelectedArray[wattsIndex]++; } } // watts zoned array const Zones *zones = rideItem->zones; int zoneRange = zones ? zones->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range and check zeroes if (zoneRange > -1 && (withz || (!withz && p1->watts))) { wattsIndex = zones->whichZone(zoneRange, p1->watts); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsZoneArray.size()) wattsZoneArray.resize(wattsIndex + 1); wattsZoneArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsZoneSelectedArray.size()) wattsZoneSelectedArray.resize(wattsIndex + 1); wattsZoneSelectedArray[wattsIndex]++; } } } int nmIndex = int(floor(p1->nm * torque_factor / nmDelta)); if (nmIndex >= 0 && nmIndex < maxSize) { if (nmIndex >= nmArray.size()) nmArray.resize(nmIndex + 1); nmArray[nmIndex]++; if (selected) { if (nmIndex >= nmSelectedArray.size()) nmSelectedArray.resize(nmIndex + 1); nmSelectedArray[nmIndex]++; } } int hrIndex = int(floor(p1->hr / hrDelta)); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrArray.size()) hrArray.resize(hrIndex + 1); hrArray[hrIndex]++; if (selected) { if (hrIndex >= hrSelectedArray.size()) hrSelectedArray.resize(hrIndex + 1); hrSelectedArray[hrIndex]++; } } // hr zoned array int hrZoneRange = mainWindow->hrZones() ? mainWindow->hrZones()->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range if (hrZoneRange > -1 && (withz || (!withz && p1-hr))) { hrIndex = mainWindow->hrZones()->whichZone(hrZoneRange, p1->hr); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrZoneArray.size()) hrZoneArray.resize(hrIndex + 1); hrZoneArray[hrIndex]++; if (selected) { if (hrIndex >= hrZoneSelectedArray.size()) hrZoneSelectedArray.resize(hrIndex + 1); hrZoneSelectedArray[hrIndex]++; } } } int kphIndex = int(floor(p1->kph * speed_factor / kphDelta)); if (kphIndex >= 0 && kphIndex < maxSize) { if (kphIndex >= kphArray.size()) kphArray.resize(kphIndex + 1); kphArray[kphIndex]++; if (selected) { if (kphIndex >= kphSelectedArray.size()) kphSelectedArray.resize(kphIndex + 1); kphSelectedArray[kphIndex]++; } } int cadIndex = int(floor(p1->cad / cadDelta)); if (cadIndex >= 0 && cadIndex < maxSize) { if (cadIndex >= cadArray.size()) cadArray.resize(cadIndex + 1); cadArray[cadIndex]++; if (selected) { if (cadIndex >= cadSelectedArray.size()) cadSelectedArray.resize(cadIndex + 1); cadSelectedArray[cadIndex]++; } } } recalc(); } else {
void PowerHist::setData(RideItem *_rideItem, bool force) { // predefined deltas for each series static const double wattsDelta = 1.0; static const double wattsKgDelta = 0.01; static const double nmDelta = 0.1; static const double hrDelta = 1.0; static const double kphDelta = 0.1; static const double cadDelta = 1.0; source = Ride; // we set with this data already if (force == false && _rideItem == LASTrideItem && source == LASTsource) return; rideItem = _rideItem; if (!rideItem) return; RideFile *ride = rideItem->ride(); bool hasData = ((series == RideFile::watts || series == RideFile::wattsKg) && ride->areDataPresent()->watts) || (series == RideFile::nm && ride->areDataPresent()->nm) || (series == RideFile::kph && ride->areDataPresent()->kph) || (series == RideFile::cad && ride->areDataPresent()->cad) || (series == RideFile::aPower && ride->areDataPresent()->apower) || (series == RideFile::hr && ride->areDataPresent()->hr); if (ride && hasData) { //setTitle(ride->startTime().toString(GC_DATETIME_FORMAT)); static const int maxSize = 4096; // recording interval in minutes dt = ride->recIntSecs() / 60.0; wattsArray.resize(0); wattsZoneArray.resize(0); wattsKgArray.resize(0); aPowerArray.resize(0); nmArray.resize(0); hrArray.resize(0); hrZoneArray.resize(0); kphArray.resize(0); cadArray.resize(0); wattsSelectedArray.resize(0); wattsZoneSelectedArray.resize(0); wattsKgSelectedArray.resize(0); aPowerSelectedArray.resize(0); nmSelectedArray.resize(0); hrSelectedArray.resize(0); hrZoneSelectedArray.resize(0); kphSelectedArray.resize(0); cadSelectedArray.resize(0); // unit conversion factor for imperial units for selected parameters double torque_factor = (context->athlete->useMetricUnits ? 1.0 : 0.73756215); double speed_factor = (context->athlete->useMetricUnits ? 1.0 : 0.62137119); foreach(const RideFilePoint *p1, ride->dataPoints()) { bool selected = isSelected(p1, ride->recIntSecs()); // watts array int wattsIndex = int(floor(p1->watts / wattsDelta)); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsArray.size()) wattsArray.resize(wattsIndex + 1); wattsArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsSelectedArray.size()) wattsSelectedArray.resize(wattsIndex + 1); wattsSelectedArray[wattsIndex]++; } } // watts zoned array const Zones *zones = rideItem->zones; int zoneRange = zones ? zones->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range and check zeroes if (zoneRange > -1 && (withz || (!withz && p1->watts))) { wattsIndex = zones->whichZone(zoneRange, p1->watts); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsZoneArray.size()) wattsZoneArray.resize(wattsIndex + 1); wattsZoneArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsZoneSelectedArray.size()) wattsZoneSelectedArray.resize(wattsIndex + 1); wattsZoneSelectedArray[wattsIndex]++; } } } // aPower array int aPowerIndex = int(floor(p1->apower / wattsDelta)); if (aPowerIndex >= 0 && aPowerIndex < maxSize) { if (aPowerIndex >= aPowerArray.size()) aPowerArray.resize(aPowerIndex + 1); aPowerArray[aPowerIndex]++; if (selected) { if (aPowerIndex >= aPowerSelectedArray.size()) aPowerSelectedArray.resize(aPowerIndex + 1); aPowerSelectedArray[aPowerIndex]++; } } // wattsKg array int wattsKgIndex = int(floor(p1->watts / ride->getWeight() / wattsKgDelta)); if (wattsKgIndex >= 0 && wattsKgIndex < maxSize) { if (wattsKgIndex >= wattsKgArray.size()) wattsKgArray.resize(wattsKgIndex + 1); wattsKgArray[wattsKgIndex]++; if (selected) { if (wattsKgIndex >= wattsKgSelectedArray.size()) wattsKgSelectedArray.resize(wattsKgIndex + 1); wattsKgSelectedArray[wattsKgIndex]++; } } int nmIndex = int(floor(p1->nm * torque_factor / nmDelta)); if (nmIndex >= 0 && nmIndex < maxSize) { if (nmIndex >= nmArray.size()) nmArray.resize(nmIndex + 1); nmArray[nmIndex]++; if (selected) { if (nmIndex >= nmSelectedArray.size()) nmSelectedArray.resize(nmIndex + 1); nmSelectedArray[nmIndex]++; } } int hrIndex = int(floor(p1->hr / hrDelta)); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrArray.size()) hrArray.resize(hrIndex + 1); hrArray[hrIndex]++; if (selected) { if (hrIndex >= hrSelectedArray.size()) hrSelectedArray.resize(hrIndex + 1); hrSelectedArray[hrIndex]++; } } // hr zoned array int hrZoneRange = context->athlete->hrZones() ? context->athlete->hrZones()->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range if (hrZoneRange > -1 && (withz || (!withz && p1->hr))) { hrIndex = context->athlete->hrZones()->whichZone(hrZoneRange, p1->hr); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrZoneArray.size()) hrZoneArray.resize(hrIndex + 1); hrZoneArray[hrIndex]++; if (selected) { if (hrIndex >= hrZoneSelectedArray.size()) hrZoneSelectedArray.resize(hrIndex + 1); hrZoneSelectedArray[hrIndex]++; } } } int kphIndex = int(floor(p1->kph * speed_factor / kphDelta)); if (kphIndex >= 0 && kphIndex < maxSize) { if (kphIndex >= kphArray.size()) kphArray.resize(kphIndex + 1); kphArray[kphIndex]++; if (selected) { if (kphIndex >= kphSelectedArray.size()) kphSelectedArray.resize(kphIndex + 1); kphSelectedArray[kphIndex]++; } } int cadIndex = int(floor(p1->cad / cadDelta)); if (cadIndex >= 0 && cadIndex < maxSize) { if (cadIndex >= cadArray.size()) cadArray.resize(cadIndex + 1); cadArray[cadIndex]++; if (selected) { if (cadIndex >= cadSelectedArray.size()) cadSelectedArray.resize(cadIndex + 1); cadSelectedArray[cadIndex]++; } } } } else {
int read_page() { int sum = 0; int bytes_read = 0; char record_command = read_bytes(1, &bytes_read, &sum); // Always 0x89 if ((0xff & record_command) == 0x89) { // 1. page # data int page_number = read_bytes(2, &bytes_read, &sum); // Page # int data_number = read_bytes(1, &bytes_read, &sum); // # of data in page if (page_number == 1 || (page_number == 64010 and secs == 0.0)) { // 2. Training Summary data (60 bytes)"; read_bytes(39, &bytes_read, &sum); int record_training_flag = read_bytes(1, &bytes_read, &sum); // Training Flag if ((record_training_flag & 0x01) == 0) { // Only new lap rideFile->addInterval(last_interval_secs, secs, QString("%1").arg(interval)); last_interval_secs = secs; interval ++; } read_bytes(20, &bytes_read, &sum); // Don't care } if (page_number == 1 || (page_number == 64010 and secs == 0.0)) { // Section Start time and date data (12 byte) int sec = read_bsd_byte(&bytes_read, &sum); // Section start time sec int min = read_bsd_byte(&bytes_read, &sum); // Section start time min int hour = read_bsd_byte(&bytes_read, &sum); // Section start time hour int day = read_bsd_byte(&bytes_read, &sum); // Section start time day int month = read_bytes(1, &bytes_read, &sum); // Section start time month int year = read_bsd_byte(&bytes_read, &sum); // Section start time year QDateTime t = QDateTime(QDate(2000+year,month,day), QTime(hour,min,sec)); if (secs == 0.0 || rideFile->startTime().toTime_t()<0) { rideFile->setStartTime(t); } else { int gap = (t.toTime_t() - rideFile->startTime().toTime_t()) - secs; secs += gap; } read_bytes(5, &bytes_read, &sum); // Don't care read_bytes(1, &bytes_read, &sum); // Data Flag data_number--; } for (int i = 0; i < data_number; ++i) { read_graph_data(&secs, &bytes_read, &sum); } int finish = 259-bytes_read; for (int i = 0; i < finish; i++) { read_bytes(1, &bytes_read, &sum); // to finish } read_bytes(1, &bytes_read, &sum); // Checksum } return bytes_read; }
void PfPvPlot::setData(RideItem *_rideItem) { rideItem = _rideItem; RideFile *ride = rideItem->ride; if (ride) { setTitle(ride->startTime().toString(GC_DATETIME_FORMAT)); // quickly erase old data curve->setVisible(false); // handle zone stuff refreshZoneItems(); // due to the discrete power and cadence values returned by the // power meter, there will very likely be many duplicate values. // Rather than pass them all to the curve, use a set to strip // out duplicates. std::set<std::pair<double, double> > dataSet; long tot_cad = 0; long tot_cad_points = 0; foreach(const RideFilePoint *p1, ride->dataPoints()) { if (p1->watts != 0 && p1->cad != 0) { double aepf = (p1->watts * 60.0) / (p1->cad * cl_ * 2.0 * PI); double cpv = (p1->cad * cl_ * 2.0 * PI) / 60.0; dataSet.insert(std::make_pair<double, double>(aepf, cpv)); tot_cad += p1->cad; tot_cad_points++; } } if (tot_cad_points == 0) { setTitle("no cadence"); refreshZoneItems(); curve->setVisible(false); } else { // Now that we have the set of points, transform them into the // QwtArrays needed to set the curve's data. QwtArray<double> aepfArray; QwtArray<double> cpvArray; std::set<std::pair<double, double> >::const_iterator j(dataSet.begin()); while (j != dataSet.end()) { const std::pair<double, double>& dataPoint = *j; aepfArray.push_back(dataPoint.first); cpvArray.push_back(dataPoint.second); ++j; } setCAD(tot_cad / tot_cad_points); curve->setData(cpvArray, aepfArray); // now show the data (zone shading would already be visible) curve->setVisible(true); } } else {