px4启动1

  1. 前言
    1.1 对于51单片机裸奔式的编程,只有一个main函数,main函数中只有一个while死循环,即最后烧入的固件只有一个可执行程序,这个可执行程序的入口函数即main函数。
    1.2 对stm32来说,可以采用51单片机传统的编程方式,采用一个main函数,但是也可以先运行一个RTOS,然后通过该操作系统来运行多个可执行程序。每一个可执行程序都有自己的main函数,一般取名为appname_main(char argc , char *argv[] ) ,即该可执行程序的入口函数。
  2. 编译工作的不同
    51单片机式的只会将多个.c和.h文件make成一个可执行程序,该可执行程序的入口函数为main()
    运行了操作系统的stm32会,例如,会将a.c a.h b.c b.h 编译成app1.exe,该可执行程序的入口函数appnme_main()在a.c或b.c中。同理可将其他文件make成app2.exe。然后再同个RTOS的启动脚本或手动执行想要运行的app。
    对于操作系统来说,可执行程序被看作是系统的命令(command),如系统自带的ls cp等实质上是可执行程序。
  3. 在nuttxx下运行某个可执行程序(app)的过程详析
    注意:在nuttx下执行某个app并不意味着在操作系统中启动了该进程。而且,操作系统执行了某个可执行程序,意味着该程序会被循环运行,只有进程才会被循环运行(因为进程的入口函数里面有while循环)。
    举个例子:
    可执行程序mc_att_control的入口函数在arducopter\modules\PX4Firmware\src\modules\mc_att_control\mc_att_control_main.cpp中,
    函数名为int mc_att_control_main(int argc, char *argv[]),一般位置会在.cpp文件的末尾,因为其他被它调用的函数或变量都要放在它前面作为声明。
    int mc_att_control_main(int argc, char argv[])
    {
    //若执行该程序时参数不对则报错
    if (argc < 2) { …}
    //若参数为 start , 则向任务管理器创建一个进程(task),并告诉任务管理器该进程的名字,句柄(pid),优//先级,运行频率,最大运行时间,进程的入口函数(task_main())等信息
    if (!strcmp(argv[1], “start”))
    {

    mc_att_control::g_control = new MulticopterAttitudeControl; //创建一个对象
    if (OK != mc_att_control::g_control->start()) //start()函数负责创建进程(task)
    {
    delete mc_att_control::g_control; //删除对象
    mc_att_control::g_control = nullptr;
    warnx(“start failed”);
    return 1;
    }
    return 0;
    }
    if (!strcmp(argv[1], “stop”))
    {

    }

    }
    下面看start()函数
    MulticopterAttitudeControl::start()
    {
    ASSERT(_control_task == -1);
    /
    start the task */
    _control_task = px4_task_spawn_cmd(“mc_att_control”,
    SCHED_DEFAULT,
    SCHED_PRIORITY_MAX - 5,
    1500,
    (px4_main_t)&MulticopterAttitudeControl::task_main_trampoline,
    nullptr);
    if (_control_task < 0)
    {
    warn(“task start failed”);
    return -errno;
    }
    return OK;
    }
    可知,该进程的名字为mc_att_control,句柄保存在任务创建函数px4_task_spawn_cmd的返回值_control_task中,任务(进程)的入口函数为task_main_trampoline。
    所以下面看task_main_trampoline函数:
    void
    MulticopterAttitudeControl::task_main_trampoline(int argc, char *argv[])
    {
    mc_att_control::g_control->task_main();
    }
    所以最后执行的是task_main(),该函数的定义如下:
    void
    MulticopterAttitudeControl::task_main()
    {

//do subscriptions

//initialize parameters cache

// wakeup source: vehicle attitude

//下面就是我们最终要找的while循环,终于让我给找到了,可谓是非了九牛二虎之力
//while循环中要执行的,也就是我们要重复执行的代码,算法。
while (!_task_should_exit) {

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

	/* timed out - periodic check for _task_should_exit */
	if (pret == 0) {
		continue;
	}

	/* this is undesirable but not much we can do - might want to flag unhappy status */
	if (pret < 0) {
		warn("mc att ctrl: poll error %d, %d", pret, errno);
		/* sleep a bit before next try */
		usleep(100000);
		continue;
	}

	perf_begin(_loop_perf);

	/* run controller on attitude changes */
	if (fds[0].revents & POLLIN) {
		static uint64_t last_run = 0;
		float dt = (hrt_absolute_time() - last_run) / 1000000.0f;
		last_run = hrt_absolute_time();

		/* guard against too small (< 2ms) and too large (> 20ms) dt's */
		if (dt < 0.002f) {
			dt = 0.002f;

		} else if (dt > 0.02f) {
			dt = 0.02f;
		}

		/* copy attitude and control state topics */
		orb_copy(ORB_ID(control_state), _ctrl_state_sub, &_ctrl_state);

		/* check for updates in other topics */
		parameter_update_poll();
		vehicle_control_mode_poll();
		arming_status_poll();
		vehicle_manual_poll();
		vehicle_status_poll();
		vehicle_motor_limits_poll();

		/* Check if we are in rattitude mode and the pilot is above the threshold on pitch
		 * or roll (yaw can rotate 360 in normal att control).  If both are true don't
		 * even bother running the attitude controllers */
		if (_vehicle_status.main_state == vehicle_status_s::MAIN_STATE_RATTITUDE) {
			if (fabsf(_manual_control_sp.y) > _params.rattitude_thres ||
			    fabsf(_manual_control_sp.x) > _params.rattitude_thres) {
				_v_control_mode.flag_control_attitude_enabled = false;
			}
		}

		if (_v_control_mode.flag_control_attitude_enabled) {

			if (_ts_opt_recovery == nullptr) {
				// the  tailsitter recovery instance has not been created, thus, the vehicle
				// is not a tailsitter, do normal attitude control
				control_attitude(dt);

			} else {
				vehicle_attitude_setpoint_poll();
				_thrust_sp = _v_att_sp.thrust;
				math::Quaternion q(_ctrl_state.q[0], _ctrl_state.q[1], _ctrl_state.q[2], _ctrl_state.q[3]);
				math::Quaternion q_sp(&_v_att_sp.q_d[0]);
				_ts_opt_recovery->setAttGains(_params.att_p, _params.yaw_ff);
				_ts_opt_recovery->calcOptimalRates(q, q_sp, _v_att_sp.yaw_sp_move_rate, _rates_sp);

				/* limit rates */
				for (int i = 0; i < 3; i++) {
					_rates_sp(i) = math::constrain(_rates_sp(i), -_params.mc_rate_max(i), _params.mc_rate_max(i));
				}
			}

			/* publish attitude rates setpoint */
			_v_rates_sp.roll = _rates_sp(0);
			_v_rates_sp.pitch = _rates_sp(1);
			_v_rates_sp.yaw = _rates_sp(2);
			_v_rates_sp.thrust = _thrust_sp;
			_v_rates_sp.timestamp = hrt_absolute_time();

			if (_v_rates_sp_pub != nullptr) {
				orb_publish(_rates_sp_id, _v_rates_sp_pub, &_v_rates_sp);

			} else if (_rates_sp_id) {
				_v_rates_sp_pub = orb_advertise(_rates_sp_id, &_v_rates_sp);
			}

			//}

		} else {
			/* attitude controller disabled, poll rates setpoint topic */
			if (_v_control_mode.flag_control_manual_enabled) {
				/* manual rates control - ACRO mode */
				_rates_sp = math::Vector<3>(_manual_control_sp.y, -_manual_control_sp.x,
							    _manual_control_sp.r).emult(_params.acro_rate_max);
				_thrust_sp = math::min(_manual_control_sp.z, MANUAL_THROTTLE_MAX_MULTICOPTER);

				/* publish attitude rates setpoint */
				_v_rates_sp.roll = _rates_sp(0);
				_v_rates_sp.pitch = _rates_sp(1);
				_v_rates_sp.yaw = _rates_sp(2);
				_v_rates_sp.thrust = _thrust_sp;
				_v_rates_sp.timestamp = hrt_absolute_time();

				if (_v_rates_sp_pub != nullptr) {
					orb_publish(_rates_sp_id, _v_rates_sp_pub, &_v_rates_sp);

				} else if (_rates_sp_id) {
					_v_rates_sp_pub = orb_advertise(_rates_sp_id, &_v_rates_sp);
				}

			} else {
				/* attitude controller disabled, poll rates setpoint topic */
				vehicle_rates_setpoint_poll();
				_rates_sp(0) = _v_rates_sp.roll;
				_rates_sp(1) = _v_rates_sp.pitch;
				_rates_sp(2) = _v_rates_sp.yaw;
				_thrust_sp = _v_rates_sp.thrust;
			}
		}

		if (_v_control_mode.flag_control_rates_enabled) {
			control_attitude_rates(dt);

			/* publish actuator controls */
			_actuators.control[0] = (PX4_ISFINITE(_att_control(0))) ? _att_control(0) : 0.0f;
			_actuators.control[1] = (PX4_ISFINITE(_att_control(1))) ? _att_control(1) : 0.0f;
			_actuators.control[2] = (PX4_ISFINITE(_att_control(2))) ? _att_control(2) : 0.0f;
			_actuators.control[3] = (PX4_ISFINITE(_thrust_sp)) ? _thrust_sp : 0.0f;
			_actuators.timestamp = hrt_absolute_time();
			_actuators.timestamp_sample = _ctrl_state.timestamp;

			_controller_status.roll_rate_integ = _rates_int(0);
			_controller_status.pitch_rate_integ = _rates_int(1);
			_controller_status.yaw_rate_integ = _rates_int(2);
			_controller_status.timestamp = hrt_absolute_time();

			if (!_actuators_0_circuit_breaker_enabled) {
				if (_actuators_0_pub != nullptr) {

					orb_publish(_actuators_id, _actuators_0_pub, &_actuators);
					perf_end(_controller_latency_perf);

				} else if (_actuators_id) {
					_actuators_0_pub = orb_advertise(_actuators_id, &_actuators);
				}

			}

			/* publish controller status */
			if (_controller_status_pub != nullptr) {
				orb_publish(ORB_ID(mc_att_ctrl_status), _controller_status_pub, &_controller_status);

			} else {
				_controller_status_pub = orb_advertise(ORB_ID(mc_att_ctrl_status), &_controller_status);
			}
		}
	}

	perf_end(_loop_perf);
}

_control_task = -1;
return;

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值