Esempio n. 1
0
void write_data_s(void)
{
	//  global_data_lock(&global_data_rc_channels->access_conf);
	//  uint8_t i;
	//  for(i=0; i < NR_CHANNELS; i++){
	//    //Write the data to global_data_rc_channels (if not 0)
	//    if(mid_values_servo[i]!=0 && min_values_servo[i]!=0 && max_values_servo[i]!=0){
	//      global_data_rc_channels->chan[i].scaling_factor =
	//        10000/((max_values_servo[i] - min_values_servo[i])/2);
	//
	//      global_data_rc_channels->chan[i].mid = mid_values_servo[i];
	//    }
	//
	//    printf("Channel %i\t Function %s \t\t Min %i\t\t Max %i\t\t Scaling Factor: %i\t Middle Value %i\n",
	//        i,
	//        global_data_rc_channels->function_name[global_data_rc_channels->function[i]],
	//        min_values_servo[i], max_values_servo[i],
	//        global_data_rc_channels->chan[i].scaling_factor,
	//        global_data_rc_channels->chan[i].mid);
	//  }
	//  global_data_unlock(&global_data_rc_channels->access_conf);

	//Write to the Parameter storage



	global_data_lock(&global_data_parameter_storage->access_conf);

	global_data_parameter_storage->pm.param_values[PARAM_SERVO1_MIN] = min_values_servo[0];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO2_MIN] = min_values_servo[1];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO3_MIN] = min_values_servo[2];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO4_MIN] = min_values_servo[3];

	global_data_parameter_storage->pm.param_values[PARAM_SERVO1_MAX] = max_values_servo[0];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO2_MAX] = max_values_servo[1];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO3_MAX] = max_values_servo[2];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO4_MAX] = max_values_servo[3];

	global_data_parameter_storage->pm.param_values[PARAM_SERVO1_TRIM] = mid_values_servo[0];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO2_TRIM] = mid_values_servo[1];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO3_TRIM] = mid_values_servo[2];
	global_data_parameter_storage->pm.param_values[PARAM_SERVO4_TRIM] = mid_values_servo[3];

	global_data_unlock(&global_data_parameter_storage->access_conf);

	usleep(3e6);
	uint8_t i;

	for (i = 0; i < NR_CHANNELS; i++) {
		printf("Channel %i:\t\t Min %i\t\t Max %i\t\t Scaling Factor: %i\t Middle Value %i\n",
		       i,
		       min_values_servo[i], max_values_servo[i],
		       global_data_rc_channels->chan[i].scaling_factor,
		       global_data_rc_channels->chan[i].mid);
	}

}
Esempio n. 2
0
void control_multirotor_position(const struct vehicle_state_s *vstatus, const struct vehicle_manual_control_s *manual,
 const struct vehicle_attitude_s *att, const struct vehicle_local_position_s *local_pos,
 const struct vehicle_local_position_setpoint_s *local_pos_sp, struct vehicle_attitude_setpoint_s *att_sp)
{
	static PID_t distance_controller;

	static int read_ret;
	static global_data_position_t position_estimated;

	static uint16_t counter;

	static bool initialized;
	static uint16_t pm_counter;

	static float lat_next;
	static float lon_next;

	static float pitch_current;

	static float thrust_total;


	if (initialized == false) {

		pid_init(&distance_controller,
			 global_data_parameter_storage->pm.param_values[PARAM_PID_POS_P],
			 global_data_parameter_storage->pm.param_values[PARAM_PID_POS_I],
			 global_data_parameter_storage->pm.param_values[PARAM_PID_POS_D],
			 global_data_parameter_storage->pm.param_values[PARAM_PID_POS_AWU],
			 PID_MODE_DERIVATIV_CALC, 150);//150

//		pid_pos_lim = global_data_parameter_storage->pm.param_values[PARAM_PID_POS_LIM];
//		pid_pos_z_lim = global_data_parameter_storage->pm.param_values[PARAM_PID_POS_Z_LIM];

		thrust_total = 0.0f;

		/* Position initialization */
		/* Wait for new position estimate */
		do {
			read_ret = read_lock_position(&position_estimated);
		} while (read_ret != 0);

		lat_next = position_estimated.lat;
		lon_next = position_estimated.lon;

		/* attitude initialization */
		global_data_lock(&global_data_attitude->access_conf);
		pitch_current = global_data_attitude->pitch;
		global_data_unlock(&global_data_attitude->access_conf);

		initialized = true;
	}

	/* load new parameters with 10Hz */
	if (counter % 50 == 0) {
		if (global_data_trylock(&global_data_parameter_storage->access_conf) == 0) {
			/* check whether new parameters are available */
			if (global_data_parameter_storage->counter > pm_counter) {
				pid_set_parameters(&distance_controller,
						   global_data_parameter_storage->pm.param_values[PARAM_PID_POS_P],
						   global_data_parameter_storage->pm.param_values[PARAM_PID_POS_I],
						   global_data_parameter_storage->pm.param_values[PARAM_PID_POS_D],
						   global_data_parameter_storage->pm.param_values[PARAM_PID_POS_AWU]);

//
//				pid_pos_lim = global_data_parameter_storage->pm.param_values[PARAM_PID_POS_LIM];
//				pid_pos_z_lim = global_data_parameter_storage->pm.param_values[PARAM_PID_POS_Z_LIM];

				pm_counter = global_data_parameter_storage->counter;
				printf("Position controller changed pid parameters\n");
			}
		}

		global_data_unlock(&global_data_parameter_storage->access_conf);
	}


	/* Wait for new position estimate */
	do {
		read_ret = read_lock_position(&position_estimated);
	} while (read_ret != 0);

	/* Get next waypoint */ //TODO: add local copy

	if (0 == global_data_trylock(&global_data_position_setpoint->access_conf)) {
		lat_next = global_data_position_setpoint->x;
		lon_next = global_data_position_setpoint->y;
		global_data_unlock(&global_data_position_setpoint->access_conf);
	}

	/* Get distance to waypoint */
	float distance_to_waypoint = get_distance_to_next_waypoint(position_estimated.lat , position_estimated.lon, lat_next, lon_next);
//	if(counter % 5 == 0)
//		printf("distance_to_waypoint: %.4f\n", distance_to_waypoint);

	/* Get bearing to waypoint (direction on earth surface to next waypoint) */
	float bearing = get_bearing_to_next_waypoint(position_estimated.lat, position_estimated.lon, lat_next, lon_next);

	if (counter % 5 == 0)
		printf("bearing: %.4f\n", bearing);

	/* Calculate speed in direction of bearing (needed for controller) */
	float speed_norm = sqrtf(position_estimated.vx  * position_estimated.vx + position_estimated.vy * position_estimated.vy);
//	if(counter % 5 == 0)
//		printf("speed_norm: %.4f\n", speed_norm);
	float speed_to_waypoint = 0; //(position_estimated.vx * cosf(bearing) + position_estimated.vy * sinf(bearing))/speed_norm; //FIXME, TODO: re-enable this once we have a full estimate of the speed, then we can do a PID for the distance controller

	/* Control Thrust in bearing direction  */
	float horizontal_thrust = -pid_calculate(&distance_controller, 0, distance_to_waypoint, speed_to_waypoint,
				  CONTROL_PID_POSITION_INTERVAL); //TODO: maybe this "-" sign is an error somewhere else

//	if(counter % 5 == 0)
//		printf("horizontal thrust: %.4f\n", horizontal_thrust);

	/* Get total thrust (from remote for now) */
	if (0 == global_data_trylock(&global_data_rc_channels->access_conf)) {
		thrust_total = (float)global_data_rc_channels->chan[THROTTLE].scale; 												//TODO: how should we use the RC_CHANNELS_FUNCTION enum?
		global_data_unlock(&global_data_rc_channels->access_conf);
	}

	const float max_gas = 500.0f;
	thrust_total *= max_gas / 20000.0f; //TODO: check this
	thrust_total += max_gas / 2.0f;


	if (horizontal_thrust > thrust_total) {
		horizontal_thrust = thrust_total;

	} else if (horizontal_thrust < -thrust_total) {
		horizontal_thrust = -thrust_total;
	}



	//TODO: maybe we want to add a speed controller later...

	/* Calclulate thrust in east and north direction */
	float thrust_north = cosf(bearing) * horizontal_thrust;
	float thrust_east = sinf(bearing) * horizontal_thrust;

	if (counter % 10 == 0) {
		printf("thrust north: %.4f\n", thrust_north);
		printf("thrust east: %.4f\n", thrust_east);
		fflush(stdout);
	}

	/* Get current attitude */
	if (0 == global_data_trylock(&global_data_attitude->access_conf)) {
		pitch_current = global_data_attitude->pitch;
		global_data_unlock(&global_data_attitude->access_conf);
	}

	/* Get desired pitch & roll */
	float pitch_desired = 0.0f;
	float roll_desired = 0.0f;

	if (thrust_total != 0) {
		float pitch_fraction = -thrust_north / thrust_total;
		float roll_fraction = thrust_east / (cosf(pitch_current) * thrust_total);

		if (roll_fraction < -1) {
			roll_fraction = -1;

		} else if (roll_fraction > 1) {
			roll_fraction = 1;
		}

//		if(counter % 5 == 0)
//		{
//			printf("pitch_fraction: %.4f, roll_fraction: %.4f\n",pitch_fraction, roll_fraction);
//			fflush(stdout);
//		}

		pitch_desired = asinf(pitch_fraction);
		roll_desired = asinf(roll_fraction);
	}

	att_sp.roll = roll_desired;
	att_sp.pitch = pitch_desired;

	counter++;
}
Esempio n. 3
0
/****************************************************************************
 * Public Functions
 ****************************************************************************/
