/* * Check if a node is in the list * @param node: The A* node to check the list for * @return the A* Node Pointer if it is in the list, NULL otherwise */ AStarNode* AStarNodeList::check_duplicate(AStarNode* node) { /* Make sure a node is passed as a parameter */ if (node == NULL) throw TerminalException("Invalid node passed to check_duplicate()."); /* A* Node found in the list */ AStarNode* found; /* Having no parent means that the position must exist somewhere in the list */ if (node->get_parent_bitmap() == 0) found = check_duplicate(node->get_pos(), NULL); /* Check for a duplicate with a parent */ else { Coord parent_coord = node->get_parent(); found = check_duplicate(node->get_pos(), &parent_coord); } /* Make sure the returned node is the SAME node pointed to by the A* Node parameter */ if (found == NULL || node == found) return found; /* * If the found node is not NULL and not the same node pointed to as the parameter, * an error has occurred */ throw TerminalException( "Found node is not a pointer to the same node as the node being sought." ); }
/** * \internal * \p cell and \p path_string may be NULL */ static void __category_edit_on_value_edited(GtkCellRendererText * cell, gchar * path_string, gchar * new_text, GebrGuiSequenceEdit * sequence_edit) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *old_text; GebrGeoXmlCategory *category; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sequence_edit->tree_view)); gtk_tree_selection_get_selected(selection, &model, &iter); gtk_tree_model_get(GTK_TREE_MODEL(sequence_edit->list_store), &iter, 0, &old_text, -1); gebr_gui_sequence_edit_set_keypresses(sequence_edit, TRUE); if (!strcmp (old_text, new_text)) return; if (check_duplicate (sequence_edit, new_text) || __category_edit_check_text(new_text)) return; gtk_tree_model_get(GTK_TREE_MODEL(sequence_edit->list_store), &iter, 2, &category, -1); gtk_list_store_set(sequence_edit->list_store, &iter, 0, new_text, -1); gebr_geoxml_value_sequence_set(GEBR_GEOXML_VALUE_SEQUENCE(category), new_text); __category_edit_validate_iter(CATEGORY_EDIT(sequence_edit), &iter); g_signal_emit_by_name(sequence_edit, "changed"); }
static uint8_t input_packet(struct net_buf *buf) { uint8_t ret = 0; bool duplicate; if (handle_ack_packet(buf)) { return 0; } if (NETSTACK_FRAMER.parse(buf) < 0) { PRINTF("simpledc: parsing failed msg len %u\n", packetbuf_datalen(buf)); return 0; } duplicate = check_duplicate(buf); if (send_ack_packet(buf, &ret)) { return ret; } if (duplicate) { return 0; } return NETSTACK_MAC.input(buf); }
/* add a variable declaration or a function prototype * declaration to the symbol table */ symbol* declare_symbol(symbol_type_t symbol_type, char *name, YYLTYPE loc, visibility_level_t level, data_type_t data_type, int size) { symbol *s; MALLOC(s, symbol, 1); s->type = symbol_type; s->loc = loc; strcpy(s->name, name); if ( symbol_type == FUNCTION ) { s->u.func.arity = size; s->u.func.return_type = data_type; s->u.func.defined = FALSE; } else { /* var*/ s->u.var.size = size; s->u.var.data_type = data_type; } if ( check_duplicate(level, s) ) { #ifndef NDEBUG fprintf(stderr, " Adding symbol `%s' with data type \t%s\n", s->name, data_type_names[(s->type == FUNCTION) ? s->u.func.return_type : s->u.var.data_type]); #endif add_symbol(level, s); return s; } else { nberrs++; return NULL; } }
/* TODO: obey static to declare a function to the file level */ symbol *define_function(char *name, YYLTYPE loc, data_type_t return_type, symbol* param_list) { symbol *s; MALLOC(s, symbol, 1); s->type = FUNCTION; s->loc = loc; strcpy(s->name, name); //s->u.func.arity = size; s->u.func.return_type = return_type; s->u.func.defined = TRUE; s->u.func.plist = param_list; print_fn_signature(s); if ( check_duplicate(GLOBAL_LEVEL, s) ) { /* if a prototype exists, replace it by the definition */ symbol *sym; if ( (sym = find_symbol(GLOBAL_LEVEL, s->name)) ) { delete_symbol(GLOBAL_LEVEL, sym); } add_symbol(GLOBAL_LEVEL, s); // add all params as vars to the current function symtable for ( sym = param_list; sym; sym = sym->u.param.next ) if ( !declare_symbol(VARIABLE, sym->name, sym->loc, FUNCTION_LEVEL, sym->u.param.data_type, sym->u.param.size) ) return NULL; return s; } else { nberrs++; printf("errrrrr\n"); return NULL; } }
static mtev_hook_return_t handle_fq_message(void *closure, struct fq_conn_s *client, int idx, struct fq_msg *m, void *payload, size_t payload_len) { if(check_duplicate(payload, payload_len) == mtev_false) { handle_metric_buffer(payload, payload_len, 1); } return MTEV_HOOK_CONTINUE; }
int main(int argc, char *argv[]) { int duplicated = 1; int pivot; /* Generate an array of non-duplicated integer * Try until we get one */ while (duplicated) { create_array(int_array, SIZE); insertion_sort(int_array, SIZE); print_array(int_array, SIZE); duplicated = check_duplicate(int_array, SIZE); } pivot = PIVOT; }
static int close_error(void) { if (error_list.header_pos < error_list.len) { struct error_s *err = (struct error_s *)&error_list.data[error_list.header_pos]; err->error_len = error_list.len - error_list.header_pos - sizeof(struct error_s) - err->line_len; switch (err->severity) { case SV_NOTDEFGNOTE: case SV_NOTDEFLNOTE: case SV_DOUBLENOTE: return 0; default: break; } if (check_duplicate(err)) { error_list.len = error_list.header_pos; return 1; } } return 0; }
int check_duplicate(visibility_level_t vl, symbol *sym) { symbol *old_sym = NULL; HASH_FIND_STR( symbol_tables[vl], sym->name, old_sym ); if (old_sym != NULL) { /* on peut déclarer une même fonction plusieurs fois */ if ( sym->type == FUNCTION && old_sym->type == FUNCTION ) { symbol *plist1, *plist2; if ( sym->u.func.defined && old_sym->u.func.defined ) { fprintf(stderr, " Redefined function: `%s': line %d, line %d\n", sym->name, old_sym->loc.first_line, sym->loc.first_line); return FALSE; // exit here to avoid over-nesting } plist1 = old_sym->u.func.plist; plist2 = sym->u.func.plist; while ( plist1 && plist2 && plist1->type == plist2->type ) { plist1 = plist1->u.param.next; plist2 = plist2->u.param.next; } if ( plist1 || plist2 ) { fprintf(stderr, " Function prototype mismatch: `%s': line %d, line %d\n", sym->name, old_sym->loc.first_line, sym->loc.first_line); fprintf(stderr, " First:"); print_fn_signature(old_sym); fprintf(stderr, " Second:"); print_fn_signature(sym); } else { // duplicate prototype: harmless return DUPLICATED_PROTO; } } else { fprintf(stderr, " Duplicated identifier: `%s': line %d, line %d\n", sym->name, old_sym->loc.first_line, sym->loc.first_line); } return FALSE; // either valid or not, duplicate -> FALSE } if ( vl == FILE_LEVEL ) return check_duplicate(GLOBAL_LEVEL, sym); return 1; }
/** * \internal */ static void category_edit_add_request(CategoryEdit * category_edit, GtkWidget *combo) { gchar *name; GtkWidget *entry; entry = gtk_bin_get_child (GTK_BIN (category_edit->categories_combo)); gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); gtk_widget_grab_focus (entry); name = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo)); if (check_duplicate (GEBR_GUI_SEQUENCE_EDIT(category_edit), name) || __category_edit_check_text(name)) { g_free(name); return; } debr_has_category(name, TRUE); __category_edit_add(category_edit, GEBR_GEOXML_SEQUENCE(gebr_geoxml_flow_append_category(category_edit->menu, name))); validate_image_set_check_category_list(category_edit->validate_image, category_edit->menu); g_signal_emit_by_name(category_edit, "changed"); g_free(name); }
/* save a prototype */ void declare_function(char *name, YYLTYPE loc, data_type_t return_type, symbol* param_list) { symbol *s; MALLOC(s, symbol, 1); s->type = FUNCTION; s->loc = loc; strcpy(s->name, name); //s->u.func.arity = size; s->u.func.return_type = return_type; s->u.func.defined = FALSE; s->u.func.plist = param_list; /* do not add it if retval is FALSE or DUPLICATED_PROTO */ int retval = check_duplicate(GLOBAL_LEVEL, s); if ( retval == TRUE ) { add_symbol(GLOBAL_LEVEL, s); } else if (retval == FALSE) { nberrs++; } // else: retval = DUPLICATED_PROTO }
void MPU9250::measure() { if (hrt_absolute_time() < _reset_wait) { // we're waiting for a reset to complete return; } struct MPUReport mpu_report; struct Report { int16_t accel_x; int16_t accel_y; int16_t accel_z; int16_t temp; int16_t gyro_x; int16_t gyro_y; int16_t gyro_z; } report; /* start measuring */ perf_begin(_sample_perf); /* * Fetch the full set of measurements from the MPU9250 in one pass. */ if (OK != _interface->read(MPU9250_SET_SPEED(MPUREG_INT_STATUS, MPU9250_HIGH_BUS_SPEED), (uint8_t *)&mpu_report, sizeof(mpu_report))) { return; } check_registers(); if (check_duplicate(&mpu_report.accel_x[0])) { return; } #ifdef USE_I2C if (_mag->is_passthrough()) { #endif _mag->_measure(mpu_report.mag); #ifdef USE_I2C } else { _mag->measure(); } #endif /* * Convert from big to little endian */ report.accel_x = int16_t_from_bytes(mpu_report.accel_x); report.accel_y = int16_t_from_bytes(mpu_report.accel_y); report.accel_z = int16_t_from_bytes(mpu_report.accel_z); report.temp = int16_t_from_bytes(mpu_report.temp); report.gyro_x = int16_t_from_bytes(mpu_report.gyro_x); report.gyro_y = int16_t_from_bytes(mpu_report.gyro_y); report.gyro_z = int16_t_from_bytes(mpu_report.gyro_z); if (check_null_data((uint32_t *)&report, sizeof(report) / 4)) { return; } if (_register_wait != 0) { // we are waiting for some good transfers before using the sensor again // We still increment _good_transfers, but don't return any data yet _register_wait--; return; } /* * Swap axes and negate y */ int16_t accel_xt = report.accel_y; int16_t accel_yt = ((report.accel_x == -32768) ? 32767 : -report.accel_x); int16_t gyro_xt = report.gyro_y; int16_t gyro_yt = ((report.gyro_x == -32768) ? 32767 : -report.gyro_x); /* * Apply the swap */ report.accel_x = accel_xt; report.accel_y = accel_yt; report.gyro_x = gyro_xt; report.gyro_y = gyro_yt; /* * Report buffers. */ accel_report arb; gyro_report grb; /* * Adjust and scale results to m/s^2. */ grb.timestamp = arb.timestamp = hrt_absolute_time(); // report the error count as the sum of the number of bad // transfers and bad register reads. This allows the higher // level code to decide if it should use this sensor based on // whether it has had failures grb.error_count = arb.error_count = perf_event_count(_bad_transfers) + perf_event_count(_bad_registers); /* * 1) Scale raw value to SI units using scaling from datasheet. * 2) Subtract static offset (in SI units) * 3) Scale the statically calibrated values with a linear * dynamically obtained factor * * Note: the static sensor offset is the number the sensor outputs * at a nominally 'zero' input. Therefore the offset has to * be subtracted. * * Example: A gyro outputs a value of 74 at zero angular rate * the offset is 74 from the origin and subtracting * 74 from all measurements centers them around zero. */ /* NOTE: Axes have been swapped to match the board a few lines above. */ arb.x_raw = report.accel_x; arb.y_raw = report.accel_y; arb.z_raw = report.accel_z; float xraw_f = report.accel_x; float yraw_f = report.accel_y; float zraw_f = report.accel_z; // apply user specified rotation rotate_3f(_rotation, xraw_f, yraw_f, zraw_f); float x_in_new = ((xraw_f * _accel_range_scale) - _accel_scale.x_offset) * _accel_scale.x_scale; float y_in_new = ((yraw_f * _accel_range_scale) - _accel_scale.y_offset) * _accel_scale.y_scale; float z_in_new = ((zraw_f * _accel_range_scale) - _accel_scale.z_offset) * _accel_scale.z_scale; arb.x = _accel_filter_x.apply(x_in_new); arb.y = _accel_filter_y.apply(y_in_new); arb.z = _accel_filter_z.apply(z_in_new); math::Vector<3> aval(x_in_new, y_in_new, z_in_new); math::Vector<3> aval_integrated; bool accel_notify = _accel_int.put(arb.timestamp, aval, aval_integrated, arb.integral_dt); arb.x_integral = aval_integrated(0); arb.y_integral = aval_integrated(1); arb.z_integral = aval_integrated(2); arb.scaling = _accel_range_scale; arb.range_m_s2 = _accel_range_m_s2; _last_temperature = (report.temp) / 361.0f + 35.0f; arb.temperature_raw = report.temp; arb.temperature = _last_temperature; grb.x_raw = report.gyro_x; grb.y_raw = report.gyro_y; grb.z_raw = report.gyro_z; xraw_f = report.gyro_x; yraw_f = report.gyro_y; zraw_f = report.gyro_z; // apply user specified rotation rotate_3f(_rotation, xraw_f, yraw_f, zraw_f); float x_gyro_in_new = ((xraw_f * _gyro_range_scale) - _gyro_scale.x_offset) * _gyro_scale.x_scale; float y_gyro_in_new = ((yraw_f * _gyro_range_scale) - _gyro_scale.y_offset) * _gyro_scale.y_scale; float z_gyro_in_new = ((zraw_f * _gyro_range_scale) - _gyro_scale.z_offset) * _gyro_scale.z_scale; grb.x = _gyro_filter_x.apply(x_gyro_in_new); grb.y = _gyro_filter_y.apply(y_gyro_in_new); grb.z = _gyro_filter_z.apply(z_gyro_in_new); math::Vector<3> gval(x_gyro_in_new, y_gyro_in_new, z_gyro_in_new); math::Vector<3> gval_integrated; bool gyro_notify = _gyro_int.put(arb.timestamp, gval, gval_integrated, grb.integral_dt); grb.x_integral = gval_integrated(0); grb.y_integral = gval_integrated(1); grb.z_integral = gval_integrated(2); grb.scaling = _gyro_range_scale; grb.range_rad_s = _gyro_range_rad_s; grb.temperature_raw = report.temp; grb.temperature = _last_temperature; _accel_reports->force(&arb); _gyro_reports->force(&grb); /* notify anyone waiting for data */ if (accel_notify) { poll_notify(POLLIN); } if (gyro_notify) { _gyro->parent_poll_notify(); } if (accel_notify && !(_pub_blocked)) { /* log the time of this report */ perf_begin(_controller_latency_perf); /* publish it */ orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb); } if (gyro_notify && !(_pub_blocked)) { /* publish it */ orb_publish(ORB_ID(sensor_gyro), _gyro->_gyro_topic, &grb); } /* stop measuring */ perf_end(_sample_perf); }
int io_open(resmgr_context_t *ctp, io_open_t *msg, MQDEV *dev, void *extra) { struct mq_attr *mqp = extra; uint32_t *smp = extra; iofunc_attr_t *attr = &dev->attr; MQDEV **head; struct mq_attr mq_attr; int status; dev_t rdev; if(S_ISDIR(dev->attr.mode)) { // Open on a new/non-existent queue. if((msg->connect.ioflag & O_CREAT) == 0) { return ENOENT; } // It must have a file_type of _FTYPE_MQUEUE or _FTYPE_SEM memset(&mq_attr, 0, sizeof(mq_attr)); switch(msg->connect.file_type) { case _FTYPE_MQUEUE: rdev = S_INMQ; head = &mq_dir_attr.link; if(msg->connect.extra_type == _IO_CONNECT_EXTRA_MQUEUE) { if (msg->connect.extra_len != sizeof(struct mq_attr)) return(ENOSYS); if (ctp->info.flags & _NTO_MI_ENDIAN_DIFF) { ENDIAN_SWAP32(&mqp->mq_maxmsg); ENDIAN_SWAP32(&mqp->mq_msgsize); } if((mq_attr.mq_maxmsg = mqp->mq_maxmsg) <= 0 || (mq_attr.mq_msgsize = mqp->mq_msgsize) <= 0) { return EINVAL; } } else { mq_attr.mq_maxmsg = 1024; mq_attr.mq_msgsize = 4096; } break; case _FTYPE_SEM: rdev = S_INSEM; head = &sem_dir_attr.link; mq_attr.mq_maxmsg = _POSIX_SEM_VALUE_MAX; mq_attr.mq_flags = MQ_SEMAPHORE; if(msg->connect.extra_type == _IO_CONNECT_EXTRA_SEM) { if (msg->connect.extra_len != sizeof(uint32_t)) return(ENOSYS); if (ctp->info.flags & _NTO_MI_ENDIAN_DIFF) { ENDIAN_SWAP32(smp); } mq_attr.mq_curmsgs = *smp; } break; default: return ENOSYS; } // Check for O_CREAT race condition (PR-11060) if ((dev = check_duplicate(msg->connect.path, *head)) != NULL) { // Re-target open to the already created device. ctp->id = dev->id; goto race; // In case non-trivial open verification code } // Get a device entry and the input/output buffers for it. if((dev = MemchunkCalloc(memchunk, 1, sizeof(*dev) + msg->connect.path_len - sizeof(char))) == NULL) { return ENOSPC; } msg->connect.mode = (msg->connect.mode & ~S_IFMT) | S_IFNAM; if((status = iofunc_open(ctp, msg, &dev->attr, attr, 0)) != EOK) { MemchunkFree(memchunk, dev); return status; } dev->mq_attr = mq_attr; dev->attr.rdev = rdev; IOFUNC_NOTIFY_INIT(dev->notify); // Add the new queue to the pathname space if((dev->id = create_device(msg->connect.path, msg->connect.file_type, dev)) == -1) { if ((status = errno) == EMFILE) { //We have created too many connections, this is the system limit status = ENFILE; //Tell the client the system is full. } MemchunkFree(memchunk, dev); return status; } strcpy(dev->name, msg->connect.path); dev->link = *head, *head = dev; // Re-target open to the newly created device. ctp->id = dev->id; } else { race: // Open on an existing queue. if((status = iofunc_open(ctp, msg, &dev->attr, 0, 0)) != EOK) { return status; } } // Attach the ocb to the device if((status = iofunc_ocb_attach(ctp, msg, NULL, &dev->attr, NULL)) == -1) { return status; } return EOK; }
void MPU9250_mag::measure(struct ak8963_regs data) { bool mag_notify = true; if (check_duplicate((uint8_t *)&data.x) && !(data.st1 & 0x02)) { perf_count(_mag_duplicates); return; } /* monitor for if data overrun flag is ever set */ if (data.st1 & 0x02) { perf_count(_mag_overruns); } /* monitor for if magnetic sensor overflow flag is ever set noting that st2 * is usually not even refreshed, but will always be in the same place in the * mpu's buffers regardless, hence the actual count would be bogus */ if (data.st2 & 0x08) { perf_count(_mag_overflows); } mag_report mrb; mrb.timestamp = hrt_absolute_time(); /* * Align axes - note the accel & gryo are also re-aligned so this * doesn't look obvious with the datasheet */ mrb.x_raw = data.x; mrb.y_raw = -data.y; mrb.z_raw = -data.z; float xraw_f = data.x; float yraw_f = -data.y; float zraw_f = -data.z; /* apply user specified rotation */ rotate_3f(_parent->_rotation, xraw_f, yraw_f, zraw_f); mrb.x = ((xraw_f * _mag_range_scale * _mag_asa_x) - _mag_scale.x_offset) * _mag_scale.x_scale; mrb.y = ((yraw_f * _mag_range_scale * _mag_asa_y) - _mag_scale.y_offset) * _mag_scale.y_scale; mrb.z = ((zraw_f * _mag_range_scale * _mag_asa_z) - _mag_scale.z_offset) * _mag_scale.z_scale; mrb.range_ga = (float)48.0; mrb.scaling = _mag_range_scale; mrb.temperature = _parent->_last_temperature; mrb.error_count = perf_event_count(_mag_errors); _mag_reports->force(&mrb); /* notify anyone waiting for data */ if (mag_notify) { poll_notify(POLLIN); } if (mag_notify && !(_pub_blocked)) { /* publish it */ orb_publish(ORB_ID(sensor_mag), _mag_topic, &mrb); } }
main(int argc, char **argv){ char input_file[128]; strcpy(input_file,argv[1]); #else int mecab_analyze (char *input_file){ #endif char input[MAX_TEXT_SIZE]; char analyzed_text[MAX_TEXT_SIZE]; char wk_buff[MAX_TEXT_SIZE]; char wk_file_name[256]; char title_buff[256]; mecab_t *mecab; const mecab_node_t *node; FILE *wfp; char surface_buff[256]; char key_list[MAX_KEY_NUMBERS][MAX_KEY_LENGTH]; int key_numbers; strcpy(wk_file_name,TO_MECAB_FILE_DIR); strcat(wk_file_name,input_file); if(read_text(wk_file_name,input,title_buff)){ fprintf(stderr,"[%s] not found\n",wk_file_name); return(-1); } /**** remove(wk_file_name); ****/ // edit character e.g. ' '' { 0x0a edit_input_text(input); /** memset(analyzed_text,'\0',sizeof(analyzed_text)); if(!modify_text(analyzed_text,input)){ strcpy(wk_buff,analyzed_text); while(1){ memset(analyzed_text,'\0',sizeof(analyzed_text)); if(modify_text(analyzed_text,wk_buff)) break; strcpy(wk_buff,analyzed_text); } } **/ strcpy(wk_file_name,TO_HIBARI_FILE_DIR); strcat(wk_file_name,input_file); if((wfp = fopen(wk_file_name,"w")) == NULL){ fprintf(stderr,"[%s] could not open\n",wk_file_name); return(-1); } /* fprintf(wfp,"{\"%s\"}.\n",input); // first write message */ fprintf(wfp,"{\"%s\"}.\n",title_buff); // write wiki title mecab = mecab_new2(""); CHECK(mecab); mecab_set_lattice_level(mecab, 0); // mecab_set_lattice_level(mecab, 1); node = mecab_sparse_tonode(mecab, input); CHECK(node); memset(key_list,'\0',sizeof(key_list)); for (key_numbers=0; node; node = node->next) { strncpy(surface_buff,node->surface,node->length); surface_buff[node->length] ='\0'; #ifdef UNIT_TEST printf("名詞:[%s] 文字種:[%d] ID:[%d]\n",surface_buff,node->char_type,node->posid); #endif if (node->length <= 1) continue; if (omitted_word(surface_buff)) continue; // check charcter type switch(node->posid){ case 3: //記号 case 4: //数字 case 5: //記号 case 6: //記号 case 7: //記号 break; case 36: // ' case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 67: if(!check_duplicate((char *)key_list,surface_buff,key_numbers)){ fprintf(wfp,"{\"%s\"}.\n",surface_buff); key_numbers ++; } break; case 61: // 非自立 名詞 case 62: case 63: case 64: case 65: case 66: break; default: // printf("[%s] ID:[%d]\n",surface_buff,node->posid); break; } #ifdef NOT_USE printf(" %s %d %d %d %d posid:[%d] %d %d %d %f %f %f %ld\n", node->feature, (int)(node->surface - input), (int)(node->surface - input + node->length), node->rcAttr, node->lcAttr, node->posid, (int)node->char_type, (int)node->stat, (int)node->isbest, node->alpha, node->beta, node->prob, node->cost); #endif } fclose(wfp); mecab_destroy(mecab); return 0; }
void MPU9250::measure() { if (hrt_absolute_time() < _reset_wait) { // we're waiting for a reset to complete return; } struct MPUReport mpu_report; struct ICMReport icm_report; struct Report { int16_t accel_x; int16_t accel_y; int16_t accel_z; int16_t temp; int16_t gyro_x; int16_t gyro_y; int16_t gyro_z; } report; /* start measuring */ perf_begin(_sample_perf); /* * Fetch the full set of measurements from the MPU9250 in one pass */ if ((!_magnetometer_only || _mag->is_passthrough()) && _register_wait == 0) { if (_whoami == MPU_WHOAMI_9250 || _whoami == MPU_WHOAMI_6500) { if (OK != read_reg_range(MPUREG_INT_STATUS, MPU9250_HIGH_BUS_SPEED, (uint8_t *)&mpu_report, sizeof(mpu_report))) { perf_end(_sample_perf); return; } } else { // ICM20948 select_register_bank(REG_BANK(ICMREG_20948_ACCEL_XOUT_H)); if (OK != read_reg_range(ICMREG_20948_ACCEL_XOUT_H, MPU9250_HIGH_BUS_SPEED, (uint8_t *)&icm_report, sizeof(icm_report))) { perf_end(_sample_perf); return; } } check_registers(); if (check_duplicate(MPU_OR_ICM(&mpu_report.accel_x[0], &icm_report.accel_x[0]))) { return; } } /* * In case of a mag passthrough read, hand the magnetometer data over to _mag. Else, * try to read a magnetometer report. */ # ifdef USE_I2C if (_mag->is_passthrough()) { # endif _mag->_measure(mpu_report.mag); # ifdef USE_I2C } else { _mag->measure(); } # endif /* * Continue evaluating gyro and accelerometer results */ if (!_magnetometer_only && _register_wait == 0) { /* * Convert from big to little endian */ if (_whoami == ICM_WHOAMI_20948) { report.accel_x = int16_t_from_bytes(icm_report.accel_x); report.accel_y = int16_t_from_bytes(icm_report.accel_y); report.accel_z = int16_t_from_bytes(icm_report.accel_z); report.temp = int16_t_from_bytes(icm_report.temp); report.gyro_x = int16_t_from_bytes(icm_report.gyro_x); report.gyro_y = int16_t_from_bytes(icm_report.gyro_y); report.gyro_z = int16_t_from_bytes(icm_report.gyro_z); } else { // MPU9250/MPU6500 report.accel_x = int16_t_from_bytes(mpu_report.accel_x); report.accel_y = int16_t_from_bytes(mpu_report.accel_y); report.accel_z = int16_t_from_bytes(mpu_report.accel_z); report.temp = int16_t_from_bytes(mpu_report.temp); report.gyro_x = int16_t_from_bytes(mpu_report.gyro_x); report.gyro_y = int16_t_from_bytes(mpu_report.gyro_y); report.gyro_z = int16_t_from_bytes(mpu_report.gyro_z); } if (check_null_data((uint16_t *)&report, sizeof(report) / 2)) { return; } } if (_register_wait != 0) { /* * We are waiting for some good transfers before using the sensor again. * We still increment _good_transfers, but don't return any data yet. * */ _register_wait--; return; } /* * Get sensor temperature */ _last_temperature = (report.temp) / 333.87f + 21.0f; /* * Convert and publish accelerometer and gyrometer data. */ if (!_magnetometer_only) { /* * Keeping the axes as they are for ICM20948 so orientation will match the actual chip orientation */ if (_whoami != ICM_WHOAMI_20948) { /* * Swap axes and negate y */ int16_t accel_xt = report.accel_y; int16_t accel_yt = ((report.accel_x == -32768) ? 32767 : -report.accel_x); int16_t gyro_xt = report.gyro_y; int16_t gyro_yt = ((report.gyro_x == -32768) ? 32767 : -report.gyro_x); /* * Apply the swap */ report.accel_x = accel_xt; report.accel_y = accel_yt; report.gyro_x = gyro_xt; report.gyro_y = gyro_yt; } /* * Report buffers. */ sensor_accel_s arb; sensor_gyro_s grb; /* * Adjust and scale results to m/s^2. */ grb.timestamp = arb.timestamp = hrt_absolute_time(); // report the error count as the sum of the number of bad // transfers and bad register reads. This allows the higher // level code to decide if it should use this sensor based on // whether it has had failures grb.error_count = arb.error_count = perf_event_count(_bad_transfers) + perf_event_count(_bad_registers); /* * 1) Scale raw value to SI units using scaling from datasheet. * 2) Subtract static offset (in SI units) * 3) Scale the statically calibrated values with a linear * dynamically obtained factor * * Note: the static sensor offset is the number the sensor outputs * at a nominally 'zero' input. Therefore the offset has to * be subtracted. * * Example: A gyro outputs a value of 74 at zero angular rate * the offset is 74 from the origin and subtracting * 74 from all measurements centers them around zero. */ /* NOTE: Axes have been swapped to match the board a few lines above. */ arb.x_raw = report.accel_x; arb.y_raw = report.accel_y; arb.z_raw = report.accel_z; float xraw_f = report.accel_x; float yraw_f = report.accel_y; float zraw_f = report.accel_z; // apply user specified rotation rotate_3f(_rotation, xraw_f, yraw_f, zraw_f); float x_in_new = ((xraw_f * _accel_range_scale) - _accel_scale.x_offset) * _accel_scale.x_scale; float y_in_new = ((yraw_f * _accel_range_scale) - _accel_scale.y_offset) * _accel_scale.y_scale; float z_in_new = ((zraw_f * _accel_range_scale) - _accel_scale.z_offset) * _accel_scale.z_scale; arb.x = _accel_filter_x.apply(x_in_new); arb.y = _accel_filter_y.apply(y_in_new); arb.z = _accel_filter_z.apply(z_in_new); matrix::Vector3f aval(x_in_new, y_in_new, z_in_new); matrix::Vector3f aval_integrated; bool accel_notify = _accel_int.put(arb.timestamp, aval, aval_integrated, arb.integral_dt); arb.x_integral = aval_integrated(0); arb.y_integral = aval_integrated(1); arb.z_integral = aval_integrated(2); arb.scaling = _accel_range_scale; arb.temperature = _last_temperature; /* return device ID */ arb.device_id = _accel->_device_id.devid; grb.x_raw = report.gyro_x; grb.y_raw = report.gyro_y; grb.z_raw = report.gyro_z; xraw_f = report.gyro_x; yraw_f = report.gyro_y; zraw_f = report.gyro_z; // apply user specified rotation rotate_3f(_rotation, xraw_f, yraw_f, zraw_f); float x_gyro_in_new = ((xraw_f * _gyro_range_scale) - _gyro_scale.x_offset) * _gyro_scale.x_scale; float y_gyro_in_new = ((yraw_f * _gyro_range_scale) - _gyro_scale.y_offset) * _gyro_scale.y_scale; float z_gyro_in_new = ((zraw_f * _gyro_range_scale) - _gyro_scale.z_offset) * _gyro_scale.z_scale; grb.x = _gyro_filter_x.apply(x_gyro_in_new); grb.y = _gyro_filter_y.apply(y_gyro_in_new); grb.z = _gyro_filter_z.apply(z_gyro_in_new); matrix::Vector3f gval(x_gyro_in_new, y_gyro_in_new, z_gyro_in_new); matrix::Vector3f gval_integrated; bool gyro_notify = _gyro_int.put(arb.timestamp, gval, gval_integrated, grb.integral_dt); grb.x_integral = gval_integrated(0); grb.y_integral = gval_integrated(1); grb.z_integral = gval_integrated(2); grb.scaling = _gyro_range_scale; grb.temperature = _last_temperature; /* return device ID */ grb.device_id = _gyro->_device_id.devid; _accel_reports->force(&arb); _gyro_reports->force(&grb); /* notify anyone waiting for data */ if (accel_notify) { _accel->poll_notify(POLLIN); } if (gyro_notify) { _gyro->parent_poll_notify(); } if (accel_notify && !(_accel->_pub_blocked)) { /* publish it */ orb_publish(ORB_ID(sensor_accel), _accel_topic, &arb); } if (gyro_notify && !(_gyro->_pub_blocked)) { /* publish it */ orb_publish(ORB_ID(sensor_gyro), _gyro->_gyro_topic, &grb); } } /* stop measuring */ perf_end(_sample_perf); }