px4最新版navigation代码分析

2023-05-16

    navigation部分位于代码Firmware/navigator文件夹中。其中不仅仅包含navigator的代码,最主要的9种不同的飞行模式的代码,它们针对不同的飞行模式计算出不同的期望的位置,即pos_sp_triplet中的数据。navigator模块承担的更是一个调度的功能,它解析commandor模块不同的命令,然后根据现有的条件进行判断,是否能切换到制定的飞行模式,如果不行则切换到当前条件下最安全的飞行模式。

    什么都不说了,直接上代码吧

Navigator::run()
{
	bool have_geofence_position_data = false;

	/* Try to load the geofence:
	 * if /fs/microsd/etc/geofence.txt load from this file */
	struct stat buffer;

	if (stat(GEOFENCE_FILENAME, &buffer) == 0) {
		PX4_INFO("Loading geofence from %s", GEOFENCE_FILENAME);
		_geofence.loadFromFile(GEOFENCE_FILENAME);
	}

	params_update();

	/* wakeup source(s) */
	px4_pollfd_struct_t fds[2] {};

	/* Setup of loop */
	//订阅最重要的两个topic即local_pos本地位置信息和vehicle_status飞机当前的状态
	fds[0].fd = _local_pos_sub;
	fds[0].events = POLLIN;
	fds[1].fd = _vehicle_status_sub;
	fds[1].events = POLLIN;

	/* rate-limit position subscription to 20 Hz / 50 ms */
	orb_set_interval(_local_pos_sub, 50);

	hrt_abstime last_geofence_check = 0;

	while (!should_exit()) {

		/* wait for up to 1000ms for data */
		int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 1000);

		if (pret == 0) {
			/* Let the loop run anyway, don't do `continue` here. */

		} else if (pret < 0) {
			/* this is undesirable but not much we can do - might want to flag unhappy status */
			PX4_ERR("poll error %d, %d", pret, errno);
			px4_usleep(10000);
			continue;

		} else {
			if (fds[0].revents & POLLIN) {
				/* success, local pos is available */
				orb_copy(ORB_ID(vehicle_local_position), _local_pos_sub, &_local_pos);
			}
		}

		perf_begin(_loop_perf);
		//拷贝无人机当前状态
		orb_copy(ORB_ID(vehicle_status), _vehicle_status_sub, &_vstatus);
		//gps数据更新
		/* gps updated */
		if (_gps_pos_sub.updated()) {
			_gps_pos_sub.copy(&_gps_pos);

			if (_geofence.getSource() == Geofence::GF_SOURCE_GPS) {
				have_geofence_position_data = true;
			}
		}
		//全局位置更新
		/* global position updated */
		if (_global_pos_sub.updated()) {
			_global_pos_sub.copy(&_global_pos);

			if (_geofence.getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
				have_geofence_position_data = true;
			}
		}
		//参数更新
		// check for parameter updates
		if (_parameter_update_sub.updated()) {
			// clear update
			parameter_update_s pupdate;
			_parameter_update_sub.copy(&pupdate);

			// update parameters from storage
			params_update();
		}

		_land_detected_sub.update(&_land_detected);
		_position_controller_status_sub.update();
		_home_pos_sub.update(&_home_pos);
		//处理和导航相关的命令
		if (_vehicle_command_sub.updated()) {
			const unsigned last_generation = _vehicle_command_sub.get_last_generation();
			vehicle_command_s cmd{};
			_vehicle_command_sub.copy(&cmd);

			if (_vehicle_command_sub.get_last_generation() != last_generation + 1) {
				PX4_ERR("vehicle_command lost, generation %d -> %d", last_generation, _vehicle_command_sub.get_last_generation());
			}
			//处理DO_GO_AROUND命令
			if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_GO_AROUND) {

				// DO_GO_AROUND is currently handled by the position controller (unacknowledged)
				// TODO: move DO_GO_AROUND handling to navigator
				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_REPOSITION) {//处理重新定位的指令

				bool reposition_valid = true;

				if (have_geofence_position_data &&
				    ((_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_NONE) &&
				     (_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_WARN))) {

					if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {

						vehicle_global_position_s test_reposition_validity {};
						test_reposition_validity.lat = cmd.param5;
						test_reposition_validity.lon = cmd.param6;

						if (PX4_ISFINITE(cmd.param7)) {
							test_reposition_validity.alt = cmd.param7;

						} else {
							test_reposition_validity.alt = get_global_position()->alt;
						}

						reposition_valid = _geofence.check(test_reposition_validity, _gps_pos, _home_pos,
										   home_position_valid());
					}
				}

				if (reposition_valid) {
					position_setpoint_triplet_s *rep = get_reposition_triplet();
					position_setpoint_triplet_s *curr = get_position_setpoint_triplet();

					// store current position as previous position and goal as next
					rep->previous.yaw = get_local_position()->heading;
					rep->previous.lat = get_global_position()->lat;
					rep->previous.lon = get_global_position()->lon;
					rep->previous.alt = get_global_position()->alt;

					rep->current.loiter_radius = get_loiter_radius();
					rep->current.loiter_direction = 1;
					rep->current.type = position_setpoint_s::SETPOINT_TYPE_LOITER;

					// If no argument for ground speed, use default value.
					if (cmd.param1 <= 0 || !PX4_ISFINITE(cmd.param1)) {
						rep->current.cruising_speed = get_cruising_speed();

					} else {
						rep->current.cruising_speed = cmd.param1;
					}

					rep->current.cruising_throttle = get_cruising_throttle();
					rep->current.acceptance_radius = get_acceptance_radius();

					// Go on and check which changes had been requested
					if (PX4_ISFINITE(cmd.param4)) {
						rep->current.yaw = cmd.param4;
						rep->current.yaw_valid = true;

					} else {
						rep->current.yaw = NAN;
						rep->current.yaw_valid = false;
					}

					if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {

						// Position change with optional altitude change
						rep->current.lat = cmd.param5;
						rep->current.lon = cmd.param6;

						if (PX4_ISFINITE(cmd.param7)) {
							rep->current.alt = cmd.param7;

						} else {
							rep->current.alt = get_global_position()->alt;
						}

					} else if (PX4_ISFINITE(cmd.param7)) {

						// Altitude without position change
						// This condition is necessary for altitude changes just after takeoff where lat and lon are still nan
						if (curr->current.valid && PX4_ISFINITE(curr->current.lat) && PX4_ISFINITE(curr->current.lon)) {
							rep->current.lat = curr->current.lat;
							rep->current.lon = curr->current.lon;

						} else {
							rep->current.lat = get_global_position()->lat;
							rep->current.lon = get_global_position()->lon;
						}

						rep->current.alt = cmd.param7;

					} else {
						// All three set to NaN - hold in current position
						rep->current.lat = get_global_position()->lat;
						rep->current.lon = get_global_position()->lon;
						rep->current.alt = get_global_position()->alt;
					}

					rep->previous.valid = true;
					rep->previous.timestamp = hrt_absolute_time();

					rep->current.valid = true;
					rep->current.timestamp = hrt_absolute_time();

					rep->next.valid = false;

				} else {
					mavlink_log_critical(&_mavlink_log_pub, "Reposition is outside geofence");
				}

				// CMD_DO_REPOSITION is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_TAKEOFF) {//处理起飞的指令
				position_setpoint_triplet_s *rep = get_takeoff_triplet();

				// store current position as previous position and goal as next
				//将当前的位置保存为takoff_triplet的前一个点的信息
				rep->previous.yaw = get_local_position()->heading;
				rep->previous.lat = get_global_position()->lat;
				rep->previous.lon = get_global_position()->lon;
				rep->previous.alt = get_global_position()->alt;

				rep->current.loiter_radius = get_loiter_radius();
				rep->current.loiter_direction = 1;
				rep->current.type = position_setpoint_s::SETPOINT_TYPE_TAKEOFF;
				//如果home的位置点有效,则根据命令中传的参数4(param4)设置yaw方向,否则将当前的yaw方向作为期望的yaw
				if (home_position_valid()) {
					rep->current.yaw = cmd.param4;

					rep->previous.valid = true;
					rep->previous.timestamp = hrt_absolute_time();

				} else {
					rep->current.yaw = get_local_position()->heading;
					rep->previous.valid = false;
				}
				//通过参数传递的目的经纬度有效的话,则作为起飞的目标,否则用当前位置的经纬度作为起飞的目标经纬度
				if (PX4_ISFINITE(cmd.param5) && PX4_ISFINITE(cmd.param6)) {
					rep->current.lat = cmd.param5;
					rep->current.lon = cmd.param6;

				} else {
					// If one of them is non-finite set the current global position as target
					rep->current.lat = get_global_position()->lat;
					rep->current.lon = get_global_position()->lon;
				}
				//期望的起飞的高度通过参数传递,但是后面的代码分析高度还是由很多其它的因素决定
				rep->current.alt = cmd.param7;

				rep->current.valid = true;
				rep->current.timestamp = hrt_absolute_time();

				rep->next.valid = false;

				// CMD_NAV_TAKEOFF is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_LAND_START) {//处理开始降落的指令

				/* find NAV_CMD_DO_LAND_START in the mission and
				 * use MAV_CMD_MISSION_START to start the mission there
				 */
				if (_mission.land_start()) {
					vehicle_command_s vcmd = {};
					vcmd.command = vehicle_command_s::VEHICLE_CMD_MISSION_START;
					vcmd.param1 = _mission.get_land_start_index();
					publish_vehicle_cmd(&vcmd);

				} else {
					PX4_WARN("planned mission landing not available");
				}

				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_MISSION_START) {//处理启动任务的指令
				if (_mission_result.valid && PX4_ISFINITE(cmd.param1) && (cmd.param1 >= 0)) {
					if (!_mission.set_current_mission_index(cmd.param1)) {
						PX4_WARN("CMD_MISSION_START failed");
					}
				}

				// CMD_MISSION_START is acknowledged by commander

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_CHANGE_SPEED) {//处理改变速度的指令
				if (cmd.param2 > FLT_EPSILON) {
					// XXX not differentiating ground and airspeed yet
					set_cruising_speed(cmd.param2);

				} else {
					set_cruising_speed();

					/* if no speed target was given try to set throttle */
					if (cmd.param3 > FLT_EPSILON) {
						set_cruising_throttle(cmd.param3 / 100);

					} else {
						set_cruising_throttle();
					}
				}

				// TODO: handle responses for supported DO_CHANGE_SPEED options?
				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);

			} else if (cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_NAV_ROI
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET
				   || cmd.command == vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE) {
				_vroi = {};

				switch (cmd.command) {
				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI:
				case vehicle_command_s::VEHICLE_CMD_NAV_ROI:
					_vroi.mode = cmd.param1;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_LOCATION:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_LOCATION;
					_vroi.lat = cmd.param5;
					_vroi.lon = cmd.param6;
					_vroi.alt = cmd.param7;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_WPNEXT_OFFSET:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_WPNEXT;
					_vroi.pitch_offset = (float)cmd.param5 * M_DEG_TO_RAD_F;
					_vroi.roll_offset = (float)cmd.param6 * M_DEG_TO_RAD_F;
					_vroi.yaw_offset = (float)cmd.param7 * M_DEG_TO_RAD_F;
					break;

				case vehicle_command_s::VEHICLE_CMD_DO_SET_ROI_NONE:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
					break;

				default:
					_vroi.mode = vehicle_command_s::VEHICLE_ROI_NONE;
					break;
				}

				_vroi.timestamp = hrt_absolute_time();

				_vehicle_roi_pub.publish(_vroi);

				publish_vehicle_command_ack(cmd, vehicle_command_s::VEHICLE_CMD_RESULT_ACCEPTED);
			}
		}

		/* Check for traffic */
		check_traffic();

		/* Check geofence violation */
		if (have_geofence_position_data &&
		    (_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_NONE) &&
		    (hrt_elapsed_time(&last_geofence_check) > GEOFENCE_CHECK_INTERVAL)) {

			bool inside = _geofence.check(_global_pos, _gps_pos, _home_pos,
						      home_position_valid());
			last_geofence_check = hrt_absolute_time();
			have_geofence_position_data = false;

			_geofence_result.timestamp = hrt_absolute_time();
			_geofence_result.geofence_action = _geofence.getGeofenceAction();
			_geofence_result.home_required = _geofence.isHomeRequired();

			if (!inside) {
				/* inform other apps via the mission result */
				_geofence_result.geofence_violated = true;

				/* Issue a warning about the geofence violation once */
				if (!_geofence_violation_warning_sent) {
					mavlink_log_critical(&_mavlink_log_pub, "Geofence violation");

					/* If we are already in loiter it is very likely that we are doing a reposition
					 * so we should block that by repositioning in the current location */
					if (_geofence.getGeofenceAction() != geofence_result_s::GF_ACTION_WARN
					    && get_vstatus()->nav_state == vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER) {
						position_setpoint_triplet_s *rep = get_reposition_triplet();

						rep->current.yaw = get_local_position()->heading;
						rep->current.lat = get_global_position()->lat;
						rep->current.lon = get_global_position()->lon;
						rep->current.alt = get_global_position()->alt;
						rep->current.valid = true;

						_pos_sp_triplet_updated = true;
					}

					_geofence_violation_warning_sent = true;
				}

			} else {
				/* inform other apps via the mission result */
				_geofence_result.geofence_violated = false;

				/* Reset the _geofence_violation_warning_sent field */
				_geofence_violation_warning_sent = false;
			}

			_geofence_result_pub.publish(_geofence_result);
		}

		/* Do stuff according to navigation state set by commander */
		NavigatorMode *navigation_mode_new{nullptr};
		//根据飞机当前的导航状态,切换到不同的任务模式
		switch (_vstatus.nav_state) {
		case vehicle_status_s::NAVIGATION_STATE_AUTO_MISSION:
			_pos_sp_triplet_published_invalid_once = false;

			_mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_NORMAL);
			navigation_mode_new = &_mission;

			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LOITER:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_loiter;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_RTL: {
				_pos_sp_triplet_published_invalid_once = false;

				const bool rtl_activated = _previous_nav_state != vehicle_status_s::NAVIGATION_STATE_AUTO_RTL;

				switch (rtl_type()) {
				case RTL::RTL_LAND: // use mission landing
				case RTL::RTL_CLOSEST:
					if (rtl_activated) {
						if (rtl_type() == RTL::RTL_LAND) {
							mavlink_log_info(get_mavlink_log_pub(), "RTL LAND activated");

						} else {
							mavlink_log_info(get_mavlink_log_pub(), "RTL Closest landing point activated");
						}

					}

					// if RTL is set to use a mission landing and mission has a planned landing, then use MISSION to fly there directly
					if (on_mission_landing() && !get_land_detected()->landed) {
						_mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD);
						navigation_mode_new = &_mission;

					} else {
						navigation_mode_new = &_rtl;
					}

					break;

				case RTL::RTL_MISSION:
					if (_mission.get_land_start_available() && !get_land_detected()->landed) {
						// the mission contains a landing spot
						_mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_FAST_FORWARD);

						if (_navigation_mode != &_mission) {
							if (_navigation_mode == nullptr) {
								// switching from an manual mode, go to landing if not already landing
								if (!on_mission_landing()) {
									start_mission_landing();
								}

							} else {
								// switching from an auto mode, continue the mission from the closest item
								_mission.set_closest_item_as_current();
							}
						}

						if (rtl_activated) {
							mavlink_log_info(get_mavlink_log_pub(), "RTL Mission activated, continue mission");
						}

						navigation_mode_new = &_mission;

					} else {
						// fly the mission in reverse if switching from a non-manual mode
						_mission.set_execution_mode(mission_result_s::MISSION_EXECUTION_MODE_REVERSE);

						if ((_navigation_mode != nullptr && (_navigation_mode != &_rtl || _mission.get_mission_changed())) &&
						    (! _mission.get_mission_finished()) &&
						    (!get_land_detected()->landed)) {
							// determine the closest mission item if switching from a non-mission mode, and we are either not already
							// mission mode or the mission waypoints changed.
							// The seconds condition is required so that when no mission was uploaded and one is available the closest
							// mission item is determined and also that if the user changes the active mission index while rtl is active
							// always that waypoint is tracked first.
							if ((_navigation_mode != &_mission) && (rtl_activated || _mission.get_mission_waypoints_changed())) {
								_mission.set_closest_item_as_current();
							}

							if (rtl_activated) {
								mavlink_log_info(get_mavlink_log_pub(), "RTL Mission activated, fly mission in reverse");
							}

							navigation_mode_new = &_mission;

						} else {
							if (rtl_activated) {
								mavlink_log_info(get_mavlink_log_pub(), "RTL Mission activated, fly to home");
							}

							navigation_mode_new = &_rtl;
						}
					}

					break;

				default:
					if (rtl_activated) {
						mavlink_log_info(get_mavlink_log_pub(), "RTL HOME activated");
					}

					navigation_mode_new = &_rtl;
					break;

				}

				break;
			}

		case vehicle_status_s::NAVIGATION_STATE_AUTO_TAKEOFF:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_takeoff;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LAND:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_land;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_PRECLAND:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_precland;
			_precland.set_mode(PrecLandMode::Required);
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDENGFAIL:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_engineFailure;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_LANDGPSFAIL:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_gpsFailure;
			break;

		case vehicle_status_s::NAVIGATION_STATE_AUTO_FOLLOW_TARGET:
			_pos_sp_triplet_published_invalid_once = false;
			navigation_mode_new = &_follow_target;
			break;

		case vehicle_status_s::NAVIGATION_STATE_MANUAL:
		case vehicle_status_s::NAVIGATION_STATE_ACRO:
		case vehicle_status_s::NAVIGATION_STATE_ALTCTL:
		case vehicle_status_s::NAVIGATION_STATE_POSCTL:
		case vehicle_status_s::NAVIGATION_STATE_DESCEND:
		case vehicle_status_s::NAVIGATION_STATE_TERMINATION:
		case vehicle_status_s::NAVIGATION_STATE_OFFBOARD:
		case vehicle_status_s::NAVIGATION_STATE_STAB:
		default:
			navigation_mode_new = nullptr;
			_can_loiter_at_sp = false;
			break;
		}

		// Do not execute any state machine while we are disarmed
		if (_vstatus.arming_state != vehicle_status_s::ARMING_STATE_ARMED) {
			navigation_mode_new = nullptr;
		}

		// update the vehicle status
		_previous_nav_state = _vstatus.nav_state;

		/* we have a new navigation mode: reset triplet */
		if (_navigation_mode != navigation_mode_new) {
			// We don't reset the triplet if we just did an auto-takeoff and are now
			// going to loiter. Otherwise, we lose the takeoff altitude and end up lower
			// than where we wanted to go.
			//
			// FIXME: a better solution would be to add reset where they are needed and remove
			//        this general reset here.
			if (!(_navigation_mode == &_takeoff &&
			      navigation_mode_new == &_loiter)) {
				reset_triplets();
			}
		}

		_navigation_mode = navigation_mode_new;

		/* iterate through navigation modes and set active/inactive for each */
		for (unsigned int i = 0; i < NAVIGATOR_MODE_ARRAY_SIZE; i++) {
			if (_navigation_mode_array[i]) {
				_navigation_mode_array[i]->run(_navigation_mode == _navigation_mode_array[i]);
			}
		}

		/* if nothing is running, set position setpoint triplet invalid once */
		if (_navigation_mode == nullptr && !_pos_sp_triplet_published_invalid_once) {
			_pos_sp_triplet_published_invalid_once = true;
			reset_triplets();
		}

		if (_pos_sp_triplet_updated) {
			publish_position_setpoint_triplet();
		}

		if (_mission_result_updated) {
			publish_mission_result();
		}

		perf_end(_loop_perf);
	}
}