void handleMessage(mavlink_message_t * msg) {


	//check for terminate command
	if(msg->msgid == MAVLINK_MSG_ID_COMMAND_LONG)
	{
		mavlink_command_long_t cmd;
		mavlink_msg_command_long_decode(msg, &cmd);

		if (cmd.target_system == mavlink_system.sysid && ((cmd.target_component == mavlink_system.compid) || (cmd.target_component == MAV_COMP_ID_ALL)))
		{
			bool terminate_link = false;
			bool reboot = false;
			/* result of the command */
			uint8_t result = MAV_RESULT_UNSUPPORTED;


			/* supported command handling start */

			/* request to set different system mode */
			if (cmd.command == MAV_CMD_DO_SET_MODE)
			{
				mavlink_system.mode = cmd.param1;
			}

			/* request to arm */
			// XXX

			/* request for an autopilot reboot */
			if (cmd.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && cmd.param1 == 1.0f)
			{
				reboot = true;
				result = MAV_RESULT_ACCEPTED;
				mavlink_msg_statustext_send(chan,0,"Rebooting autopilot.. ");
			}

			/* request for a link shutdown */
			if (cmd.command == MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN && cmd.param1 == 3.0f)
			{
				terminate_link = true;
				result = MAV_RESULT_ACCEPTED;
				mavlink_msg_statustext_send(chan,0,"Terminating MAVLink.. ");
			}

			/* supported command handling stop */


			/* send any requested ACKs */
			if (cmd.confirmation > 0)
			{
				mavlink_msg_command_ack_send(chan, cmd.command, result);
			}

			/* the two termination / reset commands need special handling */
			if (terminate_link)
			{
				printf("MAVLink: Terminating.. \n");
				fflush(stdout);
				/* sleep 100 ms to allow UART buffer to empty */
				led_off(LED_BLUE);
				led_on(LED_AMBER);
				int i;
				for (i = 0; i < 5; i++)
				{
					led_toggle(LED_AMBER);
					usleep(20000);
				}

				//terminate other threads:
				pthread_cancel(heartbeat_thread);

				//terminate this thread (receive_thread)
				pthread_exit(NULL);
			}

			if (reboot)
			{
				printf("MAVLink: Rebooting system.. \n");
				fflush(stdout);
				/* sleep 100 ms to allow UART buffer to empty */
				led_off(LED_BLUE);
				led_on(LED_AMBER);
				int i;
				for (i = 0; i < 5; i++)
				{
					led_toggle(LED_BLUE);
					led_toggle(LED_AMBER);
					usleep(20000);
				}

				//terminate other threads:
				pthread_cancel(heartbeat_thread);

				// Reset whole system
				/* Resetting CPU */
				// FIXME Need check for ARM architecture here
#ifndef NVIC_AIRCR
#define NVIC_AIRCR (*((uint32_t*)0xE000ED0C))
#endif

				/* Set the SYSRESETREQ bit to force a reset */
				NVIC_AIRCR = 0x05fa0004;

				/* Spinning until the board is really reset */
				while(true);
			}
		}
	}


	/* Handle quadrotor motor setpoints */

	if(msg->msgid == MAVLINK_MSG_ID_SET_QUAD_MOTORS_SETPOINT)
	{
		mavlink_set_quad_motors_setpoint_t quad_motors_setpoint;
		mavlink_msg_set_quad_motors_setpoint_decode(msg, &quad_motors_setpoint);

		if(quad_motors_setpoint.target_system == mavlink_system.sysid)
		{
			global_data_lock(&global_data_quad_motors_setpoint.access_conf);
			global_data_quad_motors_setpoint.motor_front_nw = quad_motors_setpoint.motor_front_nw;
			global_data_quad_motors_setpoint.motor_right_ne = quad_motors_setpoint.motor_right_ne;
			global_data_quad_motors_setpoint.motor_back_se = quad_motors_setpoint.motor_back_se;
			global_data_quad_motors_setpoint.motor_left_sw = quad_motors_setpoint.motor_left_sw;

			global_data_quad_motors_setpoint.counter++;
			global_data_quad_motors_setpoint.timestamp = global_data_get_timestamp_milliseconds();
			global_data_unlock(&global_data_quad_motors_setpoint.access_conf);

			/* Inform the other processes that there is new gps data available */
			global_data_broadcast(&global_data_quad_motors_setpoint.access_conf);
		}

	}
}
Esempio n. 4
0
static void *ubx_watchdog_loop(void * arg) //runs as a pthread and listens to uart1 ("/dev/ttyS0")
{
	/* Retrieve file descriptor */
	int fd = *((int *)arg);

	while(1)
	{
		/* if some values are to old reconfigure gps */
		int i;
		pthread_mutex_lock(&ubx_mutex);
		bool all_okay = true;
		uint64_t timestamp_now = global_data_get_timestamp_milliseconds();
		for(i = 0; i < UBX_NO_OF_MESSAGES; i++)
		{
			if(timestamp_now - ubx_state->last_message_timestamps[i] > GPS_WATCHDOG_CRITICAL_TIME_MILLISECONDS)
			{
//				printf("Warning: GPS ubx message %d not received for a long time\n", i);
				all_okay = false;
			}
		}
		pthread_mutex_unlock(&ubx_mutex);

		if(!all_okay)
		{
			/* gps error */
			printf("GPS Watchdog detected gps not running or having problems\n");

			global_data_lock(&global_data_sys_status.access_conf);
			global_data_sys_status.onboard_control_sensors_present |= 1 << 5;//TODO: write wrapper for bitmask
			global_data_sys_status.onboard_control_sensors_enabled |= 1 << 5;
			global_data_sys_status.onboard_control_sensors_health &= ~(1 << 5);
			global_data_sys_status.counter++;
			global_data_sys_status.timestamp = global_data_get_timestamp_milliseconds();
			global_data_unlock(&global_data_sys_status.access_conf);

			/* trying to reconfigure the gps configuration */
			configure_gps_ubx(fd);
			fflush(stdout);
			sleep(1);

	//		int killres = pthread_kill(&ubx_thread, SIGKILL);
	//		printf("killres=%d",killres);
	//		sleep(1);
	//		pthread_create (&ubx_thread, NULL, ubx_loop, (void *)&fd);
		}
		else
		{
			/* gps healthy */

			global_data_lock(&global_data_sys_status.access_conf);
			global_data_sys_status.onboard_control_sensors_present |= 1 << 5;//TODO: write wrapper for bitmask
			global_data_sys_status.onboard_control_sensors_enabled |= 1 << 5;
			global_data_sys_status.onboard_control_sensors_health |= 1 << 5;
			global_data_sys_status.counter++;
			global_data_sys_status.timestamp = global_data_get_timestamp_milliseconds();
			global_data_unlock(&global_data_sys_status.access_conf);
		}

		usleep(GPS_WATCHDOG_WAIT_TIME_MICROSECONDS);
	}
}
Esempio n. 5
0
static void *ubx_loop(void * arg) //runs as a pthread and listens to uart1 ("/dev/ttyS0")
{

	/* Initialize ubx state */
//	ubx_state = malloc(sizeof(gps_bin_ubx_state_t));
//	ubx_decode_init();


		/* Retrieve file descriptor */
		int fd = *((int *)arg);

		/* Initialize gps stuff */
	    int buffer_size = 1000;
//	    nmeaINFO * info = malloc(sizeof(nmeaINFO));
	    bool health_set = false;
		char * gps_rx_buffer = malloc(buffer_size*sizeof(char));

		/* gps parser (nmea) */
//		nmeaPARSER parser;
//		nmea_parser_init(&parser);
//		nmea_zero_INFO(info);
//		float lat_dec = 0;
//		float lon_dec = 0;

		/* custom (mediatek custom) */
//		gps_bin_custom_state_t * mtk_state = malloc(sizeof(gps_bin_custom_state_t));
//		mtk_decode_init(mtk_state);
//		mtk_state->print_errors = false;



//		if( !strcmp("custom",mode) )
//		{
//			printf("\t%s: custom mode\n",APPNAME);
//	//		configure_gps_custom(fd); // ?
//
//
//	//		while(1)
//	//
//	//		if (configure_gps_ubx(fd, ubx_state) != 0)
//	//
//	//		{
//	//			//TODO: execute custom read
//	//		}
//
//		}
//		else if( !strcmp("ubx",mode) )
//		{
	    	printf("\t%s: ubx mode\n",APPNAME);
	    	//set parameters for ubx


	    	//ubx state
			gps_bin_ubx_state_t * ubx_state = malloc(sizeof(gps_bin_ubx_state_t));
		   	printf("%s: ubx_state created\n",APPNAME);
			ubx_decode_init();
			ubx_state->print_errors = false;

	    	int config_not_finished = 1; //is set to 0 as soon as all configurations are completed
	    	bool configured = false;

	    	/* set parameters for ubx */

			if (configure_gps_ubx(fd) != 0)
			{
				printf("Configuration of gps module to ubx failed\n");

				/* Write shared variable sys_status */

				global_data_lock(&global_data_sys_status.access_conf);
				global_data_sys_status.onboard_control_sensors_present |= 1 << 5;//TODO: write wrapper for bitmask
				global_data_sys_status.onboard_control_sensors_enabled &= ~(1 << 5);
				global_data_sys_status.onboard_control_sensors_health &= ~(1 << 5);
				global_data_sys_status.counter++;
				global_data_sys_status.timestamp = global_data_get_timestamp_milliseconds();
				global_data_unlock(&global_data_sys_status.access_conf);
			}
			else
			{
				printf("Configuration of gps module to ubx successful\n");


				/* Write shared variable sys_status */

				global_data_lock(&global_data_sys_status.access_conf);
				global_data_sys_status.onboard_control_sensors_present |= 1 << 5;//TODO: write wrapper for bitmask
				global_data_sys_status.onboard_control_sensors_enabled |= 1 << 5;
				global_data_sys_status.counter++;
				global_data_sys_status.timestamp = global_data_get_timestamp_milliseconds();
				global_data_unlock(&global_data_sys_status.access_conf);
			}

			/* Inform the other processes that there is new gps data available */
			global_data_broadcast(&global_data_sys_status.access_conf);





	    	while(1)
	    	{




	    		read_gps_ubx(fd, gps_rx_buffer, buffer_size, &ubx_mutex);



	//
	//    		/* set health to true if config is finished after certain time (only executed once) */
	//			if(config_not_finished == 0 && counter >= GPS_COUNTER_LIMIT && false == health_set)
	//			{
	//				global_data_lock(&global_data_sys_status.access_conf);
	//				global_data_sys_status.onboard_control_sensors_health |= 1 << 5;
	//				global_data_sys_status.counter++;
	//				global_data_sys_status.timestamp = global_data_get_timestamp_milliseconds();
	//				global_data_unlock(&global_data_sys_status.access_conf);
	//
	//				health_set = true;
	//
	//				printf("%s: gps configuration successful\n",APPNAME);
	//			}
	//			else if (config_not_finished != 0 && counter >= GPS_COUNTER_LIMIT)
	//			{
	//				//reset state machine
	//				ubx_decode_init(ubx_state);
	//				ubx_state->print_errors = false;
	//				ubx_state->last_config_message_sent = UBX_CONFIGURE_NOTHING;
	//				ubx_state->last_ack_message_received = UBX_CONFIGURE_NOTHING;
	//				ubx_state->last_config_failed = false;
	//		    	config_not_finished = 1; //is set to 0 as soon as all configurations are completed
	//		    	bool configured = false;
	//		    	counter = 0;
	//
	//
	//				printf("%s: gps configuration probably failed, exiting now\n",APPNAME);
	////				sleep(1);
	////				return 0;
	//			}

	    		/* Inform the other processes that there is new gps data available */
	    		global_data_broadcast(&global_data_gps.access_conf);
	    	}

//		}
//		else if( !strcmp("nmea",mode) )
//		{
//			printf("\t%s: nmea mode\n",APPNAME);
//		}


	//	while(1)
	//	{
	//		if( !strcmp("nmea",mode) ) //TODO: implement use of global_data-gps also in nmea mode (currently only in ubx mode)
	//		{
	//			printf("\t%s: nmea mode\n");
	//			//get gps data into info
	//			read_gps_nmea(fd, gps_rx_buffer, buffer_size, info, &parser);
	//			//convert latitude longitude
	//			lat_dec = ndeg2degree(info->lat);
	//			lon_dec = ndeg2degree(info->lon);
	//
	//			//Test output
	////			printf("Lat:%d, Lon:%d,Elev:%d, Sig:%d, Fix:%d, Inview:%d\n", (int)(lat_dec*1e6), (int)(lon_dec*1e6), (int)(info->elv*1e6), info->sig, info->fix, info->satinfo.inview);
	//		}
	////		else if ( !strcmp("ubx",mode) )
	////		{
	////
	////			//get gps data into info
	////			read_gps_ubx(fd, gps_rx_buffer, buffer_size, ubx_state); //TODO: atm using the info struct from the nmea library, once the gps/mavlink structures are clear--> use own struct
	//////			lat_dec = info->lat;
	//////			lon_dec = info->lon;
	//////			printf("Lat:%d, Lon:%d,Elev:%d, Sig:%d, Fix:%d, Inuse:%d, PDOP:%d\n", (int)(lat_dec*1e6), (int)(lon_dec*1e6), (int)(info->elv*1e6), info->sig, info->fix, info->satinfo.inuse, (int)(info->PDOP*1e4));
	////		}
	//		else if	( !strcmp("custom",mode) ) //TODO: implement use of global_data-gps also in custom mode (currently only in ubx mode)
	//		{
	//			//info is used as storage of the gps information. lat lon are already in fractional degree format * 10e6
	//			//see custom.h/mtk_parse for more information on which variables are stored in info
	//			nmea_zero_INFO(info);
	//
	//			//get gps data into info
	//			read_gps_custom(fd, gps_rx_buffer, buffer_size, info, mtk_state);
	//
	//			//Test output
	////			printf("Lat:%d, Lon:%d,Elev:%d, Sig:%d, Fix:%d, Inview:%d\n", (int)(info->lat), (int)info->lon, (int)info->elv, info->sig, info->fix, info->satinfo.inview);
	//
	//		}
	//
	//
	//
	//
	//
	//	}

		free(gps_rx_buffer);
//		free(info);


		//close port
		close_port(fd);

		//destroy gps parser
//		nmea_parser_destroy(&parser);

	    return 0;

}