⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flyer.cpp

📁 UAV 自动驾驶的
💻 CPP
字号:
/* -*- indent-tabs-mode:T; c-basic-offset:8; tab-width:8; -*- vi: set ts=8: *  $Id: flyer.cpp,v 2.23 2003/03/15 05:54:54 tramm Exp $ * * (c) Trammell Hudson * (c) Aaron Kahn * * AHRS simulator based on Kalman filtering of the gyro and * accelerometer data.  Converted from Aaron's matlab code * to use the C++ math library. * * Exports AHRS data and PPM state. * ************** * *  This file is part of the autopilot simulation package. * *  Autopilot is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  Autopilot is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with Autopilot; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include <imu-filter/imu-filter.h>#include <imu-filter/AHRS.h>#include <controller/Attitude.h>#include <mat/Conversions.h>#include <mat/Quat.h>#include <state/Server.h>#include <getoptions/getoptions.h>#include <iostream>#include <fstream>#include <vector>#include "macros.h"#include "timer.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>using namespace imufilter;using namespace libcontroller;using namespace libstate;using namespace libmat;using namespace std;using namespace util;static double		dt		= 1024.0 * 256.0 / 8000000.0;static int		verbose;static ifstream		serial_port;static int		serial_fd;static voidservo_set(	int		which,	uint16_t	pos){	char		buf[4];	buf[0] = 0xFF;	buf[1] = (char) which;	buf[2] = (char) (pos >> 8);	buf[3] = (char) (pos >> 0);	if( write( serial_fd, buf, 4 ) < 4 )	{		perror( "serial write" );		return;	}	//serial_port.write( buf, 4 );	//serial_port.flush();}#if 0voidhover(	ofstream &		servo_file,	double			time,	const AHRS &		ahrs,	const Radio &		radio,	Attitude &		attitude){	static bool		last_manual;	static Vector<3>	desired_attitude;	goto_xy( 2, 1 );	if( !radio.ppm_valid )	{		printf( "NO PPM DATA                       \n" );		return;	}	printf( "Mode %d: %s\n",		radio.mode,		  radio.mode == 0 ? "XY control with PPM "		: radio.mode == 1 ? "XYZ control with PPM"		: radio.mode == 2 ? "XYZ control with USB"		:                   "UNKNOWN CONTROL MODE"	);	goto_xy( 9, 1 );	//       123456789	printf( "PPM      %05d %05d %05d %05d\n",		radio.roll,		radio.pitch,		radio.yaw,		radio.collective	);	printf( "Joy      % 05d % 05d % 05d % 05d\n",		joy_delta[0],		joy_delta[1],		joy_delta[2],		joy_coll	);			if( radio.manual )	{		if( !last_manual )			clear();		last_manual		= true;		return;	}	if( last_manual )	{		// Prevent integrator wind up by reseting		// the PID loop		attitude.reset();		last_manual = false;		desired_attitude	= ahrs.theta;		trim = Vector<3,int>( radio.roll, radio.pitch, radio.yaw );	}	goto_xy( 8, 1 );	//       123456789	printf( "Trim     %05d %05d %05d\n",		trim[0],		trim[1],		trim[2]	);	/*	 * Use the cyclic on the USB joystick for adjusting the trim.	 * The range is from -20000 to +20000 or so.	 * We want a +/- 16 deg range of attitude.	 */	const double		low	= 0x2600;	const double		high	= 0x3800;	const double		range	= 16.0 * C_DEG2RAD;	const double		scale	= range / ( high - low );	const Vector<3> 	desired_delta(/*		joy_delta[0] * scale,		joy_delta[1] * scale,		joy_delta[2] * scale*/		-(radio.roll - trim[0]) * scale,		+(radio.pitch - trim[1]) * scale,		-(radio.yaw - trim[2]) * scale * 10.0	);	attitude.attitude = desired_attitude + desired_delta;		/*	 *  Automatic flight.  Get commands from our controller	 */	const Vector<3>		commands(		attitude.step(			ahrs.theta,			ahrs.pqr		)	);	/*	 * Pitch and roll are limited to +/- 1.5 degrees by the	 * flight controller.  The simulator allows +/- 8 degrees.	 * I'm not sure what we allow on the real helicopter, but	 * lets assume 8.	 *	 * That means that 8000 ticks = 16 degrees, so 500 ticks is	 * 1 degree.  For +/- 1.5 deg that is +/- 750 ticks.	 *	 * The pitch servo is "backwards".	 */	const Vector<3>	adjust( commands * (500.0 * C_RAD2DEG) );	const Vector<3,int> cmd(		(int)(trim[0] - adjust[0]),		(int)(trim[1] - adjust[1]),		(int)(trim[2] - adjust[2])	);	for( int i=0 ; i<3 ; i++ )		servo_set( i, cmd[i] );	servo_file << time		<< " " << cmd[0]		<< " " << cmd[1]		<< " " << cmd[2]		<< endl;	goto_xy( 5, 1 );	//       123456789	printf( "Level    % 4.3f % 4.3f % 4.3f\n",		desired_attitude[0] * C_RAD2DEG,		desired_attitude[1] * C_RAD2DEG,		desired_attitude[2] * C_RAD2DEG	);	printf( "Delta    % 4.3f % 4.3f % 4.3f\n",		desired_delta[0] * C_RAD2DEG,		desired_delta[1] * C_RAD2DEG,		desired_delta[2] * C_RAD2DEG	);	printf( "Cmd      %05d %05d %05d\n",		cmd[0],		cmd[1],		cmd[2]	);}static voidhandle_joy(	const char *		data){	const int16_t *		cmds = (const int16_t*) data;	joy_delta[0]	= (int16_t) ntohs( cmds[0] );	joy_delta[1]	= (int16_t) ntohs( cmds[1] );	joy_delta[2]	= (int16_t) ntohs( cmds[2] );	joy_coll	= (int16_t) ntohs( cmds[3] );}voidudp_handler(	int			fd){	int			len;	host_t			src;	char			buf[ 1024 ];	char *			data;	struct timeval *	when;	uint32_t		type;	static struct timeval 	last;	len = udp_read( fd, &src, buf, sizeof(buf) );	data = udp_parse( buf, &when, &type );	switch( type )	{	case 1:		/* New client */		udp_clients.push_back( src );		udp_send( fd, &src, 0x0002, 0, 0 );		break;	case 2:		/* Ack from server */		// Ignore for now		break;	case 10:		/* Joystick command type */		if( timercmp( &last, when, > ) )			break;		last = *when;		handle_joy( data );		break;	default:		cerr << "Unknown message type " << type << endl;		break;	}}voidsend_all(	uint32_t		type,	const void *		buf,	size_t			len){	for( vector<host_t>::const_iterator i = udp_clients.begin() ;		i != udp_clients.end() ;		i++	) {		const host_t &client( *i );		udp_send(			udp_fd,			&client,			type,			buf,			len		);	}}voidsend_ahrs_data(	const AHRS &		ahrs){	char			buf[ 256 ];	int			len;	len = snprintf( buf, sizeof(buf),		"%3.4f,%3.4f,%3.4f,%3.4f",		ahrs.theta[0],		ahrs.theta[1],		ahrs.theta[2],		ahrs.trace	);	send_all( 3, buf, len );}voidsend_ppm_data(	const Radio &		radio){	int16_t			pulses[8];	pulses[0] = htons( radio.roll );	pulses[1] = htons( radio.pitch );	pulses[2] = htons( radio.yaw );	pulses[3] = htons( radio.collective );	pulses[4] = htons( radio.throttle );	pulses[5] = htons( radio.manual );	pulses[6] = htons( radio.mode );	pulses[7] = htons( radio.extra );	send_all( 4, (const void*) pulses, sizeof( pulses ) );}#endifstatic inthelp( void ){	cerr <<"Usage: flyer [options]\n""\n""	-h | --help			This help\n""	-V | --version			Display version\n""	-p | --port port		Port to serve data on\n""	-d | --device serial_dev	Serial device to use\n""	-s | --speed baud_rate		Serial speed\n""\n"	<< endl;	return -10;}static intversion( void ){	cerr << "$Id: flyer.cpp,v 2.23 2003/03/15 05:54:54 tramm Exp $" << endl;	return -10;}intmain(	int			argc,	char **			argv){	const char *		serial_dev	= "/dev/ttyS0";	int			serial_speed	= 38400;	int			port		= 2002;	int			real_time	= 0;	int rc = getoptions( &argc, &argv,		"h|?|help&",		help,		"V|version&",		version,		"v|verbose+",		&verbose,		"p|port=i",		&port,		"d|device=s",		&serial_dev,		"s|speed=i",		&serial_speed,		"r|realtime!",		&real_time,		"t|dt=f",		&dt,		0	);	if( rc == -10 )		return EXIT_FAILURE;	if( rc < 0 )		return help();	if( verbose )	{		cout << "serial " << serial_dev << "@" << serial_speed << endl;		cout << "port " << port << endl;		cout << "realtime " << real_time << endl;		cout << "dt " << dt << endl;	}	serial_fd = open( serial_dev, O_RDWR, 0666 );	if( !serial_fd )	{		perror( serial_dev );		return -1;	}	IMU_filter		interface(		serial_fd,		real_time,		dt	);	AHRS & 			ahrs( interface.ahrs );	IMU &			imu( interface.imu );	Radio &			radio( interface.radio );	Attitude		attitude( dt );	ofstream		angles	( "/tmp/angles.out" );	ofstream		ppm	( "/tmp/ppm.out" );	ofstream		accel	( "/tmp/accel.out" );	ofstream		rates	( "/tmp/pqr.out" );	ofstream		servos	( "/tmp/servos.out" );	interface.logfile( "/tmp/data.log" );	Server			server( port );	interface.add_fd( server.sock, Server::update, (void*) &server );	int		last_heading_sample	= interface.heading_samples;	int		last_imu_sample		= interface.imu_samples;	int		last_ahrs_sample	= interface.ahrs_samples;	int		last_ppm_sample		= interface.ppm_samples;	/* Throw away a few samples first */	while( last_imu_sample < 20 && interface.step() )	{		if( interface.heading_samples != last_heading_sample )		{			last_heading_sample = interface.heading_samples;			printf( "Init: Heading=%4.3f\n",				interface.heading			);		}		if( interface.imu_samples != last_imu_sample )		{			last_imu_sample = interface.imu_samples;			printf( "Init: "				"Accel=%4.3f %4.3f %4.3f "				"PQR=%4.3f %4.3f %4.3f\n",				imu.accel[0],				imu.accel[1],				imu.accel[2],				imu.pqr[0],				imu.pqr[1],				imu.pqr[2]			);		}	}	ahrs.initialize(		imu.accel,		imu.pqr,		0	);	while( interface.step() )	{		/* Fake compass readings every 5 Hz */		if( int( interface.time * 5 ) == int( interface.time * 5 + 0.9 ) )		{			interface.heading_samples++;			interface.heading = 0;		}		if( interface.heading_samples != last_heading_sample )		{			static double last_heading;			last_heading_sample = interface.heading_samples;			if( interface.heading < 359 )				last_heading = interface.heading;			ahrs.compass_update(				0			);		}		if( interface.imu_samples != last_imu_sample )		{			last_imu_sample = interface.imu_samples;			ahrs.imu_update(				imu.accel,				imu.pqr			);			if( verbose )			{				cout << "imu: accel=" << imu.accel << endl;				cout << "imu: pqr  =" << imu.pqr << endl;				cout << "ahrs: pqr =" << ahrs.pqr << endl;			}			interface.ahrs_samples++;		}		if( interface.ahrs_samples != last_ahrs_sample )		{			last_ahrs_sample = interface.ahrs_samples;			state_t state;			memset( (void*)&state, 0, sizeof(state) );			state.ax	= ahrs.accel[0];			state.ay	= ahrs.accel[1];			state.az	= ahrs.accel[2];			state.p		= ahrs.pqr[0];			state.q		= ahrs.pqr[1];			state.r		= ahrs.pqr[2];			state.phi	= ahrs.theta[0];			state.theta	= ahrs.theta[1];			state.psi	= ahrs.theta[2];			state.z		= -5;			server.send_packet(				AHRS_STATE,				(void*) &state,				sizeof(state)			);#if 0			send_ahrs_data( ahrs );			goto_xy( 1, 1 );#endif			printf( "Time: % 4.3f Trace: % 3.4f\n\n\n",				interface.time,				ahrs.trace			);			//       123456789			printf( "Angles:  % 4.3f % 4.3f % 4.3f (% 4.3f)\n",				ahrs.theta[0] * C_RAD2DEG,				ahrs.theta[1] * C_RAD2DEG,				ahrs.theta[2] * C_RAD2DEG,				interface.heading * C_RAD2DEG			);			angles				<< interface.time << " "				<< ahrs.theta[0] << " "				<< ahrs.theta[1] << " "				<< ahrs.theta[2] << endl;			accel				<< interface.time << " "				<< imu.accel[0] << " "				<< imu.accel[1] << " "				<< imu.accel[2] << endl;			rates				<< interface.time << " "				<< imu.pqr[0] << " "				<< imu.pqr[1] << " "				<< imu.pqr[2] << " "				<< ahrs.pqr[0] << " "				<< ahrs.pqr[1] << " "				<< ahrs.pqr[2] << endl;		}#if 0		if( interface.ppm_samples != last_ppm_sample )		{			last_ppm_sample = interface.ppm_samples;			hover(				servos,				interface.time,				ahrs,				interface.radio,				attitude			);			ppm				<< interface.time << " "				<< radio.roll << " "				<< radio.pitch << " "				<< radio.yaw << " "				<< radio.throttle << " "				<< radio.collective << " "				<< radio.manual << " "				<< radio.mode << " "				<< endl;			send_ppm_data( radio );		}#endif	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -