void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ){ plumed_assert( cutoffwasset && pos.size()==indices.size() ); // Must be able to check that pbcs are not nonsensical in some way?? -- GAT // Setup the pbc object by copying it from action mypbc.setBox( pbc.getBox() ); // Setup the lists if( pos.size()!=allcells.size() ){ allcells.resize( pos.size() ); lcell_lists.resize( pos.size() ); } { // This is the reciprocal lattice // notice that reciprocal.getRow(0) is a vector that is orthogonal to b and c // This allows to use linked cells in non orthorhomic boxes Tensor reciprocal(transpose(mypbc.getInvBox())); ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff ); if( ncells[0]==0 ) ncells[0]=1; ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff ); if( ncells[1]==0 ) ncells[1]=1; ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff ); if( ncells[2]==0 ) ncells[2]=1; } // Setup the strides nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1]; // Setup the storage for link cells unsigned ncellstot=ncells[0]*ncells[1]*ncells[2]; if( lcell_tots.size()!=ncellstot ){ lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot ); } // Clear nlcells for(unsigned i=0;i<ncellstot;++i) lcell_tots[i]=0; // Clear allcells allcells.assign( allcells.size(), 0 ); // Find out what cell everyone is in unsigned rank=comm.Get_rank(), size=comm.Get_size(); for(unsigned i=rank;i<pos.size();i+=size){ allcells[i]=findCell( pos[i] ); lcell_tots[allcells[i]]++; } // And gather all this information on every node comm.Sum( allcells ); comm.Sum( lcell_tots ); // Now prepare the link cell lists unsigned tot=0; for(unsigned i=0;i<lcell_tots.size();++i){ lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; } plumed_assert( tot==pos.size() ); // And setup the link cells properly for(unsigned j=0;j<pos.size();++j){ unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ]; lcell_lists[ myind ] = indices[j]; lcell_tots[allcells[j]]++; } }
/* * this function makes a random maze with exactly one path between * any two points in the maze * * If you're curious about the algorithm, come talk to me. It's not very * complicated (although the code might be confusing) */ void makeMaze() { int num_visited = 1; int first; int finish_col; makeAllWalls(); markCell(0, 0); // mark the first cell as visited /* add the first cell (row 0, col 0) to the linked list of visited cells */ first = cellID(0, 0); annotateCell(0, 0, 0); while(num_visited < MAZE_SIZE * MAZE_SIZE) { int visit = rand() % num_visited; int cell = first; int row, col; int d; int nrow, ncol; findCell(cell, &row, &col); while (visit > 0) { cell = annotation(row, col); findCell(cell, &row, &col); visit -= 1; } d = rand() % 4; nrow = row; // row of neighbor cell ncol = col; // col of neighbor cell interpretDir(&nrow, &ncol, d); if (nrow >= 0 && nrow < MAZE_SIZE && ncol >= 0 && ncol < MAZE_SIZE && !isMarked(nrow, ncol)) { clearWall(row, col, d); num_visited += 1; markCell(nrow, ncol); annotateCell(nrow, ncol, first); first = cellID(nrow, ncol); } } start_col = rand() % MAZE_SIZE; start_col = 2 * start_col + 1; maze[0][start_col] &= ~WALL; finish_col = rand() % MAZE_SIZE; maze[MATRIX_SIZE - 1][2 * finish_col + 1] &= ~WALL; //maze[MATRIX_SIZE - 1][0] &= ~WALL; }
void MVList::dirtyCell(int i,int j) /**************************************************************************** * * Function: MVList::dirtyCell * Parameters: i,j - Index of the cell to dirty * * Description: Sets the dirty bit for the specified cell. * ****************************************************************************/ { findCell(i,j).flags |= lsDirty; }
void MVList::refreshCell(int i,int j) /**************************************************************************** * * Function: MVList::refreshCell * Parameters: i,j - Index of the cell to refresh * * Description: Refreshes the indexed cell if it is dirty. * ****************************************************************************/ { if (findCell(i,j).flags & lsDirty || (cursor.x == i && cursor.y == j)) MVListBase::drawCell(i,j); }
void HashMap<KeyType,ValueType>::remove(KeyType key) { int bucket = hashCode(key) % nBuckets; Cell *parent; Cell *cp = findCell(bucket, key, parent); if (cp != NULL) { if (parent == NULL) { buckets[bucket] = cp->next; } else { parent->next = cp->next; } delete cp; numEntries--; } }
/** * Initiates loop to run spreadsheet program until user quits * @param response Pointer to store the value entered by user at command prompt * @param spreadsheet The spreadsheet of cells * @param value Pointer that stores the value to be entered into a cell within the spreadsheet * @param address Pointer that stores the address of cell to store value * @param formula Pointer that stores formula * @param fType Pointer that stores the FormulaType to perform calculations */ void run(char *response, Cell spreadsheet[], char *value, size_t *address, char *formula, FormulaType *fType, int socket) { size_t addr; char val[IN_BUF_LIMIT]; char cacheAddr[CELL_ADDRESS]; char formatStr[80]; if (!recoveredSpreadSheet) initSpreadSheet(spreadsheet); displaySpreadSheetToClient(spreadsheet, socket); while (true) { if (!prompt(response, value, socket)) break; // cell guaranteed to be valid, no need for if statement. findCell(spreadsheet, response, address); addr = *address; printf("Address is: %lu\n", addr); printf("Value has %lu chars and is %s\n", strlen(value), value); sprintf(formatStr, "Old value: %s. New value: %s.\n", spreadsheet[addr].value, value); // fflush(st) printf("%s\n", value); // SOCKET_WRITE(socket, formatStr, MSG_DONTWAIT); SOCKET_WRITE(socket, "Return to reload spreadsheet", 0); if (isFormula(value, formula, fType)) { strcpy(cacheAddr, response); spreadsheet[addr].type = FORMULA; puts("FORMULA"); sprintf(val, "%f", calculateFormula(value, fType, spreadsheet, address)); printf("Val is %s\n", val); strcpy(spreadsheet[addr].value, val); spreadsheet[addr].address[0] = cacheAddr[0]; spreadsheet[addr].address[1] = cacheAddr[1]; spreadsheet[addr].address[2] = '\0'; } else if (cellAlNum(value) == true) { spreadsheet[addr].type = ALNUM; puts("ALNUM"); strcpy(spreadsheet[addr].value, value); } else { spreadsheet[addr].type = NUM; puts("NUM"); strcpy(spreadsheet[addr].value, value); // SEG-FAULTS HERE! } displaySpreadSheetToClient(spreadsheet, socket); saveWorkSheet(spreadsheet, socket); } SOCKET_WRITE(socket, "U got served bitch!", MSG_DONTWAIT); }
void MVList::toggleCell(int i,int j) /**************************************************************************** * * Function: MVList::toggleCell * Parameters: i,j - Index of cell to toggle * * Description: Toggles the selection flags for the specified cell. * ****************************************************************************/ { CellItem& cell = findCell(i,j);; cell.flags ^= lsSelected; cell.flags |= lsDirty; }
ValueType & HashMap<KeyType,ValueType>::operator[](KeyType key) { int bucket = hashCode(key) % nBuckets; Cell *cp = findCell(bucket, key); if (cp == NULL) { if (numEntries > MAX_LOAD_PERCENTAGE * nBuckets / 100.0) { expandAndRehash(); } cp = new Cell; cp->key = key; cp->value = ValueType(); cp->next = buckets[bucket]; buckets[bucket] = cp; numEntries++; } return cp->value; }
void MVList::deselectCell(int i,int j) /**************************************************************************** * * Function: MVList::deselectCell * Parameters: i,j - Index of the cell to de-select * * Description: Clears the selected flags for the item. If the cell was * already selected, we set the dirty bit for the cell. * ****************************************************************************/ { CellItem& cell = findCell(i,j); if (cell.flags & lsSelected) cell.flags |= lsDirty; cell.flags &= ~lsSelected; }
void MVList::drawCell(int i,int j,const MVRect& bounds) /**************************************************************************** * * Function: MVList::drawCell * Parameters: i,j - Index of the cell to draw * bounds - Bounding box to draw the item in * * Description: Draws the cell item within the specified bounds. Note that * the appropriate clipping rectangle will already have been * set up before this routine is called. * ****************************************************************************/ { CellItem& cell = findCell(i,j); if (cell.text) { // If the items is selected and this is the focused view, highlight // the item, otherwise clear the background for the item. dc.setColor(getColor( cell.flags & lsSelected ? scListHighlightCell : scListInterior)); dc.fillRect(bounds); // Draw the text for the item useFont(fmSystemFont); dc.setColor(getColor( cell.flags & lsSelected ? scListSelectedCell : scListCell)); dc.drawStr(bounds.left() + INDENTLEFT, bounds.top() + INDENTTOP,cell.text); // If the cursor is on the item, and view is focused then draw // a dotted outline around the cell. if ((state & sfFocused) && cursor.x == i && cursor.y == j) { attributes_t attr; dc.getAttributes(attr); dc.setColor(getColor( cell.flags & lsSelected ? scListCursor : scListCell)); dc.setPenStyle(MGL_BITMAP_TRANSPARENT); dc.setPenBitmapPattern(0,MGL_GRAY_FILL); dc.usePenBitmapPattern(0); drawRect(bounds); dc.restoreAttributes(attr); } } cell.flags &= ~lsDirty; }
void MVList::setCell(int i,int j,const char *text) /**************************************************************************** * * Function: MVList::setCell * Parameters: i,j - Index of the cell whose text to set * text - Pointer to the text for the cell * * Description: Sets the text for the cell. If this is NULL, nothing is * drawn in the cell. * ****************************************************************************/ { CellItem& cell = findCell(i,j); cell.text = text; cell.flags |= lsDirty; }
void MVList::selectCell(int i,int j) /**************************************************************************** * * Function: MVList::selectCell * Parameters: i,j - Index of the cell to select * * Description: Sets the selected flag for the item. If the cell was not * already selected, we set the dirty bit for the cell. * ****************************************************************************/ { CellItem& cell = findCell(i,j); if (!(cell.flags & lsSelected)) cell.flags |= lsDirty; cell.flags |= lsSelected; }
ibool MVList::getCell(int i,int j,const char*& text) /**************************************************************************** * * Function: MVList::getCell * Parameters: i,j - Index of the cell whose text to set * text - Place to store the text for the cell * Returns: True if the cell is selected, false if not. * * Description: Finds the text of a cell, returning true if the cell is * selected. * ****************************************************************************/ { CellItem& cell = findCell(i,j); text = cell.text; return (cell.flags & lsSelected); }
bool CMagic120Cell::calcViewTwist( int clickedCell, bool leftClick, STwist & twist ) { CSettings & settings = getSettings(); int newCellIndex = clickedCell; int oldCellIndex = settings.m_centerCell; Cell & newCell = m_cellsUnprojected[newCellIndex]; Cell & oldCell = m_cellsUnprojected[oldCellIndex]; twist.m_leftClick = leftClick; if( setupViewRotation( twist, newCell, oldCell ) ) { if( leftClick ) settings.m_centerCell = newCellIndex; else { // We have to search for the new center. // This was so difficult to figure out!!! God, it sucked. // I would have thought the oldCell would always be at 0,0,0,-1 after // the current view rotations, and that for this reason we wouldn't // have to apply the current view rotations below, but that wasn't true. CVector4D newCenter = m_cellsUnprojected[oldCellIndex].getCenter(); CMatrix4D tempRot; twist.getViewRotationMatrix( twist.m_viewRotationMagnitude*-1, tempRot ); CMatrix4D R = m_currentViewRotation * tempRot; newCenter.rotateFromMatrix( R.m ); settings.m_centerCell = findCell( newCenter ); } return true; } return false; }
/** * @brief Finds the next Cell for a LocalCoords object along a trajectory * defined by some angle (in radians from 0 to pi). * @details The method will update the LocalCoords passed in as an argument * to be the one at the boundary of the next Cell crossed along the * given trajectory. It will do this by recursively building a linked * list of LocalCoords from the LocalCoords passed in as an argument * down to the lowest level Cell found. In the process it will set * the local coordinates for each LocalCoords in the linked list for * the Lattice or Universe that it is in. If the LocalCoords is * outside the bounds of the Lattice or on the boundaries this method * will return NULL; otherwise it will return a pointer to the Cell * that the LocalCoords will reach next along its trajectory. * @param coords pointer to a LocalCoords object * @param angle the angle of the trajectory * @param universes a map of all of the Universes passed in by the Geometry * @return a pointer to a Cell if found, NULL if no cell found */ Cell* Lattice::findNextLatticeCell(LocalCoords* coords, double angle, std::map<int, Universe*> universes) { /* Tests the upper, lower, left and right Lattice Cells adjacent to * the LocalCoord and uses the one with the shortest distance from * the current location of the LocalCoord */ /* Initial distance is infinity */ double distance = std::numeric_limits<double>::infinity(); /* Current minimum distance */ double d; /* Properties of the current LocalCoords */ double x0 = coords->getX(); double y0 = coords->getY(); int lattice_x = coords->getLatticeX(); int lattice_y = coords->getLatticeY(); /* Slope of trajectory */ double m = sin(angle) / cos(angle); /* Properties of the new location for LocalCoords */ /* Current point of minimum distance */ double x_curr, y_curr; /* x-coordinate on new Lattice cell */ double x_new = x0; /* y-coordinate on new Lattice cell */ double y_new = x0; /* New x Lattice cell index */ int new_lattice_x; /* New y Lattice cell index */ int new_lattice_y; /* Test Point for computing distance */ Point test; /* Check lower Lattice cell */ if (lattice_y >= 0 && angle >= M_PI) { y_curr = (lattice_y - _num_y/2.0) * _width_y; x_curr = x0 + (y_curr - y0) / m; test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Upper Lattice cell */ if (lattice_y <= _num_y-1 && angle <= M_PI) { y_curr = (lattice_y - _num_y/2.0 + 1) * _width_y; x_curr = x0 + (y_curr - y0) / m; test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Left Lattice cell */ if (lattice_x >= 0 && (angle >= M_PI/2 && angle <= 3*M_PI/2)) { x_curr = (lattice_x - _num_x/2.0) * _width_x; y_curr = y0 + m * (x_curr - x0); test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* Right Lattice cell */ if (lattice_x <= _num_x-1 && (angle <= M_PI/2 || angle >= 3*M_PI/2)) { x_curr = (lattice_x - _num_x/2.0 + 1) * _width_x; y_curr = y0 + m * (x_curr - x0); test.setCoords(x_curr, y_curr); /* Check if the test Point is within the bounds of the Lattice */ if (withinBounds(&test)) { d = test.distanceToPoint(coords->getPoint()); /* Check if distance to test Point is current minimum */ if (d < distance) { distance = d; x_new = x_curr; y_new = y_curr; } } } /* If no Point was found on the Lattice cell, then the LocalCoords was * already on the boundary of the Lattice */ if (distance == INFINITY) return NULL; /* Otherwise a Point was found inside a new Lattice cell */ else { /* Update the Localcoords location to the Point on the new Lattice cell * plus a small bit to ensure that its coordinates are inside cell */ double delta_x = (x_new - coords->getX()) + cos(angle) * TINY_MOVE; double delta_y = (y_new - coords->getY()) + sin(angle) * TINY_MOVE; coords->adjustCoords(delta_x, delta_y); /* Compute the x and y indices for the new Lattice cell */ new_lattice_x = (int)floor((coords->getX() - _origin.getX())/_width_x); new_lattice_y = (int)floor((coords->getY() - _origin.getY())/_width_y); /* Check if the LocalCoord is on the lattice boundaries and if so adjust * x or y Lattice cell indices i */ if (fabs(fabs(coords->getX()) - _num_x*_width_x*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getX() > 0) new_lattice_x = _num_x - 1; else new_lattice_x = 0; } if (fabs(fabs(coords->getY()) - _num_y*_width_y*0.5) < ON_LATTICE_CELL_THRESH) { if (coords->getY() > 0) new_lattice_y = _num_y - 1; else new_lattice_y = 0; } /* Check if new Lattice cell indices are within the bounds, if not, * new LocalCoords is now on the boundary of the Lattice */ if (new_lattice_x >= _num_x || new_lattice_x < 0) return NULL; else if (new_lattice_y >= _num_y || new_lattice_y < 0) return NULL; /* New LocalCoords is still within the interior of the Lattice */ else { /* Update the LocalCoords Lattice cell indices */ coords->setLatticeX(new_lattice_x); coords->setLatticeY(new_lattice_y); /* Move to next lowest level Universe */ coords->prune(); Universe* univ = _universes.at(new_lattice_y).at(new_lattice_x).second; LocalCoords* next_coords; /* Compute local position of Point in next level Universe */ double nextX = coords->getX() - (_origin.getX() + (new_lattice_x + 0.5) * _width_x); double nextY = coords->getY() - (_origin.getY() + (new_lattice_y + 0.5) * _width_y); /* Set the coordinates at the next level LocalCoord */ next_coords = new LocalCoords(nextX, nextY); next_coords->setPrev(coords); coords->setNext(next_coords); next_coords->setUniverse(univ->getId()); /* Search lower level Universe */ return findCell(coords, universes); } } }
void ThreeByThreeBoard::Apply(int input, string owner) { Cell * cell = findCell(input); cell->Owner = owner; }
bool HashMap<KeyType,ValueType>::containsKey(KeyType key) const { return findCell(hashCode(key) % nBuckets, key) != NULL; }
ValueType HashMap<KeyType,ValueType>::get(KeyType key) const { Cell *cp = findCell(hashCode(key) % nBuckets, key); if (cp == NULL) error("get: no value for key"); return cp->value; }
Cell ThreeByThreeBoard::FindCell(int value) { return * findCell(value); }
void LineCombiner::add( QPointF p1, QPointF p2 ) { bool ok; qDebug() << "add" << p1 << p2; // find closest points within the threshold distance of p1 and p2 IndexPt * ip1 = _findClosestPt( p1 ); IndexPt * ip2 = _findClosestPt( p2 ); // normalize the cases if ( ! ip1 ) { std::swap( ip1, ip2 ); std::swap( p1, p2 ); } if ( ip1 ) { CARTA_ASSERT( ip1-> poly ); } if ( ip2 ) { CARTA_ASSERT( ip2-> poly ); } // case1: this line segment is not near anything else if ( ip1 == nullptr && ip2 == nullptr ) { qDebug() << "case null null"; // we insert a new polyline and update spacial index // make a new polyline from p1 and p2 Poly * poly = new Poly; poly->append( p1 ); poly->append( p2 ); // insert beginning of this polyline into grid findCell( p1 )-> pts.append( IndexPt( poly, false ) ); // insert end of this polyine into grid findCell( p2 )-> pts.append( IndexPt( poly, true ) ); IndexPt ipt1( poly, true ); CARTA_ASSERT( findCell( ipt1.pt() )->pts.contains( ipt1 ) ); return; } // catch a super-special case.... both points point to the same polyline, same end... // we'll treat this as if only one of the points pointed to a polyline) if( ip2 && ip1->poly == ip2->poly && ip1->flipped == ip2->flipped) { qDebug() << "super special"; ip2 = nullptr; } // only one point has a match (ip1, ip2 is null) if ( ip1 != nullptr && ip2 == nullptr ) { qDebug() << "case poly null"; // make a copy of what ip1 points to, because it'll be destroyed IndexPt ip1copy = * ip1; // remove ip1 from it's corresponding cell (after this ip1 will point to // a destroyed memory!) ok = findCell( ip1-> pt() )-> pts.removeOne( * ip1 ); CARTA_ASSERT( ok ); // re-point ip1 to the copy ip1 = & ip1copy; // we extend the polyline that ip1 points to with p2 if ( ip1-> flipped ) { ip1-> poly-> append( p2 ); } else { ip1-> poly-> prepend( p2 ); } // and add a new index point (for p2) to the respective cell findCell( p2 )-> pts.append( * ip1 ); return; } // both points have a match, and it's the same polyline, but different ends... if ( ip1-> poly == ip2-> poly ) { qDebug() << "case poly poly same"; CARTA_ASSERT( ip1->flipped == ! ip2->flipped ); // we need to remove both points from their cells Poly * poly = ip1->poly; ok = findCell( ip1->pt() )->pts.removeOne( * ip1 ); CARTA_ASSERT( ok ); ok = findCell( ip2->pt() )->pts.removeOne( * ip2 ); CARTA_ASSERT( ok ); // make it a closed polyline poly->append( poly->first() ); QPolygonF polygon = poly2polygon( poly ); m_polygons.push_back( polygon ); delete poly; return; } // last case is: both points have a match to 2 different polylines qDebug() << "case poly poly diff"; // we need to merge these two polylines together IndexPt ip1c = * ip1; IndexPt ip2c = * ip2; // remove first polyline from the spatial index ok = findCell( ip1c.poly->front() )-> pts.removeAll( { ip1c.poly, false } ); CARTA_ASSERT( ok ); ok = findCell( ip1c.poly->back() )-> pts.removeAll( { ip1c.poly, true } ); CARTA_ASSERT( ok ); // remove second polyline from the spatial index ok = findCell( ip2c.poly->front() )-> pts.removeAll( { ip2c.poly, false } ); CARTA_ASSERT( ok ); ok = findCell( ip2c.poly->back() )-> pts.removeAll( { ip2c.poly, true } ); CARTA_ASSERT( ok ); Q_UNUSED(ok); // we need to handle 4 cases for merging... in any case, we'll be re-using poly1 and // appending/prepending to it all elements from poly2 // case1: append poly2 to the end of poly1, in forward order if ( ip1c.flipped && ! ip2c.flipped ) { qDebug() << "subcase1 - append forward"; for ( auto & pt : * ip2c.poly ) { ip1c.poly->append( pt ); } } else if ( ip1c.flipped && ip2c.flipped ) { qDebug() << "subcase2 - append reverse"; QLinkedListIterator < QPointF > i( * ip2c.poly ); i.toBack(); while ( i.hasPrevious() ) { ip1c.poly-> append( i.previous() ); } } else if ( ! ip1c.flipped && ! ip2c.flipped ) { qDebug() << "subase3 - prepend forward"; for ( auto & pt : * ip2c.poly ) { ip1c.poly->prepend( pt ); } } else { qDebug() << "subase4 - prepend reverse"; QLinkedListIterator < QPointF > i( * ip2c.poly ); i.toBack(); while ( i.hasPrevious() ) { ip1c.poly-> prepend( i.previous() ); } } // get rid of poly2 delete ip2c.poly; // re-insert the endpoints of poly1 into spatial index ip1c = IndexPt( ip1c.poly, false ); ip2c = IndexPt( ip1c.poly, true ); findCell( ip1c.poly->first() )->pts.append( ip1c ); findCell( ip1c.poly->last() )->pts.append( ip2c ); } // add
ValueType HashMap<KeyType,ValueType>::get(KeyType key) const { Cell *cp = findCell(hashCode(key) % nBuckets, key); if (cp == NULL) return ValueType(); return cp->value; }
CCM_FUNC static THD_FUNCTION(ThreadADC, arg) { (void)arg; chRegSetThreadName("Sensors"); adcsample_t * sensorsDataPtr; size_t n; uint16_t i, pos; uint32_t an[3] = {0, 0, 0}; median_t an1, an2, an3; uint8_t row, col; chThdSleepMilliseconds(250); timcapEnable(&TIMCAPD3); chVTSet(&vt_freqin, FREQIN_INTERVAL, freqinVTHandler, NULL); adcStartConversion(&ADCD1, &adcgrpcfg_sensors, samples_sensors, ADC_GRP1_BUF_DEPTH); median_init(&an1, 0 , an1_buffer, ADC_GRP1_BUF_DEPTH/2); median_init(&an2, 0 , an2_buffer, ADC_GRP1_BUF_DEPTH/2); median_init(&an3, 0 , an3_buffer, ADC_GRP1_BUF_DEPTH/2); while (TRUE) { while (!recvFreeSamples(&sensorsMb, (void*)&sensorsDataPtr, &n)) chThdSleepMilliseconds(5); an[0]= 0; an[1]= 0; an[2]= 0; /* Filtering and adding */ for (i = 0; i < (n/ADC_GRP1_NUM_CHANNELS); i++) { pos = i * ADC_GRP1_NUM_CHANNELS; an[0] += median_filter(&an1, sensorsDataPtr[pos]); an[1] += median_filter(&an2, sensorsDataPtr[pos+1]); an[2] += median_filter(&an3, sensorsDataPtr[pos+2]); } /* Averaging */ an[0] /= (n/ADC_GRP1_NUM_CHANNELS); an[1] /= (n/ADC_GRP1_NUM_CHANNELS); an[2] /= (n/ADC_GRP1_NUM_CHANNELS); /* Convert to milliVolts */ an[0] *= VBAT_RATIO; an[1] *= AN_RATIO; an[2] *= AN_RATIO; sensors_data.an1 = an[0]; sensors_data.an2 = an[1]; sensors_data.an3 = an[2]; /* Analog/Digital Sensors */ if (settings.sensorsInput == SENSORS_INPUT_DIRECT) { sensors_data.tps = calculateTpFromMillivolt(settings.tpsMinV, settings.tpsMaxV, sensors_data.an2); sensors_data.rpm = calculateFreqWithRatio(sensors_data.freq1, settings.rpmMult); sensors_data.spd = calculateFreqWithRatio(sensors_data.freq2, settings.spdMult); } else if (settings.sensorsInput == SENSORS_INPUT_TEST) { sensors_data.tps = rand16(0, 200); sensors_data.rpm = rand16(10, 18000); sensors_data.spd = rand16(5, 10000); } /* AFR */ if (settings.afrInput == AFR_INPUT_AN) { sensors_data.afr = calculateAFRFromMillivolt(settings.AfrMinVal, settings.AfrMaxVal, sensors_data.an3); } else if (settings.afrInput == AFR_INPUT_TEST) { sensors_data.afr = rand16(11000, 16000) / 100; } if (dbg_sensors) { chprintf(DBG_STREAM,"->[SENSORS] TPS mV/PCT: %06u/%04u\r\n", sensors_data.an2, sensors_data.tps); chprintf(DBG_STREAM,"->[SENSORS] RMP Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq1, settings.rpmMult, sensors_data.rpm); chprintf(DBG_STREAM,"->[SENSORS] SPD Hz/Mult/Val: %06u/%.4f/%04u\r\n", sensors_data.freq2, settings.spdMult, sensors_data.spd); } if (findCell(sensors_data.tps/2, sensors_data.rpm, &row, &col)) { sensors_data.cell.row = row; sensors_data.cell.col = col; if (dbg_sensors) { chprintf(DBG_STREAM,"->[SENSORS] Row:Value/Col:Value: %02u:%05u/%02u:%05u\r\n", row, tableRows[row], col, tableColumns[col]*100); } if ((settings.functions & FUNC_RECORD) && sensors_data.rpm != 0) { /* Average */ tableAFR[row][col] = tableAFR[row][col] == 0 ? sensors_data.afr : ((uint16_t)sensors_data.afr+(uint16_t)tableAFR[row][col])/2; /* Peaks */ tableKnock[row][col] = sensors_data.knock_value > tableKnock[row][col] ? sensors_data.knock_value : tableKnock[row][col]; } } } return; }
/** * Calculates the result of entered formula * @param value The formula * @param ftype Type of formula (SUM, RANGE, AVERAGE) * @param sheet The spreadsheet * @param address Address of the cell to store result * @return Result of calculation */ double calculateFormula(char *value, FormulaType *ftype, Cell sheet[], size_t *address) { char addr1[CELL_ADDRESS]; //stores the extracted value of the first address in formula char addr2[CELL_ADDRESS]; //stores the extracted value of the first address in formula double answer = 0.0; size_t i, start, end, temp, count; switch (*ftype) { case AVERAGE: addr1[0] = value[8]; addr1[1] = value[9]; addr1[2] = '\0'; addr2[0] = value[11]; addr2[1] = value[12]; addr2[2] = '\0'; findCell(sheet, addr1, address); start = *address; findCell(sheet, addr2, address); end = *address; // Swaps start and end if start address is greater than end address if (start > end) { temp = start; start = end; end = temp; } // If addresses are in the same column then do calculations with values vertically if (addr1[0] == addr2[0]) { count = 0; for (i = start; i <= end;) { if (sheet[i].type == NUM) { answer += atof(sheet[i].value); ++count; } i += 9; } answer = answer / count; // If addresses are in the same row then do calculations with values horizontally } else if (toupper(addr1[1]) == toupper(addr2[1])) { count = 0; for (i = start; i < end; i++) { if (sheet[i].type == NUM) { answer += atof(sheet[i].value); ++count; } } if (answer > 0) answer = answer / count; else answer = 0; } break; case SUM: addr1[0] = value[4]; addr1[1] = value[5]; addr1[2] = '\0'; addr2[0] = value[7]; addr2[1] = value[8]; addr2[2] = '\0'; findCell(sheet, addr1, address); start = *address; findCell(sheet, addr2, address); end = *address; // Swaps start and end if start address is greater than end address if (start > end) { temp = start; start = end; end = temp; } // If addresses are in the same column then do calculations with values vertically if (addr1[0] == addr2[0]) { for (i = start; i <= end;) { if (sheet[i].type == NUM) answer += atof(sheet[i].value); i += 9; } // If addresses are in the same row then do calculations with values horizontally } else if (toupper(addr1[1]) == toupper(addr2[1])) { for (i = start; i < end; i++) { if (sheet[i].type == NUM) answer += atof(sheet[i].value); } } break; case RANGE: addr1[0] = value[6]; addr1[1] = value[7]; addr1[2] = '\0'; addr2[0] = value[9]; addr2[1] = value[10]; addr2[2] = '\0'; findCell(sheet, addr1, address); start = *address; findCell(sheet, addr2, address); end = *address; // Swaps start and end if start address is greater than end address if (start > end) { temp = start; start = end; end = temp; } // If addresses are in the same column then do calculations with values vertically if (addr1[0] == addr2[0]) { answer = 0; for (i = start; i <= end;) { if (sheet[i].type == NUM) { if (atof(sheet[i].value) > answer) answer = atof(sheet[i].value); } i += 9; } // If addresses are in the same row then do calculations with values horizontally } else if (toupper(addr1[1]) == toupper(addr2[1])) { for (i = start; i < end; i++) { if (sheet[i].type == NUM) { if (atof(sheet[i].value) > answer) answer = atof(sheet[i].value); } } } break; } return answer; }