由于代码内容很多,只是提供一个分析的样例,只能根据自己的实际需要,针对某个部分进行的详细的分析,从而二次开发出自己的功能

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

px4最新版navigation代码分析 的相关文章

随机推荐

  • 汇编 —— 算术和逻辑操作

    文章目录 加载有效地址leaq 练习题练习题答案 一元操作符 amp 二元操作符一元 amp 二元 练习题练习题答案 移位操作移位练习题练习题答案 特殊的算数操作符练习题练习题答案 参考文献 写在前面 xff1a 从腾讯实习回来之后 xff
  • clang-format安装配置与vscode支持

    文章目录 calng format安装centos下clang format安装ubuntu下clang format的安装vscode支持clang format clang format使用参考文献 calng format安装 cen
  • 分布式共识算法 —— Raft详解

    文章目录 分布式共识算法顺序一致性线性一致性因果一致性 Raft 算法原理概览选举机制新节点加入leader 掉线处理多个 follower 同时掉线 日志复制 参考文献 分布式共识算法 首先我们先明确这个问题 xff1a 为什么需要分布式
  • container_of 根据成员变量获得包含其的对象的地址!

    写在前面 本系列文章的灵感出处均是各个技术书籍的读后感 xff0c 详细书籍信息见文章最后的参考文献 CONTAINER OF 在书中发现一个很有意思的宏 xff0c 以此可以衍生出来其很多的用法 xff0c 这个宏可以根据某个成员变量的地
  • Linux 内核观测技术BPF

    BPF简介 BPF xff0c 全称是Berkeley Packet Filter xff08 伯克利数据包过滤器 xff09 的缩写 其诞生于1992年 xff0c 最初的目的是提升网络包过滤工具的性能 后面 xff0c 随着这个工具重新
  • bpftrace 指南

    文章目录 0 bpftrace0 1 bpftrace组件0 2 bpftrace 帮助信息0 3 bpftrace 工具速览表0 4 bpftrace 探针0 4 1 tracepoint0 4 2 usdt0 4 3 kprobe和kr
  • make px4_sitl_default gazebo编译报错解决办法

    PX4无人机ROS下仿真 xff0c 下载Fireware后执行make px4 sitl default gazebo编译 xff0c 编译过程中出现如下错误 xff1a 错误原因是两个package没有安装 xff1a gstreame
  • 理解实时操作系统与裸机的区别

    早期嵌入式开发没有嵌入式操作系统的概念 xff0c 直接操作裸机 xff0c 在裸机上写程序 xff0c 比如用51单片机基本就没有操作系统的概念 通常把程序分为两部分 xff1a 前台系统和后台系统 简单的小系统通常是前后台系统 xff0
  • 4.1.2.HTTP报文格式解析

    不同的请求方式 xff0c 他们的请求格式可能是不一样的 xff0c 请求格式就是我们所说的的报文格式 但是 xff0c 通常来说一个HTTP请求报文由请求行 xff08 request line xff09 请求头 xff08 heade
  • apt-get autoremove 命令你敢不敢用?

    apt get autoremove 命令你敢不敢用 xff1f 用apt时看到有提示 xff0c 说有些软件包已经不再被需要 xff0c 可以使用 autoremove 命令删除 xff0c 我是一个希望保持系统简洁性的人 xff0c 当
  • 英伟达(NVIDIA)系列显卡(GPU)技术指标对比排行

    性能概览 关于N卡架构发展史详见本人前篇博客 点击打开链接 Pascal xff08 帕斯卡 xff09 架构 显卡名称cuda核心数量主频 xff08 MHz xff09 超频 xff08 MHz xff09 存储速度显存配置位宽带宽 G
  • Cmake gcc make makefile 区别以及联系

    作者 xff1a 辉常哥 链接 xff1a https www zhihu com question 27455963 answer 89770919 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业
  • 使用Docker构建一个Git镜像,用来clone仓库

    概述 使用docker已经有一年多了 xff0c 最近意识到 xff0c 我在快速编排服务的时候 xff0c shell脚本里用到的git还是原生的 于是打算也将git容器化 xff0c 在dockerhub上搜罗了一筐 xff0c 找到这
  • make -C M选项

    modules MAKE C KERNELDIR M 61 PWD modules 这句是Makefile的规则 xff1a 这里的 MAKE 就相当于make xff0c C 选项的作用是指将当前工作目录转移到你所指定的位置 M 61 选
  • 什么是耦合、解耦

    一 耦合 1 耦合是指两个或两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象 2 在软件工程中 xff0c 对象之间的耦合度就是对象之间的依赖性 对象之间的耦合越高 xff0c 维护成本越高 xff0c 因此对象的设计
  • ERROR! Session/line number was not unique in database. History logging moved to new session 178

    原来的代码 xff1a MODEL NAME 61 39 ssd mobilenet v1 coco 2017 11 17 39 载入训练好的pb模型 detection graph 61 tf Graph with detection g
  • 基于px4的hc-sr04-pwm超声波模块的驱动开发

    一直想实现无人的避障功能 xff0c 但是px4源生代码又不支持避障 xff0c 所以只能自己动手写 避障的基础条件还是获取距离数据 xff0c 超声波模块就是最熟悉也是最简单的模块了 px4源生代码也支持了几种超声波模块 xff0c 但是
  • px4最新版commander代码分析

    commander位于Firmware src modules commander文件夹中 该部分主要负责对地面站 遥控器以及其它部分发布的cmd命令 xff0c 包括vehicle command VEHICLE CMD DO SET M
  • SMPL模型进阶

    SMPL模型是一种参数化人体模型 xff0c 是马普所提出的一种人体建模方法 xff0c 该方法可以进行任意的人体建模和动画驱动 这种方法与传统的LBS的最大的不同在于其提出的人体姿态影像体表形貌的方法 xff0c 这种方法可以模拟人的肌肉
  • px4最新版navigation代码分析

    navigation部分位于代码Firmware navigator文件夹中 其中不仅仅包含navigator的代码 xff0c 最主要的9种不同的飞行模式的代码 xff0c 它们针对不同的飞行模式计算出不同的期望的位置 xff0c 即po