A LabVIEW Based Autonomous Airship Flight Controller
A LabVIEW Based Autonomous Airship Flight Controller
Thompson
Design of an Autonomous Airship Platform
Leo Rampen 2012 MECH5030M Aeronautical and Aerospace Engineering University of Leeds Woodhouse Lane, Leeds LS2 9JT
Leo Rampen
Supervised By:
Dr. Rob Hewson Prof. Martin Levesley Dr. Peter Culmer April 26, 2012
Leo Rampen
Abstract
There is a demand for aordable aerial observation capabilities across a number of sectors. The recent rise in low cost sensors and computer platforms allows the realisation of a low cost autonomous aircraft. This report details the design, implementation and testing of the control and electrical system of an autonomous airship. The report identies key work done in implementing and testing both a ight control system and the corresponding electronics for an autonomous airship. The use of PID feedback controllers for orientation, altitude and navigation is discussed and the results of simulating a waypoint navigation controller with dierent environmental conditions are demonstrated. The message sending process of a designed and implemented TCP and Wi-Fi based communication system is shown, and the content and format of the selected messages is given. A ground station concept making use of an interactive map is shown. The report goes into detail on the limitations of the sensing options, describing the fusion strategy used to mitigate these. Finally, the electronic circuit boards and electrical systems designed and built are described. The implemented ight control system is mostly functional. Simulation will allow the selection and validation of control constants. All the objectives that were initially set have been met to some degree, with those that are short waiting on nal system integration. Final system integration - the connection of all the components along the blimp envelope - will allow ight testing shortly.
ii
Leo Rampen
Acknowledgements
The achievements made during the course of this project would not have been possible without an exceptional eort by all the project team. Moving from design concepts to a working airship system in the time available has required consistent meetings, long design discussions and a great deal of hard work. The support and ideas of all the team members have made this possible. Team Members Joe Beaumont Davis Chamia Rhys Neild
The enthusiasm, advice and assistance of our three supervisors has been invaluable. Regularly meeting with us to explore our concepts and ideas allowed the project to get o the ground. Technical support from the supervisors has been hugely helpful in the design and manufacturing phase. Supervisors Dr. Rob Hewson Prof. Martin Levesley Dr. Peter Culmer
The assistance of our industrial sponsor, National Instruments, has been particularly useful. The hardware and support provided by the NI team aided us immeasurably. Industrial Advisors Hannah Wade - National Instruments
iii
Leo Rampen
Contents
1 Introduction 1.1 Report Overview . . . . . . . . . . . . . . . . . . . . . . 1.2 Aims and Objectives . . . . . . . . . . . . . . . . . . . . 1.2.1 Control, Navigation and Communication Software 1.2.2 Electronics and Electrical Systems . . . . . . . . . 2 Context and Literature Review 2.1 Flight Control Systems . . . . . . . . . . . . . . . . . 2.1.1 Summary of Existing Computer and Autopilot 2.1.2 Control Algorithms and Processes . . . . . . . 2.2 Navigation and Autonomy . . . . . . . . . . . . . . . 2.3 Communication Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 2 3 4 4 4 6 8 8 9 9 9 10 12 13 13 14 14 15 15 17 17 18 19 21 21 21 22 23 23 24 iv
. . . . . . Platforms . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
3 Equipment and Software Used 3.1 Software Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Lab Equipment Used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Hardware Used in Final Aircraft Design . . . . . . . . . . . . . . . . . . 4 Development of a Flight Control System 4.1 Orientation and Velocity Control Loops . 4.1.1 Flight Modes . . . . . . . . . . . 4.1.2 Testing and Simulation . . . . . . 4.2 Navigation System . . . . . . . . . . . . 4.2.1 Heading and Altitude Control . . 4.2.2 Navigation Simulation . . . . . . 4.2.3 Waypoint Structure . . . . . . . . 4.3 Communications Protocol Design . . . . 4.3.1 Low Level Protocol . . . . . . . . 4.3.2 Implemented Message Protocol . 5 Sensing and Actuation 5.1 Communicating with Sensors 5.1.1 Inertial Sensors . . . . 5.1.2 Ultrasonic Rangender 5.1.3 GPS Module . . . . . 5.2 Sensor Fusion . . . . . . . . . 5.2.1 Validation . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
Leo Rampen
6 Electronic Systems Design 6.1 Power Budget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Circuit Board Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Aircraft Wiring Harness . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Conclusion 8 Future Work Appendices A Control System LabVIEW VIs B Test Interface Groundstation - LabVIEW VIs C Navigation Simulation - MATLAB Code D Sensor Fusion Validation - MATLAB Code E EAGLE CAD Circuit Diagrams and PCB Designs F Interactive Waypoint Selection Map Code
34 70 76 80 85 91
Leo Rampen
List of Figures
3.3.1 Images of the aircraft systems . . . . . . . . . . . . . . . . . . . . . . . . 4.0.1 The main components of the ight control system. . . . . . . . 4.0.2 The aircraft axes of rotation and standard co-ordinate system. 4.2.1 Stable simulation responses. . . . . . . . . . . . . . . . . . . . 4.2.2 Undesirable controller responses. . . . . . . . . . . . . . . . . . 4.3.1 The TCP communication component structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 12 13 16 16 18 22 23 24 25
5.1.1 The I2 C reading process. . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.2 A single UART byte frame. The number of start and stop bits is variable. 5.2.1 The Direction Cosines Matrix complementary lter fusion method process 5.2.2 Integrated gyroscope (blue) and fused (red) orientations demonstrating roll axis divergence during small movements. . . . . . . . . . . . . . . . . . . 6.2.1 The three circuit boards designed and built. EAGLE schematics are included in Appendix E. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 A top level view of the aircraft wiring diagram. . . . . . . . . . . . . . . E.0.1The breakout board PCB design for the GS1011 wireless module. . . . . E.0.2The design for a stripboard based IO pin breakout board for the sensors. E.0.3The design of the stripboard based servo breakout board. . . . . . . . . .
27 28 86 86 90
List of Acronyms
ADC analogue to digital converter AHRS attitude heading reference system CPP Contract Performance Plan ESC electronic speed controller FPGA eld programmable gate array HIL hardware in the loop I2 C Inter-Integrated Circuit
vi
Leo Rampen IDE integrated development environment IMU inertial measurement unit IO input / output LSB least signicant bit MSB most signicant bit PID proportional-integral-dierential sbRIO single board RIO onboard ight computer TCP Transmission Control Protocol UART Universal Asynchronous Receiver/Transmitter UAV unmanned aerial vehicle
vii
Leo Rampen
1.
Introduction
Aerial observation is used globally for military operations, law enforcement, infrastructure inspection and environmental monitoring.[1] One of the primary barriers to the wider adoption of aerial observation is the high cost involved. Operating a helicopter can cost anything from 500 through 3000 an hour dependent on application.[2] Fixed wing aircraft tend to be cheaper, but costs are still in the same region. Both types of aircraft require expensive and permanent infrastructure for operation. In the eld of aerial observation, the advantages of an unmanned platform are considerable. A compact system can be deployed from a greater range of spaces, and incurs very few of the costs attached to manned aircraft when not in use. Unmanned aircraft can remain on station for extended periods of time, limited by the capacity of batteries or fuel tanks rather than the mental capacity of their pilots. The lighter weight and reduced safety requirements of systems that dont need to carry a pilot generally reduces overall cost and complexity. Most unmanned aerial vehicles (UAVs) in operation today are military. While some commercial UAVs are in use, legislation generally limits them to under 7 kg.[3, 4] At this scale, UAVs are best suited to emerging applications such as local surveillance, agricultural monitoring and low altitude aerial photography. Most commercial platforms are based on radio controlled multi-rotor helicopters or aircraft. An as-yet unexplored area is the use of buoyant or semi-buoyant airships for small scale observation. The aim of the project was to demonstrate the concept of buoyancy in an UAV by designing, building and testing an autonomous aerial observation platform. An extensive literature review and design requirement consideration led to the objectives identied in the project Contract Performance Plan (CPP). Key areas of work were identied as follows: 1. 2. 3. 4. 5. 6. 7. 8. 9. Airship envelope design and manufacture Gondola structural design and manufacture Propulsion system design, testing and manufacture Electronic system design and manufacture Control and navigation system design and implementation Communications system design and implementation Ground station design and implementation Camera hardware design and manufacture Vision software design and implementation 1
Leo Rampen
Distribution of work dened by the CPP was altered slightly as the project progressed. The key change pertinent to this report was the assignment of ground station design and implementation to Rhys Neild. The areas of work that are discussed in this report are highlighted in bold.
1.1
Report Overview
This report covers work done in the design and implementation of an airship (or blimp) ight control system. This includes an active orientation control using feedback controllers, autonomous navigation algorithms and a wireless communication system. Also discussed in this report is the design and building of an electrical system for the aircraft. This included the design of a number of circuit boards for interfacing with sensors and the design of a complete wiring harness electrical system to provide power and control signals across the length of the aircraft.
1.2
Before any technical work was done, time was taken to identify a number of key project aims. The overall project aims are identied in the project CPP.
1.2.1
As stated in the CPP, the aim relevant to the aircraft control is as follows: The airship must have a degree of autonomy and navigational capability with a view to further advancements to the complexity of the automation system in the future. This lead to the development of a number of relevant objectives. These are enumerated here as they are in the CPP. 12. Visual data must be able to be streamed back to the groundstation. 13. The airship must be able to track its current location and orientation. 14. The airship must be able to travel to a specied location and actively correct its trajectory. 15. The airship must have an on-board active stabilisation system. 16. If communication is lost, the airship must be capable of returning to the point of launch Later in the project, these were modied slightly. In the place of objective 16, a simpler requirement to shut o power on loss of communications was dened. It was deemed safer to allow the aircraft to slowly fall from the sky than to try and return to the point of launch. 2
Leo Rampen
1.2.2
Electronic system objectives were not initially dened to the same extent. At the initial stage of the project it was unclear what hardware was to be used and how it would be electronically interfaced. Most electronics work was related to linking the single board RIO onboard ight computer (sbRIO) with sensors, actuators and motors. As work progressed, a number of objectives materialised. 1. Understand the voltage and current requirements of all electrical components. 2. Design and manufacture circuit boards to connect the sbRIO to relevant components. 3. Design and manufacture a wiring harness to provide power and command signals to all systems. 4. Procure or design and manufacture power supplies to convert the battery voltage to that required by the components used. These objectives were crucial for the overall functionality of the aircraft. Many software tests could not be performed before the completion of the supporting electrical systems, and so priority was given to many of these objectives.
Leo Rampen
2.
A wide range of research papers are available detailing aerial vehicle control and autonomy. Additionally, there are several open source autopilot systems designed to provide autonomy for small aircraft. The selection of a communication method and the design of a communications protocol were both inuenced by existing literature and autopilot systems. Analysis of control and communications methods outlined in both these areas gave considerable insight into potential modes of operation. A broad understanding of the topic, including an appreciation for how existing autopilots implement features, proved vital during the design and implementation of an autonomous control system.
2.1
2.1.1
A range of light weight compact computing hardware exists. These tend to be based on well documented microcontrollers such as the AVR ATMega series or on more capable ARM processors. Based on these computers are many commercial and hobbyist autopilots for small aircraft. This section aims to provide a broad overview of possibly suitable compact computing platforms and an indication of any existing autopilot implementations. Computer Platforms Numerous compact computer platforms are available for embedded control systems. Primary aspects for consideration are weight, power consumption, cost and, perhaps most importantly, the complexity of developing for the platform. Arduino The Arduino is an open source electronics prototyping platform. The Arduino project develops a range of compact and cheap microcontroller development boards based around the Atmel ATMega family of processors and a simple development environment. A simplied C++ based programming language is used. The system is almost unique amongst microcontrollers in its ease of set up and use.[5] Primary advantages include the very low cost, light weight and large active developer community. A wide range of libraries have been developed for it and a number of existing autopilot systems could provide a good source for reference code and implementation details. 4
Leo Rampen
There are some limitations. Principally, the low clock speed of the processor limit the extent to which complex control algorithms can be run. The total size of the code executed on the system is also constrained, although the larger onboard storage (EEPROM) of newer devices such as the Arduino Mega largely negate this problem. Due to low processing power, the platform is unable to do any digital video processing or machine vision. Any camera used in conjunction with an Arduino must be capable of independently transmitting video data to the ground station. The arduino is the base platform of the Ardupilot open source autopilot system.[6] Gumstix Gumstix is a family of very compact computer modules. Primarily based around an ARM processor, the Gumstix platform comprises of the main computer module and a range of expansion boards.[7] The platform runs an embedded Linux software stack. Development is generally in C++. The platform is signicantly more powerful than the Arduino. The additional processing power available gives the potential for digital video processing and communication. An embedded Wi-Fi module could reduce the overall system weight. Primary disadvantages include the limited developer community, low familiarity with C++ and the much greater complexity involved in setting up a full operating system stack to run developed software. National Instruments Single Board RIO Industrial partners National Instruments have a range of embedded computer devices. The range of Single Board RIO devices oer particular potential for development. The sbRIO 9602 has both an onboard real time processor and an embedded eld programmable gate array (FPGA). The advantage of this over a microcontroller (which must run all programmed statements in order) is the complete parallelisation and high speed of the input / output (IO). Unlike a conventional microcontroller, a large number of high speed IO protocols can be implemented at once. A signicant advantage of the sbRIO over any other possible options is the Labview graphical development environment. This provides a large number of pre-made functions for robotics, communications and control use, allowing for faster development. The support National Instruments can provide is also an advantage of this platform. The sbRIOs principal disadvantage is the weight, size and power requirements of the board. A 3 cell Lithium Polymer battery has a nominal voltage of 11.1 V. The sbRIOs required 19-30 V input means an additional voltage boost converter would be needed for power. 5
Leo Rampen
Other Options There are a range of other microcontrollers available, some of which are already used for autopilot implementations. Other Atmel based microcontrollers include the low power ATTiny and the more powerful AVR32.[8] The multi core Parallax Propeller microcontroller provides the basis for a number of dierent autopilots.[9, 10] There are a number of dierent computer modules based around the ARM architecture, including the BeagleBoard and the OpenPilot platform. For these platforms, the primary limitation is the software development system used. Most embedded microcontrollers have a complex development process in low level languages. Developing on an unsupported platform with a small development community and an unfamiliar language and process could prove a signicant project risk.
2.1.2
Active ight stabilisation in three dimensions can be complicated and require careful controller design. For the airship design, the natural stability in roll removes the need for active control in all axes and the large buoyancy component reduces the need for high frequency control response. A number of existing systems make use of an attitude heading reference system (AHRS), comparing the aircraft orientation with a desired one and generating control inputs from the mixed outputs of independent proportional-integral-dierential (PID) control loops.[11, 6, 12] Sensor Fusion For the AHRS, making sense of inertial measurement unit (IMU) data can be a complicated process. Each sensor has its own range of strengths, weaknesses and sources of error. Gyroscopes provide a linear and fairly smooth output, but have no absolute reference. Accelerometers provide an absolute reference indicating the direction of gravity, but are subject to large amounts of noise. Magnetometers also provide an absolute reference, indicating the direction of the magnetic eld in which they sit. Unfortunately nearby metallic objects or electrical currents can skew the output.[13] A sensor fusion algorithm must be used to maintain a valid aircraft orientation over time and through aggressive movements. A number of options, ranging from simple gyroscope integration to complicated and computationally intense Kalman ltering processes are available for sensor fusion.
Leo Rampen
Gyroscope Integration Gyroscope integration provides the simplest method of orientation calculation. Each time the gyroscope is read, the value (in radians per second) is integrated and added onto previous rotations. The computational and mathematical simplicity of this method is outweighed by the susceptibility of gyroscopes to drift over time. Integration errors, rounding errors and measurement errors add up, leading to an indicated orientation that can be signicantly dierent to the actual one. If the gyroscope is ever moved to such an extent that the output saturates, the orientation will be subject to larger errors. Complementary Filter A complementary lter introduces a weighted accelerometer reading into the orientation reading. This is most succinctly demonstrated mathematically as is shown below.
t = wg (t1 + gyro dt) + wa xacc In this equation, t represents the angle at this timestep, wg and wa are the integration and accelerometer weightings, t1 is the angle at the previous timestep and gyro is the latest gyroscope reading. Typical values for wg and wa might be 0.98 and 0.02 respectively. The small accelerometer weighting will, over time, correct the angle with absolute readings. The small weighting acts as a low pass lter, minimising the response to noise.[14] Direction Cosines Matrix A further advancement of the complementary lter concept represents orientation with rotation matrices, which are known as a direction cosines matrix as the values are the cosines of the angles between the aircraft orientation and the global coordinate system. An advantage of this method is the ability to multiply the matrices together to calculate the outcome of a number of rotations. The orthogonal properties of the rotation matrix can be monitored and the matrix normalised if theyre found to stray. This process reduces small integration and rounding errors. In the method described by Mahoney et al. and further expanded into a practical implementation by Premerlani and Bizard, a proportional-integral controller is used to combat gyroscope drift. Yaw, pitch and roll error signals are created from the absolute sensors. The output of the controller is fed back into the gyroscope readings.[15, 16] This is the method implemented in the Ardupilot system.[6]
Leo Rampen
Kalman Filter A Kalman lter uses past state knowledge and a model of the dynamic system to make a prediction of the current system state. This is then updated based on observed sensor measurements. A properly congured Kalman lter produces a statistically optimum output for the sensor information given. Downsides of a Kalman lter for orientation estimation are the complexity of nding the correct noise and uncertainty values for initialisation, and the computational and mathematical complexity of the process. There are a few examples of Kalman lters used in existing UAV control systems.[11, 12]
2.2
Most autonomous navigation systems use GPS for navigation between waypoints. Other systems have used machine vision or laser rangenders.[12, 17] The simplest GPS navigation simply points the UAV at the heading to the waypoint, while more complicated systems use some form of trajectory or path following between waypoints.[18, 19]
2.3
Communication Options
Reliable communication for aircraft command is vital. A number of low cost options are available. The selected option is largely dependent on the nal computer chosen, as each device has dierent capabilities. The most basic form of wireless communication acts as a virtual serial port. Devices available include Bluetooth modules, Zigbee low power transceivers, and Wi-Fi modules.[20, 21] These are all limited by the baud rate of the serial port (usually up to around 1 Mbps) or the protocol bandwidth. For faster data throughput (required for video transmission), other protocols must be considered. Wi-Fi modules interfacing over SPI can achieve higher speeds, or a Wi-Fi based ethernet bridge could allow standard network speeds.[22] For testing purposes, range is less important. Wi-Fi has been successfully tested past 37 km, while high end Zigbee modules have stated ranges in excess of 80 km.[23, 21] CAA rules limit aircraft to a 500 m radius and line of sight, reducing the need for long range radio.[24]
Leo Rampen
3.
A variety of software and hardware was used during the design and manufacturing process. An additional summary of the key components used in the nal aircraft is given.
3.1
Software Used
A summary of some of the software vital for the project is given. This is by no means an exhaustive list, but provides an indication of the key software used. The control system was implemented using National Instruments LabVIEW software. This is a graphical programming environment with emphasis on the data ow between functions. EAGLE electronic circuit CAD software was used for the design and circuit board layout of all the boards produced. Mathworks MATLAB was used to simulate some basic navigation scenarios and to test the navigation controller code. The Python scripting language was used to test data communication, and to implement a web server to allow interactive waypoint mapping. Javascript was used to build a mapping interface. Solidworks 3D CAD software was used to quickly prototype designs and to determine component layout. The Arduino integrated development environment (IDE) was used in conjunction with the Wiring C++ based programming language for Arduino software development.
3.2
A range of lab equipment was used. A number of items proved useful in debugging and testing electronic systems independent of each other. The ability to quickly check that signals and voltage levels were correct proved invaluable while building the electrical systems. An oscilloscope was used for debugging of implemented FPGA digital IO. This included checking that the digital signals produced by a serial implementation were correct and ensuring that the length and timing of the pulses generated for servo control were ideal. 9
Leo Rampen
An Arduino microcontroller development board was used for serial debugging and sensor testing. The simplicity of the Arduino language and the wide range of code examples available allowed quick testing independent of LabVIEW. This proved important in identifying any pin connection problems and ruling out faulty sensors. A multimeter proved invaluable in continuity testing, circuit resistance measurement and voltage checking. The ability to quickly probe the produced circuits allowed potential problems to be diagnosed independently of other systems. A number of hand tools were used for nal assembly.
3.3
Final components used in the nal aircraft design were selected based on cost, weight, ease of use and availability. A summary of the key components used and their selection criteria is below. The single board RIO onboard ight computer (sbRIO) provided by National Instruments. After considering the options identied in Section 2.1.1, the sbRIO was selected due to the large body of support from our industrial partners National Instruments. The sbRIO was programmed using the LabVIEW graphical programming environment. This board was damaged during the project, and so late stage development and testing was done on an NI cRIO platform. A DLink DIR615 wireless router. This provides wireless communications capabilities and acts as a network switch to allow use of the network camera. Initially a more compact wireless module was selected for use, but problems in achieving the bandwidth required lead to a change to a wireless router. Communication options are discussed in Section 2.3, while justication for the selection of Wi-Fi is given in Section 4. 10
Leo Rampen
A Sensor Stick IMU. This is a simple board providing an electrical interface to a gyroscope, an accelerometer and a magnetometer. Section 2 discusses a number of sensing options considered. An SRF02 ultrasonic rangender. This provides accurate short-range height readings for landing and maintaining ground clearance. A GS407 Ublox5 GPS module. This provides GPS location data for navigation and location telemetry. An Axis M1054 network camera for visual observation. This is mounted on a gimbal device for pan and tilt movement. Discussion of camera selection and gimbal design is documented in Rhys Neilds report.[25] Three brushless motors driven by standard hobby electronic speed controllers (ESCs). All are commanded by standard pulse width servo control documented in greater detail in Section 5. Two are located at the front, mounted on an arm able to swivel to provide thrust vectoring. One is located at the rear, mounted on a bracket to allow swivelling. This provides a pitching and yawing moment. The propulsion system is dened in more detail in the report by Davis Chamia.[26] A range of hobby servos using the same pulse width control dened above. Four servos are used in the control surfaces. Two are used to swivel the motors, one at the rear and one at the front. An additonal two are used for the camera gimbal movement.
Figure 3.3.1
11
Leo Rampen
4.
The aircraft designed is a complex system utilising 13 servos, 4 control surfaces, 3 motors and 6 sensors. To eectively provide control of the system, a number of dierent aspects had to be developed. The basic ight control system can be divided into three main areas: 1. The ight controller, composed of a number of feedback control loops. 2. The waypoint navigation system generating control inputs. 3. The communications system, receiving and sending data to the groundstation. Each of these components provides important contributions to the overall autonomy of the aircraft. An illustration demonstrating how these relate to each other is shown in Figure 4.0.1.
Figure 4.0.1: The main components of the ight control system. A standard aircraft co-ordinate system was used for consistency. This is demonstrated in Figure 4.0.2. Notably, the Z axis acts down in this coordinate system. The following sections describe the implemented software built in LabVIEW. Some images of the VIs built are included in Appendix A. For the full LabVIEW VIs the author can be contacted.
12
Leo Rampen
Figure 4.0.2: The aircraft axes of rotation and standard co-ordinate system.
4.1
The control system uses PID control loops to generate motor control outputs based on a range of inputs. Motors are commanded in terms of X, Y and Z dimension thrusts, and then an overall thrust and swivel angle is computed for the front and rear motors. Saturation values are used to limit thrust, and priority is given to vertical thrust to reduce the likelyhood of losing altitude. This system lies in the Flight state controller part of Figure 4.0.1.
4.1.1
Flight Modes
The ight controller has a number of clearly dened ight modes. Each mode makes use of sensor data - IMU orientation, GPS altitude and ultrasonic rangender ground height - to compute motor and control surface control outputs. Forward ight mode takes a heading, altitude and ground speed as inputs. A desired pitch is generated based on the error to the target altitude. Tail motor thrusts and control surface angles are computed from the orientation error. Forward thrust is computed from the ground speed error. Motor outputs in each axis are summed and swivel angles computed. 13
Leo Rampen
The initial implementation of the orientation controller operates only on yaw and pitch. Roll was initially ignored due to the natural stability of the airship. Dierential thrust on the front motors, although an option, was not utilised. Hover ight is somewhat dierent. The altitude controller sets thrust equally on all three motors. Desired orientation is set at level, with the orientation controller maintaining this. Landing is very much like hover, but a constant vertical velocity is maintained. The ultrasonic rangender is used for precise height measurement. In Take-o mode, the aircraft rises to hover at 2 m, before proceeding to be commanded normally. An idle mode is implemented which shuts o all motors.
4.1.2
The ight control system is set up for hardware in the loop (HIL) testing. When a Simulation boolean is dened, sensor data is replaced with data read over the network from a simulation running elsewhere. The desired motor control inputs are then passed back over the network for simulation input. This allows the full system to be tested on the intended hardware before any ying takes place. Some information about the implementation of the simulation is outlined in the report by Joe Beaumont.[27] The simulation system is not yet fully functional.
4.2
Navigation System
An initial project requirement was to introduce a degree of autonomy into the airship. The aircraft is always in one of 3 discrete modes. In manual control mode, no navigation commands are generated. Orientation and forward throttle commands are communicated directly from the ground-station. Two autonomous modes - waypoint navigation mode and machine vision navigation mode - were implemented. Machine vision mode is covered further in Rhys Neilds report.[25] The navigation system makes use of a GPS receiver for location information. Desired waypoints are communicated with the aircraft over WiFi. The navigation controller generates heading, velocity and altitude requirements which are fed into the controllers described in Section 4.1. This arrangement can be described as a cascading controller, as it makes use of a number of PID loops in a row. This simplies the tuning process.
14
Leo Rampen
4.2.1
The navigation system uses a simple PID controller to determine desired heading. The bearings from the previous waypoint and the current GPS location to the target waypoint are computed and the error used to drive the controller. As a crosswind will manifest as a steady state error, integrator windup will cause the aircraft to compensate by crabbing into the wind. With no integrator component, the aircraft would drift downwind before approaching the waypoint heading into the wind. The desired aircraft velocity is proportional to the distance to the target waypoint. A saturation value is set as the cruise velocity. By using a low saturation value and a high proportional constant, the cruise velocity is maintained for most of a waypoint leg. The cruise velocity must be selected to maintain vertical control authority and will be nalised based on real world aircraft performance. The altitude commanded by the navigation system is based on the dierence in height between the target and previous waypoint. As the aircraft progresses between the two, the desired altitude is increased proportionally. Each waypoint denes an acceptance radius, typically 5 metres. When the distance to the waypoint is under this, it is deemed reached and any tasks dened are completed. If the boolean ag pass through is true, the velocity is maintained through the waypoint. If a hover time is dened, the aircraft will hover until this has elapsed. If the boolean ag land is true, the aircraft will land at the waypoint. If no ags are set as waypoint tasks, the current waypoint variable is incremented and the aircraft will y to the next waypoint. Because of the slow speed of the aircraft, the navigation system is run at 5 Hz to reduce the overall processing power needed.
4.2.2
Navigation Simulation
The navigation algorithms were simulated in Mathworks MATLAB software. A vastly simplied navigation problem was set up and the PID controller implemented. This allowed the mathematics to be validated and initial values for controller constants to be determined. Aircraft position was calculated through simple addition of the previous position, the aircraft speed and the wind vector. The initial integrator guess was the bearing to the target waypoint. This simulation was eective as a concept validation, but would require signcantly more work to eectively model a true navigation system.
15
Leo Rampen
The output of the simulation is shown across Figures 4.2.1a to 4.2.2b. The gures all represent the navigation system with a crosswind applied. The red pentagram represents the previous waypoint, while the green asterisk represents the target. The black diamonds show the path of the aircraft. With the right controller constants, the aircraft can follow the required track even with crosswinds close to its full ight speed. Wind speeds above the aircraft ight speed cause the controller to break down and the aircraft to blow o course. The selected process gains must reect the fact stability of the navigation system is more important than the response speed. Complete system simulation will allow further tuning of the process gains. The MATLAB code used for the simulation is included in Appendix C.
Figure 4.2.1: Stable simulation responses. The black arrow represents wind direction and speed.
(a) Complete controller breakdown in a wind faster (b) A very unstable response indicating poor tuning. than the aircraft speed
16
Leo Rampen
4.2.3
Waypoint Structure
An array data structure is used to represent waypoints. Rows represent individual waypoints, while columns reect the data dened by that waypoint. Table 4.2.1 shows the information in a waypoint. This includes the co-ordinates and a number of boolean ags indicating tasks to undertake once the waypoint is reached. A seperate conguration variable is used to identify the current waypoint. Any changes to the order of waypoints is made by reordering the rows in the array.
Column 0 1 2 3 4 5 6 7 8 9 Data Latitude Longitude Altitude Hold time Acceptance radius Pass straight through Yaw angle Return to launch Land Camera viewpoint Format Degrees Degrees Metres Seconds Metres Boolean Radians Boolean Boolean Integer
Table 4.2.1: The data represented by each column in the navigation waypoint array. The waypoint array contains many similar rows. Other arrays are assembled in a similar fashion.
4.3
A range of commands were required to be sent to the aircraft. Commands included waypoints indicating where to y to, viewpoints indicating the required position of the camera, conguration settings and manual ight control settings. Additionally, telemetry data was required to be returned to the ground station. This called for a reliable and eective message communication system. Some key requirements were identied: 1. Control commands must be communicated quickly and without corruption. 2. Aircraft telemetry must be communicated at high frequency. 3. Video data from the onboard camera must be communicated to the ground station at an acceptable frequency. 4. The system must maintain a heartbeat signal, indicating a successful connection. This problem was addressed in two parts. The rst was a system to transfer string data between the ground station and the aircraft. The second was the design of an extensible messaging protocol with low processing overheads.
17
Leo Rampen
4.3.1
The Transmission Control Protocol (TCP), a standard networking protocol designed to deliver an ordered stream of bytes reliably, was used. The ground station acts as a client, initiating all connections, while the aircraft control system acts as a server. The ground station periodically polls the aircraft for required data (such as aircraft orientation), and the blimp responds. When any user controller parameters on the groundstation are changed, the new data is sent to the aircraft. This process is demonstrated in Figure 4.3.1. Initially two 4 byte integers are sent. The rst integer reects the total size of the data payload to follow and tells the server how much data to read. The second integer is a command byte which identies the type of message being sent. The client periodically sends commands (identied by a command byte in the range 2 to 9) and requests for data (with command bytes above 20). If the sent message is a command the aircraft will reply with ACK to acknowledge receipt. If the sent message is a request for data the aircraft will reply with that data. Data at the client is produced by events (such as the user changing a conguration value) or by timed loops. When data to be sent to the aircraft is produced, it is added to LabVIEW named queue. A loop continually checks the queue for data to send. When 18
Leo Rampen
data is in the queue, a TCP connection is initiated with the server on the aircraft and the data is transferred. Any messages received in reply are added to another queue, which is parsed by a separate loop. The use of LabVIEW named queues to transfer data ensures that all generated data is eventually transferred to the remote system. Periods of high data generation, perhaps occurring when a number of timed loops coincide with each other, are smoothed out by periods with less communication. As long as the amount of data generated does not exceed the total throughput of the network connection over time, data will be transferred. The aircraft continually listens for connection attempts. When one is made, the received message is parsed and any relevent local settings updated. If the message is a request for information, a reply is made. The data connection is continually monitored with a heartbeat signal. The aircraft is periodically polled every second, and key information about the current ight mode is returned. Other data is only sent if the heartbeat signal was recently received. If the aircraft receives no signal for 5 seconds, the ight control loops are ended, the motors shut down and the aircraft enters an idle state. This is a safety feature.
4.3.2
Existing protocols and systems were identied and analysed. Many existing open autopilot systems make use of the Micro Air Vehicle Communication Protocol (MAVLink) system originally developed for the Pixhawk UAV.[12, 6] MAVLink eciently transfers pre-dened data across serial links. The MAVLink system generates C based message packing and unpacking functions to allow the creation of a simple string from the required message data.[28] A number of challenges were identied in using the MAVLink system. While LabVIEW does allow for the calling of externally compiled libraries written in C, past experience has proved that this can be complex to implement. The key requirement that the software written was able to be executed on both the Windows based ground station and the aircraft also limited this option. Additionally, LabVIEW data types are not directly transferable to C types. Problems were anticipated with oating point numbers and 2 dimensional arrays. The decision was made to develop a protocol inspired by MAVLink, but solely written in LabVIEW. The large feature-set of MAVLink provides many functions not required for 19
Leo Rampen
Int 2 3 4 5 6 7
Uplink Data Represented Waypoints Viewpoints Camera conguration Aircraft conguration Manual control commands Shut down command
Array Size 10xN Array 11xM Array 5x1 Array 6x1 Array 6x1 Array Boolean
Array Size 6x1 Array 3x1 Array 7x1 Array String Strings Integer
Table 4.3.1: The message types communicated. The Int column represents the command byte for that message. the initial aircraft prototype, and so a subset of key features was developed. The format of data was modied to closer reect LabVIEW data types and software design methods. The selected communication messages are demonstrated in Table 4.3.1. To represent most of the data sent, an array structure was used. As a means of example, Table 4.2.1 shows the columns and data represented in the waypoint array. This structure allowed by virtue of its ordered nature a clear waypoint hierarchy. A disadvantage of this system was the requirement to communicate the entire array when any changes were made. This could be negated with a dierential algorithm. Messages consisting only of one number or boolean are sent as simple numerical strings. Data integrity was ensured by the aircraft regularly taking the MD5 checksum of all conguration arrays. The groundstation compares the checksum sent by the aircraft to that of its own conguration arrays. If they dont match, the conguration arrays are re-sent to the aircraft. This system sets the ground station as the Master, and ensures all settings on the aircraft are up to date. A simple groundstation was written to ease the passing of data between the user and the control system. In conjunction, a map based waypoint selection system was written in Javascript, HTML and Python. This allows a user to select a series of waypoints on an interactive map, and upload them to the aircraft. The aircraft location is also plotted on the map. The user interface, the LabVIEW VIs and map source code are included in Appendices B and F.
20
Leo Rampen
5.
Interfacing with the selected sensors and actuators is a vital aspect of the control system. The hardware used is detailed in Section 3.
5.1
Three primary sensors are used on the aircraft. The inertial measurement unit (IMU) is a small board comprising of three chips. The ADXL345 accelerometer, HMC5843 magnetometer and ITG-3200 gyroscope chips are all MEMs devices which communicate over a standard Inter-Integrated Circuit (I2 C) interface. The SRF02 Ultrasonic Rangender is a lightweight distance sensor. It uses acoustic pulses to determine distance, and is also communicated with by I2 C. The GS407 Ublox5 GPS is a small GPS module with support for standard NMEA sentences. It communicates over a Universal Asynchronous Receiver/Transmitter (UART) serial interface.
5.1.1
Inertial Sensors
Reading over I2 C All I2 C devices have a 7 bit slave bus address which for all practical purposes is xed. To read values from an I2 C device, rst a command byte must be written to the device slave address. Commands are dened by the device datasheet. On receipt of a command, the device will respond with the requested data. Data is represented as bytes in the form of least signicant bits (LSBs) and most signicant bits (MSBs). These can be joined in a bit shift operation to give the output value. The data read from each chip can then be interpreted based on the datasheet instructions to yield an acceleration, rotation rate or orientation with respect to North in standard units. The process used to read X, Y and Z acceleration values from the ADXL345 accelerometer is shown in Figure 5.1.1. The other two chips are broadly similar. Development of the LabVIEW I2 C implementation drew from the LabVIEW built in examples and from I2 C guides for the Arduino platform.[29]
21
Leo Rampen
Figure 5.1.1: The I2 C reading process. 1. 6 bytes, starting at the 0x32 register of the accelerometer (which is at the slave address 0x53), are read. 2. The returned 6 byte data array is indexed for individual bytes. 3. The data returned is built into numbers. The 6 bytes correspond to the X, Y and Z LSBs and MSBs. 4. The resulting 16 bit signed integer is converted to an unsigned integer 1 5. The integer is then scaled by a value dened in the datasheet - in this case 256 . Sensor Limitations Each sensor has limitations, both in terms of drift and environmental noise and in terms of fundamental hardware limitations. The digital sensors used all provide internal analogue to digital converters (ADCs), and so the limitations and sensitivity of each chip is quantied in its datasheet. The three inertial sensors and their resolutions and limits are summarised on Table 5.1.1. The gyroscope and accelerometer bias can generally be negated by averaging readings over a stationary period.
ADXL345 ITG-3200 HMC5843 Accelerometer Gyroscope Magnetometer Limits 2g 2000 /s 1.0 Ga Resolution 3.9 mg 0.07 /s 1300 counts/mGa Tolerance 40 mg 40 /s 5% [30] [31] [32]
5.1.2
Ultrasonic Rangender
The SRF02 rangender also interfaces over I2 C, but required more careful consideration. The timing requirements of acoustic sensing mean that the sensor takes approximately 65 ms to determine range. To determine distance, an initialise ranging command must be sent, and then time allowed to pass before the distance is read o the device. The device returns 255 for both bytes until a range is available, and so a while loop was set up to continually poll it until valid data was returned. 22
Leo Rampen
5.1.3
GPS Module
The GPS required implementation of a serial protocol over the sbRIO digital IO pins. While the sbRIO hardware does have a standard serial port, the placement away from the other board digital IO pins made it impractical to use. Like the I2 C implementation, this was based on LabVIEW implemented examples with some modication to better integrate the code with the rest of the IO code running on the FPGA. The serial protocol is a very open specication. The baud rate (indicating bit length), number of start bits, number of stop bits and the presence of a parity bit for error detection are all predened. From the idle condition of high, a byte is communicated over the TX pin by rst making the pin low for the start bit length, before setting the pin to high or low at the dened baud rate. The end of transmission is indicated by a number of stop bits. The basic byte frame is demonstrated in Figure 5.1.2. The GS407 module used is read at 9600 baud with 8 data bits, 1 stop bit and no parity bits. Data received from the GPS is in the form of NMEA 2.0 standard sentences. A parser for this format is included within LabVIEW.
Figure 5.1.2: A single UART byte frame. The number of start and stop bits is variable.
5.2
Sensor Fusion
As discussed in Section 2.1.2, fusing the data read from the IMU to generate an accurate and reliable orientation is crucial. From the methods discussed, the Direction Cosines Matrix method was selected for implementation. This presented a good compromise between the complexity of implementing a Kalman lter and the limited accuracy of a simple gyroscope integration method. The method has been shown to be eective in a number of existing autopilot systems, and so presented less of a project risk than other methods. A full account of the mathematical equations used is given by Premerlani and Bizard.[16] The implemented algorithms use a feedback controller. The process is demonstrated graphically in Figure 5.2.1. At point 1, gyroscope data is read through the process outlined in Section 5.1.1. The X, Y and Z values are multiplied by the timestep and built into a rotation matrix representing the rotation during the timestep. Rotation rates are assumed to be constant through 23
Leo Rampen
Figure 5.2.1: The Direction Cosines Matrix complementary lter fusion method process the timestep. At point 2, the produced rotation matrix is multiplied by the previous rotation matrix to produce a matrix representing the aircrafts current orientation. With no correction, this orientation matrix only demonstrates aircraft orientation with respect to initial start orientation. At point 3, small numerical and integration errors are corrected. A property of a direction cosine matrix as used here is that it is orthogonal - the matrix multiplied by its transpose yields an identity matrix. Any small changes which cause the loss of orthogonality can be corrected. Point 4 takes into account magenetometer and accelerometer values, computing the error between the orientations indicated by the absolute sensor and that indicated by the gyroscope based rotation matrix. The PI produces an oset (point 5) applied to the next gyroscope values read.
5.2.1
Validation
To validate the method, a number of IMU readings were taken. The basic integral method discussed in Section 2 and the feedback method discussed above were implemented in MATLAB and the resulting rotations plotted. Figure 5.2.2 shows the dierence between the integrated and fused roll orientation over a 40 second period of small movements. All the MATLAB code used for this is included in Appendix D.
24
Leo Rampen
Figure 5.2.2: Integrated gyroscope (blue) and fused (red) orientations demonstrating roll axis divergence during small movements.
25
Leo Rampen
6.
The airship requires a large number of electrical systems to maintain autonomy. Sensors, servos and motor ESCs were interfaced with using digital IO on the sbRIOs. The power requirements of each component had to be assessed and power supplies with the correct voltage and current capabilities designed and built.
6.1
Power Budget
The voltage and current requirements of each electrical component used was assessed and a power budget constructed. Broadly, most systems required either 3.3 V or 5 V. Balancing this requirement with the battery supply voltage of 11.1 V and the Single Board RIO voltage requirement of 19 - 30 V required careful consideration. The power required by each item is demonstrated in Table 6.1.1. Power sources used are also shown. Each servo must be considered in terms of its stalled current - the current draw seen when the servo is unable to move due to being physically blocked. For the camera and router, a 5 V 3A switching step down converter was used, while for the camera gimbal a 5 V linear regulator was used. The continuously high power draw of the router and camera called for the weight and cost of an ecient switching regulator, while the high peak current but low average current of the camera gimbal proved to be suitable for a cheaper and lighter linear regulator.
Power Supply Battery Boost converter Switching buck converter Voltage regulator Voltage regulator Rear ESC voltage regulator Front ESC voltage regulator Source Battery Battery Battery sbRIO 5 V out Battery Battery Voltage 11.1 V 20 V 5V 5V 3.3 V 5V 5V Peak Current 30 A+ 3A 3A 3A 250 mA 1A 2A Powers Motors sbRIO Wi-Fi router, camera Gimbal servos Sensors Rear servos Swivel servo
Table 6.1.1: The power converters used on the aircraft. The source of all electrical power is the battery.
6.2
Three circuit boards were designed for the aircraft. The rst, a breakout board for the GS1011 Wi-Fi module described in Section 3, was produced as a PCB. Because of the limited bandwidth possible, the GS1011 module and PCB were not used in the 26
Leo Rampen
nal design. To reduce turn-around time and allow easier modication, the last two (connecting the sbRIO pins, sensors, servos, motor controllers and power supplies) were developed on 0.1 pitch copper stripboard. Figures 6.2.1a to 6.2.1c show the three designs. The full EAGLE circuit diagrams and PCB layouts are included in Appendix E.
(a) The GS1011 Wi-Fi module (b) The sbRIO actuation breakbreakout board out boards.
Figure 6.2.1: The three circuit boards designed and built. EAGLE schematics are included in Appendix E. The initial design for the sensor breakout board had problems with electrical noise. Attempting to operate both the GPS and the IMU on the same circuit caused communications with the IMU to break down. Additional capacitors and a rerouted power supply yielded no improvement. A second design, moving the GPS o the board entirely and seperating the sensors electrically as much as possible was found to be functional.
6.3
Providing the correct voltage, power and signals to the dierent components of the aircraft required some consideration. A wiring harness was designed to do this eectively. Wire gauge was selected based on current requirements. A single ground plane is in operation throughout the aircraft, with high impedence resistors used to protect the digital IO of the FPGA from too much current. A simplied aircraft wiring diagram is shown in Figure 6.3.1. Not shown are the main motors (which are on an arm protruding from the propulsion gondola) and the three control surface servos for the other ns.
27
Leo Rampen
28
Leo Rampen
7.
Conclusion
This report has demonstrated some of the tasks undertaken to meet the initial objectives. For all objectives, signicant progress has been made. An implemented ight control system allows the autonomous operation of the aircraft. A functional communications system allows user commands to be processed and telemetry data returned. A complete electrical system allows the reading of sensors and the commanding of control surfaces and motors. Additional safety features to shut down the aircraft on loss of communication and monitor the control system for errors have also been implemented. In some areas, work is close to complete. The electrical system is fully functional, and the communications system has shown high resiliency. While the ight control system has been implemented to match all objectives, without considerable further testing it is unclear where bugs and errors lie. Hardware in the loop simulation will allow the control loop constants to be tuned and cause any errors or oversights to surface. The project has a legacy which includes a signicant amount of LabVIEW code and a number of electronic circuit boards. The circuit diagrams of the boards are included in Appendix E. Use of the airship system would require inspection of these diagrams to ensure correct wiring connections. By necessity, a wide range of elds must be investigated to build a complete control system. Gaining an understanding of dynamics, feedback controllers, electronic circuit design and a great deal more has been both an engaging and an enjoyable process.
29
Leo Rampen
8.
Future Work
While a lot of work has been done, a great deal remains. In particular, the tuning of the ight control loops will require some focus both during simulation and in ight tests. Some nal integration work is required to connect the tail assembly to the main electrical system. It is anticipated that this work will continue during May. The damaged sbRIO limits aircraft ight capability. If a similar board cannot be sourced, a dierent control board (such as an Arduino) will have to be used. The route to be taken will become clear after further feedback from National Instruments. Flight testing is planned for the near future. The work required on the control system building up to this will depend on the computer board used for ying. If an Arduino has to be used, porting the control system will take some additional time. In the longer term, a number of design changes could be made. The bulky and heavy Wi-Fi router was selected for ease of setup. With further work, a much lighter weight module such as the GS1011 could achieve the bandwidth required for video. The overall weight of the control system could be reduced by designing and etching a single printed circuit board. This was initially considered, but the complexity of a single design coupled with the risk of mistakes rendering the board useless led to the current stripboard based solution. National Instruments have a lighter sbRIO board with a proprietary high density connector. A PCB designed to interface with that board would save signcant weight.
30
Leo Rampen
Bibliography
[1] A. Horcher and R. J. Visser, Unmanned aerial vehicles: Applications for natural resource management and monitoring, tech. rep., San Dimas Technology and Development Center. [2] BBC, North wales police reveal 1.7m helicopter running cost, Dec. 2010. http: //www.bbc.co.uk/news/uk-wales-north-east-wales-11985097. [3] CAP722 - unmanned aircraft system operations in uk airspace guidance, tech. rep., Civil Aviation Authority, Apr. 2010. [4] The air navigation order 2009, tech. rep., UK Government, Nov. 2009. [5] Arduino homepage, 04 2012. http://www.arduino.cc/. [6] Ardupilot mega, Apr. 2012. http://code.google.com/p/ardupilot-mega/wiki/ home?tm=6. [7] Gumstix, 04 2012. http://www.gumstix.com/. [8] Microcontrollers - Atmel Corporation, 04 2012. http://www.atmel.com/products/ microcontrollers/default.aspx. [9] Octopilot, Octopilot, 06 2009. http://code.google.com/p/octopilot/. [10] Attopilot, Attopilot v3 AHRS IMU, 04 2012.
http://www.
attopilotinternational.com/products/acs/attopilotahrs.html.
[11] J. S. Jang and D. Liccardo, Automation of small uavs using a low cost mems sensor and embedded computing platform, in 25th Digital Avionics Systems Conference, 2006 IEEE/AIAA, pp. 1 9, oct. 2006. [12] L. Meier, P. Tanskanen, F. Fraundorfer, and M. Pollefeys, Pixhawk: A system for autonomous ight using onboard computer vision, in Robotics and Automation (ICRA), 2011 IEEE International Conference on, pp. 2992 2997, may 2011. [13] S. Fux, Development of a planar low cost Inertial Measurement Unit for UAVs and MAVs, Masters thesis, Swiss Federal Institude of Technology, Zurich, 2008. [14] S. Colton, The balance lter, a simple solution for integrating accelerometer and gyroscope measurements for a balancing platform, tech. rep., June 2007.
31
Leo Rampen
[15] R. Mahoney, S.-H. Cha, and T. Hamel, A coupled estimation and control analysis for attitude stabilisation of mini aerial vehicles., tech. rep., Nov. 2006. [16] W. Premerlani and P. Bizard, Direction cosine matrix imu: Theory, tech. rep., May 2009. [17] Y. Lin, Hyypp, and A. Jaakkola, Mini-uav-borne lidar for ne-scale mapping, Geoscience and Remote Sensing Letters, IEEE, vol. 8, pp. 426 430, may 2011. [18] W. Ren and R. Beard, Trajectory tracking for unmanned air vehicles with velocity and heading rate constraints, Control Systems Technology, IEEE Transactions on, vol. 12, pp. 706 716, sept. 2004. [19] D. Nelson, D. Barber, T. McLain, and R. Beard, Vector eld path following for miniature air vehicles, Robotics, IEEE Transactions on, vol. 23, pp. 519 529, june 2007. [20] Wireless product specications, Apr. 2012. http://www.lm-technologies.com/ adapters/LM058_Bluetooth_Serial_Adapter/. [21] Digi XBee Wireless RF Modules - Digi International, Apr. 2012. http://www. digi.com/xbee/. [22] Gs1011MXXS size-optimised Wi-Fi modules, Apr. 2012. http://www.gainspan. com/products/GS1011MS_modules.php. [23] K. Chebrolu, B. Raman, and S. Sen, Long-distance 802.11b links: performance measurements and experience, in Proceedings of the 12th annual international conference on Mobile computing and networking, MobiCom 06, (New York, NY, USA), pp. 7485, ACM, 2006. [24] CAP658 - Model Aircraft: A Guide to Safe Flying, tech. rep., Civil Aviation Authority, Apr. 2010. [25] tech. rep. [26] D. Chamia, Design of an autonomous airship platform, tech. rep., University of Leeds, 2012. [27] J. Beaumont, Design of an autonomous airship platform, tech. rep., University of Leeds, 2012. [28] Mavlink micro air vehicle communication protocol, 04 2012. qgroundcontrol.org/mavlink/start.
http://
[29] Connecting to sparkfuns 9dof sensor stick: I2c access to adxl345, itg-3200, and hmc5843, 02 2012. http://chionophilous.wordpress.com/2012/02/10/
connecting-to-sparkfuns-9dof-sensor-stick-i2c-access-to-adxl345-itg-3200-and-hmc5843/.
[30] ADXL345 data sheet. [31] ITG-3200 data sheet. [32] HMC5843 data sheet. 32
Leo Rampen
Appendices
33
Leo Rampen
A.
The LabVIEW VIs included are the main ones written for the ight control system. The MasterControl.vi control system sits over 14 pages. 3 loops are within it. The top one checks that a heartbeat has been received within the last 5 seconds, and if it hasnt it puts the system into idle mode, shutting down propellers. If no heartbeat has been received within a reasonable period of time, it restarts the system. The second one is the comms loop. This loop runs continuously, listening for connection attempts over TCP. If made, the connection data is inspected for the command byte and the message is read to the relevent conguration variables or the data requested is returned to the groundstation. The third loop is the overall system state machine. This operates in 4 states. In startup, sensors are initialised and the conguration is read from a le stored onboard. In the ight state, the main control loops including those to read sensors, navigate and control the camera are run. If a shutdown signal is received, from either the heartbeat checker or the ground control station, the system enters the shut down state. Here motors are turned o, sensors are shut down and any conguration is saved. Saving the conguration allows waypoints and system conguration to persist over multiple resets and power loss conditions. This is a poor way to inspect LabVIEW virtual instruments. For the les involved, please contact the author at mn08lhsr@leeds.ac.uk or leorampen@gmail.com
34
Page 1
User Commanded Shutdown 00:00:00.000 DD/MM/YYYY Last Heartbeat Time If we haven't been contacted for 3 minutes (but the timestamp isn't 0) 180 Reset the RIO and load everything again (should fix any problems) True
100000
Restart (Self)
Comms In and Out - Receive commands from the groundstation and either respond with the data required, or store the data sent.
False
False
14 Shut down process: Set motors armed to 0 Initiate a connection Don't start if there's an error 5131 4 Read all byt es 1 2 3 If not landed, initiate main loop with "return to launch" as waypoint 0 0 1 2 Altitude K_I 0 1 2 Yaw K_P 0 1 2 Yaw K_D Yaw K_I 0 1 2 Altitude K_P Altitude K_D 0 1 2 Navigation K_I Navigation K_P Navigation K_D Read the first 4 bytes It'll say how many bytes in total are being sent 0 0 0 0 0 Reset All Feedback 4 5 6 Velocity K_I Velocity K_P Velocity K_D 0 1 2 Hover Altitude K_I 0 1 2 Hover Yaw K_I Hover Yaw K_P Hover Yaw K_D Hover Altitude K_P Hover Altitude K_D Pitch K_I Pitch K_P Pitch K_D ACK
Ensure aircraft landed (cut motors, see if falls? or ultrasonic rangefinder value (might not work at low heights).
status
"Run"
Orientation and Velocity Control Loop - 10 Hz System Mode High frequency loop IMU read and control feedback stuff only Flight Mode Wait Finished Late? [i-1] Altitude controller Desired Orientation TO DO LIST: Elevator and positive motor "force stealer" IMU: Fix yaw 3D correction Ensure axes are correct Constants for the IMU DCM feedback method 0 0 1 1 1 1 1 1 1 1 1 Simulation Desired Altitude GPS Altitude Rangefinder Altitude 0 0 0 0 0 Current R Matrix 0 Front Swivel Angle Add in altitude controller input Motor Thrust Desired Velocity GPS Velocity Rear Swivel Angle "Flight" If we're in hover mode, we need to maintain altitude FPGA VI Reference Out Rear Thrust
Mo
0 0
0 0 0
4 Hz General Loop 4 Hz Low frequency loop - read GPS Read at 4 Hz GPS Latitude
GPS Data
GPS Longitude
Convert from knots to m/s GPS Data Simulation watchdogID GPS Error GPS Altitude Tell the watchdog we're still alive Navigation, Command and Rangefinder Loop - 10 Hz Shut Down GPS Heading 0.51444 GPS Velocity
Simulation
"Waypoints"
Current Waypoint
Desired Velocity "Manual"
Still need
Desired Altitude
Viewpoint Source GS Commanded Viewpoint Current Viewpoint Viewpoint Array Current Viewpoint 0
4 5 6
GP
Current Waypoint
Viewpoint Source Current Viewpoint
Waypoint Array
Viewpoint Array 60 Camera Config Homepoint Shut Down
Page 2
Flash LED or power stuff off or whatever Need to power cycle to bring back on.
Comms Error
status
Rear Motor Setting Everything's finished, close up Shut Down Right Motor Setting Elevator Angle
Rudder Angle
Shut Down
Potential option is to check the required tail thrust, and if it's positive (ie down), then replace it with a moment balanced front Z thrust up. Another thing to have would be to check the velocity, and replace a force in the tail with a corresponding control surface force.
Shut Down
Page 3
"Wayp
Return heartbeat
"SEND-DATA" <name>LEEDS BLIMP</name><ms-count> 1 </ms-count><system-mode>
%s
System Mode </system-mode><command-mode>
%s
Control Command Mode </command-mode><flight-mode> Flight Mode
%s
</flight-mode>
"False", Default
COMMAND-UNKNOWN
Waypoint Array
0 0
Initia
Waypoint Array
Viewpoint Array
Camera Config
Write the camera config Homepoint 0 0 ACK Camera Config Shut Down
Load the co
Motors Armed
Current Waypoint
Viewpoint Source
Current Viewpoint
Read the configuration to variables 0 0 Motors Armed 0 1 2 3 4 Control Command Mode Simulation GS Commanded Viewpoint
Current Waypoint
Viewpoint Source GS Commanded Viewpoint
6 "Manual" Manual Control Commands 0 0 Write manual control commands if we're in manual control mode
ACK
Desired Orientation
Default
Page 4
Waypoint Array
0 0
"Land"
0 10
1 2 500 5 0
Define the flight mode Flight Mode Idle Motors Armed 0 1 2 3 4 Control Command Mode Flight Mode Move the control surfaces here, maybe? Start a watchdog. This is only in place when the mode is not "wait". If the VI crashes in any mode other than "wait", this'll reset the hardware. watchdogID
Current Waypoint
Viewpoint Source GS Commanded Viewpoint
Waypoint Array
Viewpoint Array
Camera Config
Page 5
0 0
0 0
Page 6
Contr
Cu
Turn off the watchdog watchdogID
Vie
GS Com
Page 7
Close the FPGA reference FPGA VI Reference Out FPGA Error Out Wait
Waypoint Array
Viewpoint Array Camera Config Homepoint
Page 8
If the command sent is 1, shut down and wait. Otherwise, run normally User Commanded Shutdown
ACK
ACK Homepoint
10
ACK
Simulation
11
ACK 0 0 IMURollPitchYaw
12
oldest read timestamp latitude (deg) 0 0 0 1 2 3 4 longitude (deg) ground speed (knots) true track angle (deg) altitude above mean sea level (m) GPS data
ACK
13
ACK
GPS Latitude GPS Longitude GPS Altitude GPS Velocity Rangefinder Altitude GPS Heading 20
Page 9
Wait
Shut Down
Start Up
Page 10
Current R Matrix 21
Left Motor Setting Right Motor Setting Rear Motor Setting Front Swivel Angle Rear Swivel Angle Elevator Angle Rudder Angle 22
24
24
Waypoint Array
25
25
Viewpoint Array
26
26
Current Waypoint
27
27
Camera Config
28
Motors Armed
Don't check current waypoint or viewpoint because they're subject to change by navigation
Page 11
True
True
Page 1
This VI takes two vectors. Each is generated by another VI between 2 GPS coordinates. Each vector has it's origin in the first position, with North as the reference point (3D North). The angle between the origin and the target (in both cases, the target is the target waypoint) is calculated. The error betweent the two is then multiplied by a proportional constant (currently 1). The resulting error is added onto the bearing to the target to get a new bearing requirement. The level to which the new bearing doesn't point towards the target is defined by the extent to which the aircraft isn't on track.
This VI takes two vectors. Each is generated by another VI between 2 GPS coordinates. Each vector has it's origin in the first position, with North as the reference point (3D North). The angle between the origin and the target (in both cases, the target is the target waypoint) is calculated. The error betweent the two is then multiplied by a proportional constant (currently 1). The resulting error is added onto the bearing to the target to get a new bearing requirement. The level to which the new bearing doesn't point towards the target is defined by the extent to which the aircraft isn't on track. Current Position Bearing to target from current position Yaw 0 1
Desired Position
Timestep
Navigation K_I
Navigation K_P
Navigation K_D
Page 1 CalculateYawPitch.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Control Loops\CalculateYawPitch.vi Last modified on 21/04/2012 at 19:37 Printed on 24/04/2012 at 16:43
CalculateYawPitch.vi
This VI computes yaw and pitch thrust values. Yaw is the thrust acting at the tail in the Y direction. Pitch is the thrust acting the tail in the Z direction. These are computed from the current IMU rotation matrix and the desired rotation matrix from navigation or manual control.
The output is a motor value, positive yaw means a thrust towards the right hand side (looking forward). Positive pitch mean thrust acting downwards. Standard aircraft axes are used, as defined in Leo Rampen's report.
Pitch K_I
Pitch K_P
Pitch K_D Tail Z Thrust
IMU R Matrix
Desired R Matrix
Tail Y Thrust
Timestep
Yaw K_I
Yaw K_P
Yaw K_D
Page 1 checkRangefinderi2c.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Rangefinder Interface\checkRangefinderi2c.vi Last modified on 19/04/2012 at 16:33 Printed on 24/04/2012 at 16:36
checkRangefinderi2c.vi
FPGA VI Reference In
Previous Range
Simulation
error in
This VI polls the i2c rangefinder, and outputs either the previous range (input it) or an updated range depending on whethe it's ready or not. Range in cm.
False Enabled Read the range registers Simulation If it's the first time, returns 0 If it's busy, returns 255 If it's got a range, returns range Read registers 2 and 3 If it's not 255, set the range is what's read. Wait 20 ms, and then tell it to get a new range. If it is 255, do nothing.
Previous Range
True
Range
0 FPGA VI Reference In 0 255 0 error in 2 pulse rangefinder 0 0 51 error out
Port
1
Bytes To Read
1 70
Page 1
Rear Motor
Rear Motor PWM FPGA VI Reference Out Right Motor PWM Left Motor PWM Swivel Servo PWM error out Rear Swivel Servo PWM
This VI writes to the FPGA the PWM values required to command the motors and swivel servos for the front and rear motors. It outputs the PWM values commanded (they have saturation points beyond which they won't increase, so it is useful to know the values). This needs to be modified to reflect each individual piece of hardware. Scale the thrust values, and then add the lowest PWM command to get the final output. Set the saturation values for the motors. Servos also need calibration.
False Motors Armed
FPGA VI Reference
Add
0
True
Left Motor PWM Right Motor PWM Front Swivel Angle Check with testing
True
Rear Motor
True
False
False
True
False
True
True
Page 1 FlightAltitudeController.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Control Loops\FlightAltitudeController.vi Last modified on 21/04/2012 at 19:37 Printed on 24/04/2012 at 16:47
FlightAltitudeController.vi
FPGA VI Reference Required Altitude Current GPS Altitude Current Rangefinder Altitude Timestep error in FPGA VI Reference Out Pitch Angle error out
This VI takes the required altitude, the current GPS altitude and the current rangefinder altitude and outputs a desired orientation in the pitch axis. If the rangefinder reads under 1 m, then the VI will maintain that height rather than descend.
Check rangefinder If we're away from the ground, hold based on GPS. If we're under 2m, hold based on rangefinder Check GPS altitude
If rangefinder < 1m, set 1 m as required altitude Else, set GPS as required altitude
FPGA VI Reference
Required Altitude
Tr
Current Rangefinder Altitude Saturation of +/- 0.25 rad (~30 deg) 2 Timestep
0.25
Pitch Angle
-0.25
Altitude K_I error in Altitude K_P error out Altitude K_D Fal Fal
Tr
Tr
Page 1
Motor Thrust
Motor Swivel Angle
This VI takes as an input the required X and Z forces for the front motors, and converts that to swivel angle and thrust. Differential thrust is currently not calculated, but could be in the future. Swivel angle is +/- pi, from horizontally forward.
Motor Thrust
Front Z Thrust
Resultant Thrust
Front X Thrust
Page 1
Required Altitude Current GPS Altitude Current Rangefinder Altitude Timestep FPGA VI Reference
error out
This VI takes the required altitude, the current GPS altitude and the current rangefinder altitude and gives two Z axis motor outputs (positive down). If the rangefinder reads under 1 m, then the VI will maintain that height rather than descend.
Check rangefinder Check GPS altitude
Else, set GPS as required altitude If we're away from the ground, hold based on GPS. If we're under 2m, hold based on rangefinder FPGA VI Reference FPGA VI Reference Out
Required Altitude
Tr Tail Z Thrust
Front Z Thrust
2
Timestep
error out
error in
Fals
Fal
Tru
Page 2
Page 1
FPGA VI Reference
Simulation
This VI gets the current GPS coordinates. It's designed to request data 6 times from the GPS, yielding all six commonly returned strings. The NMEA parser outputs the GPS data.
False Previous GPS data
FPGA VI Reference Out Return old GPS data if invalid. Iterate 6 times because that gets us all 6 returned strings
Simulation
6 FPGA VI Reference
GPS data
error in
Page 1 InitGPS.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\GPS Interface\InitGPS.vi Last modified on 19/04/2012 at 16:33 Printed on 24/04/2012 at 16:46
InitGPS.vi
This VI initiates the GPS. It first checks that NMEA strings are being received from the GPS. It then waits until the NMEA strings are making sense - ie a position has been found. WARNING: This VI *could* run indefinitely if there's no chance of a GPS fix. Consider that before using it.
True
GPS data
GPS data
error in
Simulation
False
Data is now valid Wait for GPS fix Wait for valid data
baud rate
9600
data bits
parity
None stop bits 1 bit
Page 1
InitIMUi2c.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\IMU Interface\InitIMUi2c.vi Last modified on 18/04/2012 at 13:16 Printed on 24/04/2012 at 16:57
InitIMUi2c.vi
FPGA VI Reference
Simulation
error in
This VI transfers data to and from the FPGA VI to send and receive bytes from an I2C port. It's hard coded for our "Sens Stick" IMU. Input - FPGA reference and error. Output - FPGA referance and error. Connect it in your init code, and use it' sister function (IMU read) to get data at control loop speed.
False
Disabled
Init gyro FPGA VI Reference Out Writing to register 16: binary 11011 (see notebook)
0 0 error in
2D 8
10110 11011
2 0 error out
100000
1E
68
Simulation
0 53
Enabled
True
Page 1 initRangefinderi2c.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Rangefinder Interface\initRangefinderi2c.vi Last modified on 18/04/2012 at 13:16 Printed on 24/04/2012 at 16:51
initRangefinderi2c.vi
This VI inits the SRF02 Ultrasonic Rangefinder device i2c bus. Call it once in init.
FPGA VI Reference
False Disabled Init Rangefinder i2c bus error in
error out
Simulation
400000
Enabled
True
Page 1 NavigationMain.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Navigation\NavigationMain.vi Last modified on 21/04/2012 at 19:35 Printed on 24/04/2012 at 16:38
NavigationMain.vi Holding Info Holding Info Out Flight Mode Desired Velocity
Current Waypoint
Timestep GPS data Homepoint
Desired Orientation
Waypoint Array
This VI conducts navigation algorithms.
It has three steps. Initially, it loads information from the waypoint array passed, and decides the target and previous coordinates. It then determines the flight mode based on the waypoint array. This is either hover, flight or land. If hover, the VI will maintain hover for the time described in the waypoint array.
Finally, depending on flight mode it produces control outputs - desired orientation (roll and pitch are 0), desired velocity an desired altitude.
See how far we are from the target waypoint GPS Coordinates Current Waypoint Array Target Coordinates Acceptance Radius These are where we want to go
Pass Through True 5 False
0 3 True
Acceptance Radius
We're not going to the homepoint
Land
Current Waypoint
Holding Waypoint Holdi
Holding Info
False Start Hold Time These are where we're coming from
Hover
Previous Coordinates
Holding Waypoint 0 3
Get previous waypoint for path following. If no previous defined, use homepoint
GPS Bearing
GPS Coordinates
GPS Alititude GPS Velocity
0.51444
False
False
False
"Land"
True
True
0 Desired velocity is 0
Desired Veloc
0 0
Desired Or
Desired orientation
Page 2 NavigationMain.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Navigation\NavigationMain.vi Last modified on 21/04/2012 at 19:35 Printed on 24/04/2012 at 16:38
"Flight", Default
hover timer and hover, or move on to t If we're to land, disregard everything else Previous Coordinates Target Coordinates GPS Coordinates
False 2 0 0
0 0 0 Flight Mode
Desired Altitude Calculate distance travelled, and scale the desired path vector by that to get an approximate altitude you should be at.
Desired Velocity
Forward Flight Speed Calculation Flight Mode Pass Through False Simple proportional forward flight speed
Desired Altitude
Saturated speed if true GPS Coordinates Target Coordinates Proportional constant 0.5
Desired Velocity
Minimum speed
Saturation speed
00:00:00.000 DD/MM/YYYY 0 Holding Info Out Start Hold Time Holding Waypoint
Saturation Speed
5
Page 3 NavigationMain.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Navigation\NavigationMain.vi Last modified on 21/04/2012 at 19:35 Printed on 24/04/2012 at 16:38
True
"Flight", Defa
We're in the acceptance radius. Either start the hover timer and hover, or move on to the next waypoint
False
Previous Coordinates
True Land False
Current Waypoint
Hold Time
Calculate distance travelled, and scale the desired path vector by that to get an approximate altitude you should be at.
Hover
Flight Mode
Forward Flight Speed Calculation False Simple proportional forward flight speed Pass Through
Saturation
Minimum s
False
Simple prop
Target Coordinates
False
Current Waypoint
Hold Time
Holding Waypoint
Holding Waypoint
Hover
Flight Mode
"Hover"
False
Flight
Flight Mode
Target Coordinates
2
Current Waypoint
Current Waypoint
Desired orientation
False
Current Waypoint
Holding Waypoint Holding Waypoint
Hover
Flight Mode
False
Holding Waypoint
Hover
Flight Mode
True True We're here because the current waypoint is being held on, but has passed it's hold time.
Current Waypoint
Current Waypoint
Page 4 NavigationMain.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Navigation\NavigationMain.vi Last modified on 21/04/2012 at 19:35 Printed on 24/04/2012 at 16:38
0 0
Desired Orientation
Desired Altitude
Desired Velocity
False
Saturation speed
True
Desired Altitude
Desired Velocity
Desired Orientation
Page 5 NavigationMain.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Navigation\NavigationMain.vi Last modified on 21/04/2012 at 19:35 Printed on 24/04/2012 at 16:38
False We're still hovering
Hover
Flight Mode
True We're here because the current waypoint is being held on, but has passed it's hold time.
Current Waypoint
Current Waypoint
True
Land
Flight Mode
Page 1
error out
Use this VI to convert a spreadsheet string into one suitable for transmission. The command integer specified is concatenated, and EoL characters are converted to ampersands for easier transmission and subsequent parsing.
Command Byte Command 4 bytes
String to Send
error out
&
Page 1 PID.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Control Loops\PID.vi Last modified on 21/04/2012 at 19:34 Printed on 24/04/2012 at 16:48
PID.vi K_D
K_I
Timestep (ms)
result
K_P
Setpoint
Current Value
This is a simple PID implementation. Give it a setpoint and current value, plus a bunch of gains, and it'll do the rest.
Current Value
Integrator
0 K_I
K_P
result
Proportional
Timestep (ms)
1000
K_D
Derivative
Page 1 ReadIMUi2c.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\IMU Interface\ReadIMUi2c.vi Last modified on 19/04/2012 at 16:33 Printed on 24/04/2012 at 16:23
ReadIMUi2c.vi error in Previous R Matrix
FPGA VI Reference
Simulation
FPGA VI Reference Out error out Gyro Correction Integral Term R Matrix
This VI reads the IMU. Addresses are hard coded. It takes the FPGA reference (opened and with the IMU inited already) and outputs the orientation of the IMU. Call it at whatever frequency you want to read the IMU.
Simulation
False
Enabled Previous Integral Term
Timestep
Gyroscope Raw
0 0 1 1 2
2 3 4 5
32
0
53
6
68
6
4 5
256
1E 6
Page 2 ReadIMUi2c.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\IMU Interface\ReadIMUi2c.vi Last modified on 19/04/2012 at 16:33 Printed on 24/04/2012 at 16:23
R Matrix
Gyro Correction
Timestep
Integral Term
120 -6
14.375
appended array
-20
Magnetometer
True
0 1 2 0
http://stackoverflow.com/questions/1251828/calculate-rotations-to-look-at-a-3d-point
error out
Page 1 ReceivedStringInitialParse.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Communications\ReceivedStringInitialParse.vi Last modified on 12/04/2012 at 10:45 Printed on 24/04/2012 at 16:52
ReceivedStringInitialParse.vi
Received String
error in (no error)
Received Data
Command Integer
error out
This VI takes received data strings and strips out the command byte. It also converts any ampersands to EOL characters. The returned string can be put straight into the spreadsheet string to array function.
Received Data
Received String
&
Command Integer
0
error in (no error)
error out
Page 1 TailAngleCalculator.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\cRIO-ReadIMU\Control Loops\TailAngleCalculator.vi Last modified on 11/04/2012 at 16:49 Printed on 24/04/2012 at 16:56
TailAngleCalculator.vi
Tail Y Thrust Tail Z Thrust
This VI takes required Y and Z thrusts for the tail and converts them into a positive thrust value and a swivel angle. Swivel angle is defined as +/- pi, where 0 is vertically upwards (although the Z axis acts downwards, the motor spends most of it's time providing an upwards thrust).
Tail Z Thrust Tail Thrust
Resultant Thrust
Page 1
Front X Thrust
Timestep
Velocity K_D
Leo Rampen
B.
A test interface for communicating with the aircraft and control system was developed. Demonstrated in the following pages is its front and back end. The mapping interface is described further in Section 4.2.
70
Page 1 Temp-GSFrontend.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\GS-Comms\Temp-GSFrontend.vi Last modified on 20/04/2012 at 18:11 Printed on 24/04/2012 at 22:26
Temp-GSFrontend.vi
LoadWPData
5 6
Map Interface This is a rudimentary interface to the Leeds Blimp. It's designed to let you send and receive relevant data. Use it for a better groundstation. Blimp Current Waypoint
0
Latitude
0
GPS Velocity
0 GPS Headi ng 0
Longitude
0
GPS Altitude
0
Rangefinder Altitude
0
Elevator Angle
0
Rudder Angle
0
R Matrix (Orientation)
0 0 0 0 0 0 0 0 0 0 0
Blimp Address
Simulation Enabled
192.168.0.2
Heartbeat Received
Shut Down Blimp
point 0,0 is the "reset all feedback nodes" value. Set it to 1 for a little while to set them all to 0. PID Constants Last Heartbeat Time
00:00:00.000 D D /MM/YYYY 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Heartbeat String
0 0 0 0
Order is: K_I, K_P, K_D Velocity Altitude Yaw Pitch Hover Altitude Hover Yaw
We're getting data claiming to be a heartbeat, but it's not got the right text in it! Nonsense Heartbeat Received
Data GS to Blimp
Data Blimp to GS
Aircraft Config
0
source
0 0 0 0 0
status
code
0
source
0 0 0 0 0 0 0
Waypoint Array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Page 2 Temp-GSFrontend.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\GS-Comms\Temp-GSFrontend.vi Last modified on 20/04/2012 at 18:11 Printed on 24/04/2012 at 22:26
Homepoi nt 0 0 0 0 0 0 0 0
Page 3 Temp-GSFrontend.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\GS-Comms\Temp-GSFrontend.vi Last modified on 20/04/2012 at 18:11 Printed on 24/04/2012 at 22:26
Doesn't actually do anything yet
Shut Down Position information from the blimp Blimp orientation Blimp Heartbeat
Latitude
Current vehicle command state Left Motor Setting Front Swivel Angle Elevator Angle
Longitude
Heartbeat Received
Rear Motor Setting
IWebBrowser2
Refresh
Busy
N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\Software\Waypoint Mapping\MapServer latitude= Latitude longitude= Longitude altitude= GPS Altitude
&
http://localhost:5000/map/
Comms In and Out - Send data to TCP server on blimp, receive data back and queue it.
5131
Blimp Address
Shut Down
Parse Received Data - Initiate replies Parse data received and copy it into the right variables
100
Blimp to GS
Data Blimp to GS
True
21
Data GS to Blimp
100
GS to Blimp
0 1 2 R Matrix (Orientation)
Heartbeat Checker
If a heartbeat was received in the last 3 seconds, set to true. Otherwise, set to false.
False
Heartbeat Received
GS to Blimp
SEND-DATA
Shut Down
Send Config and Control Data If the waypoint array indicator has changed, and there's a connection to the blimp, add the new array to the queue.
Waypoint Array
if there's no heartbeat received, don't change the shift register (ie the change will be persistently registered until data sent).
True GS to Blimp
Heartbeat Received
Viewpoint Array
True GS to Blimp
Page 4 Temp-GSFrontend.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\GS-Comms\Temp-GSFrontend.vi Last modified on 20/04/2012 at 18:11 Printed on 24/04/2012 at 22:26
IHTML2Document
IWebBrowser2
Document IHTMLDocument2 IHTMLElement innerHTML \s
body
Waypoint Array
Map Errors
save-bli
Shut Down
Page 5 Temp-GSFrontend.vi N:\Faculty-of-Engineering\Mech-Eng\Learning+Teaching\UG-Projects-11-12\Level 4\airship_platform\ Software\FPGA IO\GS-Comms\Temp-GSFrontend.vi Last modified on 20/04/2012 at 18:11 Printed on 24/04/2012 at 22:27
3
Camera Config
GS to Blimp
True
True GS to Blimp
Aircraft Config
5
False
Homepoint
True GS to Blimp
True GS to Blimp
Shut Down
10
Heartbeat Received
20
Shut Down
Heartbeat Received
22
True GS to Blimp
24
Heartbeat Received
25
27
28
Shut Down
Heartbeat Received
Simulation Enabled
11
12
13
GPS Data
Rangefinder Altitude
Heartbeat Received
Simulation Enabled
14
PID Constants
Leo Rampen
C.
76
22/04/12 01:10
W:\TempWithoutM\PlotTrajectory.m
1 of 3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This is: PlotTrajectory.m % % Also Required: arrows.m % % - - - - - - - - - - - - - - - - - - - - - - - % % Author : LEO RAMPEN % % This file simulates the navigation system % % of the Leeds Blimp. It prints to a graph % % approximate paths based on the PID values % % and entered wind speed. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all; clc; hold off; %Define the past and target waypoints PastLocation = [40,100]; TargetLocation = [160, 100]; %Plot a line between the two plotPoint1 = [PastLocation(1), TargetLocation(1)]; plotPoint2 = [PastLocation(2), TargetLocation(2)]; plot(plotPoint1, plotPoint2) axis([0 200 0 200]); %Set the axis scale hold on; %Plot markers for the target and past waypoints plot(PastLocation(1), PastLocation(2), 'Marker','p','Color','red', 'MarkerSize',15); plot(TargetLocation(1), TargetLocation(2), 'Marker','*','Color','green', 'MarkerSize', 20); %Define our wind speed WindSpeed = 6; %in pixels/step WindDirection = [0, 10]; %A 2D vector %Calculate the direction vector for the stated wind Wind = (WindDirection/norm(WindDirection)) * WindSpeed if (WindSpeed > 0) %Plot our wind on the graph ArrowTip = [120, 50]; ArrowBase = ArrowTip - (10*Wind); arrow(ArrowBase, ArrowTip); end %Define our aircraft disp('1 for past location, 2 for random'); %StartPosInput = input('Where do you want to start?'); StartPosInput =1; switch StartPosInput case 1 StartingPosition = PastLocation; case 2 posX = round(rand(1)*200);
22/04/12 01:10
W:\TempWithoutM\PlotTrajectory.m
2 of 3
posY = round(rand(1)*200); StartingPosition = [posX, posY]; end AircraftSpeed = 5 %in pixels/step AircraftPosition = StartingPosition; %Set the initial aircraft position PathBearing = atan2((TargetLocation(2) - PastLocation(2)), (TargetLocation(1) PastLocation(1))); %The bearing of the path we're following if (PathBearing < 0) PathBearing = PathBearing + 2*3.141596; end
%Plot the aircraft's initial position plot(AircraftPosition(1), AircraftPosition(2), 'Marker','d','Color','black','MarkerSize',5); dist = sqrt((AircraftPosition(1) - TargetLocation(1))^2 + (AircraftPosition(2) TargetLocation(2))^2); %Calculate the distance to the target %Control loop constants K_I = 0; K_P = 3; K_D = 0; %Calculate bearing to target BearingToTarget = atan2((TargetLocation(2) - AircraftPosition(2)), ( TargetLocation(1) - AircraftPosition(1))); if (BearingToTarget < 0) BearingToTarget = BearingToTarget + 2*3.141596; end %Calculate the initial bearing error BearingError = BearingToTarget - PathBearing; PrevBearingError = BearingError; %Initialise bearing IntegralBearing = BearingToTarget;
i = 0; while (dist > 15) && (i < 80) %Compute the distance to the target dist = sqrt((AircraftPosition(1) - TargetLocation(1))^2 + (AircraftPosition(2) TargetLocation(2))^2); %Calculate the distance to the target %Compute the bearing to the target BearingToTarget = atan2((TargetLocation(2) - AircraftPosition(2)), ( TargetLocation (1) - AircraftPosition(1))); if (BearingToTarget < 0) BearingToTarget = BearingToTarget + 2*3.141596; end %Control loops. Get the error BearingError = BearingToTarget - PathBearing; %Very simple integral control IntegralBearing = IntegralBearing + (BearingError * K_I);
22/04/12 01:10
W:\TempWithoutM\PlotTrajectory.m
3 of 3
%And proportional ProportionalBearing = K_P * BearingError; %And differential DifferentialBearing = K_D * (BearingError - PrevBearingError); PrevBearingError = BearingError; %Total bearing AircraftBearing = IntegralBearing + ProportionalBearing + DifferentialBearing; %Compute X and Y values for velocity VelocityAdjustment = [((AircraftSpeed) * cos(AircraftBearing)), ((AircraftSpeed) * sin(AircraftBearing))]; %Compute new aircraft position AircraftPosition = AircraftPosition + VelocityAdjustment + Wind; %plot our new position plot(AircraftPosition(1), AircraftPosition(2), 'Marker','diamond','Color','black', 'MarkerSize',5); pause(0.1); i = i + 1; end
Leo Rampen
D.
80
24/04/12 22:15
hold off clear all
M:\MATLAB\IMU\PlotIMU.m
1 of 4
FileToLoad = 'IMUDataSlowRotate.txt'; F = csvread(FileToLoad); Acc(:,1) = F(:,1); Acc(:,2) = F(:,2); Acc(:,3) = F(:,3); Magn(:,2) = F(:,4); %magnetometer X and Y swapped on the board. Magn(:,1) = F(:,5); Magn(:,3) = F(:,6); Gyro(:,1) = F(:,7); Gyro(:,2) = F(:,8); Gyro(:,3) = F(:,9); %Define the timestep dt = 0.05; %seconds %Correct the accelerometer Acc = Acc/256; %Correct the gyro %Gyro = Gyro + Gyro_Correction; %GyroOffset = sum(Gyro)/size(Gyro, 1); %These came out as: -117.962, 5.268 and 20.781 Gyro(:,1) = Gyro(:,1) + 117.962; Gyro(:,2) = Gyro(:,2) - 5.268; Gyro(:,3) = Gyro(:,3) - 20.781; Gyro = Gyro/14.375; Gyro = (Gyro*2*pi())/360; %Correct the magnetometer %do simple integration R_gyro = eye(3); R = eye(3) i=2; % %rotation matrix - just integration % while (i<=size(F, 1)) % %Integrate gyro readings % d_theta_x = Gyro(i,1)*dt; % d_theta_y = Gyro(i,2)*dt; % d_theta_z = Gyro(i,3)*dt; % %build a matrix for this step % R_gyro_step = [1, (-d_theta_z), d_theta_y; d_theta_z, 1, (-d_theta_x); (d_theta_y), d_theta_x, 1]; % %Total rotation % R_gyro = R_gyro*R_gyro_step; % i = i+1; % end %Simple integration method
24/04/12 22:15
M:\MATLAB\IMU\PlotIMU.m
2 of 4
i = 2 integ_orientation = [0 0 0]; while (i<= size(F,1)) %integrate and store integ_orientation(i,1) = Gyro(i,1)*dt + integ_orientation(i-1,1); integ_orientation(i,2) = Gyro(i,2)*dt + integ_orientation(i-1,2); integ_orientation(i,3) = Gyro(i,3)*dt + integ_orientation(i-1,3); if (integ_orientation(i,1) < -pi()) integ_orientation(i,1) = integ_orientation(i,1) + 2*pi(); elseif (integ_orientation(i,1) > pi()) integ_orientation(i,1) = integ_orientation(i,1) - 2*pi(); end if (integ_orientation(i,2) < -pi()) integ_orientation(i,2) = integ_orientation(i,2) + 2*pi(); elseif (integ_orientation(i,2) > pi()) integ_orientation(i,2) = integ_orientation(i,2) - 2*pi(); end if (integ_orientation(i,3) < -pi()) integ_orientation(i,3) = integ_orientation(i,3) + 2*pi(); elseif (integ_orientation(i,3) > pi()) integ_orientation(i,3) = integ_orientation(i,3) - 2*pi(); end i = i+1; end i=2; Gyro_Correction = zeros(3); correct_orientation(1, :) = [0 0 0]; I_Correction = 0; %Full DCM method % while(i<=size(F,1)) %Integrate gyro readings and add on corrections %Equation 17 d_theta_x = Gyro(i,1)*dt - Gyro_Correction(1); d_theta_y = Gyro(i,2)*dt - Gyro_Correction(2); d_theta_z = Gyro(i,3)*dt - Gyro_Correction(3); %build a matrix for this step R_gyro_step = [1, (-d_theta_z), d_theta_y; d_theta_z, 1, (-d_theta_x); (d_theta_y), d_theta_x, 1]; %Total rotation R = (R*R_gyro_step); %%%%%%%%%%%%%%%%% %Renormalisation% %%%%%%%%%%%%%%%%% %Equations 18, 19 20 and 21 error = dot(R(1,:),R(2,:)'); X_orth = R(1,:)' - ((error/2)*R(2,:)'); Y_orth = R(2,:)' - ((error/2)*R(1,:)'); Z_orth = cross(X_orth,Y_orth);
24/04/12 22:15
M:\MATLAB\IMU\PlotIMU.m
3 of 4
X_orth = X_orth/norm(X_orth); Y_orth = Y_orth/norm(Y_orth); Z_orth = Z_orth/norm(Z_orth); R(1,:) = X_orth; R(2,:) = Y_orth; R(3,:) = Z_orth; %%%%%%%%%%%%%%%%%%%% %Drift cancellation% %%%%%%%%%%%%%%%%%%%% %Magnetometer bearing %This is from http://code.google.com/p/ardu-imu/source/browse/branches/ArduIMU% 20v1.7/Compass.pde cos_roll = cos(integ_orientation(i,1)); sin_roll = sin(integ_orientation(i,1)); cos_pitch = cos(integ_orientation(i,2)); sin_pitch = sin(integ_orientation(i,2)); %tilt compensated X Magn_X = Magn(i,1)*cos_pitch + Magn(i,2)*sin_roll*sin_pitch + Magn(i,3) *cos_roll*sin_pitch; %Tilt compensated Y Magn_Y = Magn(i,2)*cos_roll-Magn(i,3)*sin_roll; Magn_Bearing = -atan2(-Magn_Y,Magn_X); COGX = cos(Magn_Bearing); COGY = sin(Magn_Bearing); % O_to_N = norm(Magn(i,:)); O_to_Axis = norm([Magn(i,1),Magn(i,3)]); Magn_Bearing = asin(O_to_Axis/O_to_N); %Our global frame bearing BearingCapture(i) = Magn_Bearing; Magn_X = O_to_Axis/O_to_N; Magn_Y = Magn(i,2)/O_to_N; %Yaw correction in the global frame %Equations 23 and 24 Yaw_Correction = R(1,1)*COGY - R(2,1)*COGX; Yaw_Correction = Yaw_Correction*R(3,:)'; %Skip the centrifugal stuff because we have no velocity %Equation 27 RollPitch_Correction = cross(R(3,:)',Acc(i,:)'); %%%%%%%%%%%%%%%%%%%%% %Feedback controller% %%%%%%%%%%%%%%%%%%%%% W_RP = 0.1; W_Y = 0.3; K_P = 1; K_I = 1;%2,5 Total_Correction = W_RP*RollPitch_Correction + W_Y*Yaw_Correction; P_Correction = K_P*Total_Correction; I_Correction = I_Correction + K_I*dt*Total_Correction;
% % % %
24/04/12 22:15
M:\MATLAB\IMU\PlotIMU.m
4 of 4
Gyro_Correction = P_Correction + I_Correction; %Look at rotation around X correct_orientation(i,1) = %Around Y - the pitch axis correct_orientation(i,2) = %Around Z - the yaw axis correct_orientation(i,3) = the roll axis. asin(dot(R(3,:),R(:,1)')); asin(dot(R(3,:),R(:,2)')); -asin(dot([R(1,1),R(2,1),0],[0, 1, 0]));
% % % % %
%Try something else %roll correct_orientation(i,1) = atan2(R(3,2),R(3,3)); %pitch correct_orientation(i,2) = -asin(R(3,1)); %yaw correct_orientation(i,3) = atan2(R(2,1),R(1,1)); i = i+1; end p = plot(correct_orientation(:,1),'Color','red') xlabel('Timestep (0.05 seconds)') ylabel('Orientation (rad)') hold on fixed_int_orient = integ_orientation; plot(fixed_int_orient(:,1)) %plot(BearingCapture(:), 'color', 'green')
Leo Rampen
E.
The three boards designed are shown below, and their circuit schematics follow.
85
Leo Rampen
Figure E.0.1: The breakout board PCB design for the GS1011 wireless module.
Figure E.0.2: The design for a stripboard based IO pin breakout board for the sensors. 86
1 2 3 4
1 2 3 4
11 10 9 8 7 6 5 4 3 2 1
1 2 3 4
1 2
1 2
1 2
1 2 3
1 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 2 3 4 5 6 7
1 2 3 4 5 6
Leo Rampen
Figure E.0.3: The design of the stripboard based servo breakout board.
90
Leo Rampen
F.
The interactive waypoint selection map is designed to run on the groundstation. The current implementation uses a LabVIEW internet control as can be seen in the rst images. The code is launched by a BAT le which runs the ServeMaps.py web server. This acts as a gateway between LabVIEW and the Javascript and HTML based mapping interface.
91
##################################################### # This is a web server using the Bottle framework # # It is designed to store and communicate waypoint # # information for the Leeds Blimp. # # Data is stored in SQLite. The JS map interacts # # through a POST based API and a JSON interface. # # See the corresponding map.tpl for the javscript. # ##################################################### import sqlite3 from bottle import get, post, request, route, run, template, static_file import time @route('/map') @route('/map/') def index(): return template('map') @route('/static/<filepath:path>') def server_static(filepath): return static_file(filepath, root= 'N:/Faculty-of-Engineering/Mech-Eng/Learning+Teaching/UG-Projects-11-12/Level 4/airship_platform/Software/Waypoint Mapping/MapServer/static') @post('/map/post') def save_waypoints(): conn = sqlite3.connect('blimp-data.db') conn.execute("create table if not exists waypoints (id INTEGER PRIMARY KEY, wporder INTEGER NOT NULL, latitude real NOT NULL, longitude real NOT NULL, altitude REAL NOT NULL, hover REAL NOT NULL, acceptance REAL NOT NULL, yaw REAL NOT NULL, viewpoint INTEGER NOT NULL, passthrough integer NOT NULL, launchpoint integer NOT NULL, land integer NOT NULL)") new_save = request.forms.get('new_save','') if new_save == "1": conn.execute("DELETE FROM waypoints") c = conn.cursor() wporder = request.forms.get('order','').strip() latitude = request.forms.get('latitude','').strip() longitude = request.forms.get('longitude','').strip() altitude = request.forms.get('altitude','').strip() hover = request.forms.get('hover','').strip() acceptance = request.forms.get('acceptance','').strip() yaw = request.forms.get('yaw','').strip() viewpoint = request.forms.get('viewpoint','').strip() passthrough = request.forms.get('passthrough','').strip() launchpoint = request.forms.get('launchpoint','').strip() land = request.forms.get('land','').strip() c.execute("INSERT INTO waypoints (wporder, latitude, longitude, altitude, hover, acceptance, yaw, viewpoint, passthrough, launchpoint, land) VALUES (?,?,?,?,?,?,?,?,?,?,?)",(wporder, latitude, longitude, altitude, hover, acceptance, yaw, viewpoint, passthrough, launchpoint, land)) conn.commit() c.close() return {'saved':'true'} @route('/map/wp-labview')
-1-
def return_labview_waypoints(): conn = sqlite3.connect('blimp-data.db') c = conn.cursor() c.execute("SELECT * FROM waypoints ORDER BY wporder ASC") all_waypoints_fetched = c.fetchall() c.close() all_waypoints = all_waypoints_fetched[:-1] #remove the last, empty part spreadsheet_string = "" for waypoint in all_waypoints: for column in waypoint[2:]: if str(column) == "true": column = 1 if str(column) == "false": column = 0 spreadsheet_string += str(column) + "\t" spreadsheet_string = spreadsheet_string[:-1] #remove the last tab spreadsheet_string += "*" return spreadsheet_string @post('/map/save-blimp-loc') def load_labview_data(): conn = sqlite3.connect('blimp-data.db') conn.execute("create table if not exists blimp (id INTEGER PRIMARY KEY, timestored INTEGER NOT NULL, latitude REAL NOT NULL, longitude real NOT NULL, altitude real NOT NULL)") blimp_latitude = request.forms.get('latitude','').strip() blimp_longitude = request.forms.get('longitude','').strip() blimp_altitude = request.forms.get('altitude','').strip() current_time = time.time() c = conn.cursor() c.execute("INSERT INTO blimp (timestored, latitude, longitude, altitude) VALUES (?,?,?,?)",(current_time, blimp_latitude, blimp_longitude, blimp_altitude)) conn.commit() c.close() return {'saved':'true'} @get('/map/blimp-loc') def get_blimp_location(): conn = sqlite3.connect('blimp-data.db') c = conn.cursor() c.execute("SELECT * FROM blimp ORDER BY timestored DESC LIMIT 20;") latest_blimp_location= c.fetchall() c.close() return_dict = {} i = 0 for location in latest_blimp_location: location_dict = { 'latitude' : location[2], 'longitude' : location[3], 'altitude' : location[4] } return_dict[i] = location_dict i += 1 return return_dict
-2-
@route('/map/wp-json') def return_json_waypoints(): conn = sqlite3.connect('blimp-data.db') c = conn.cursor() c.execute("SELECT * FROM waypoints ORDER BY wporder ASC") all_waypoints_fetched = c.fetchall() c.close() all_waypoints = all_waypoints_fetched[:-1] #remove the last, empty part json_return = {} json_return['total'] = len(all_waypoints) #tell the reader the total number of waypoints for i in range(0,len(all_waypoints)): waypoint_name = "wp-" + str(i) #build a dict for this waypoint waypoint_dict = { 'latitude' : all_waypoints[i][2], 'longitude' : all_waypoints[i][3], 'altitude' : all_waypoints[i][4], 'hover' : all_waypoints[i][5], 'acceptance' : all_waypoints[i][6], 'yaw' : all_waypoints[i][7], 'viewpoint' : all_waypoints[i][8], 'passthrough' : all_waypoints[i][9], 'launchpoint' : all_waypoints[i][10], 'land' : all_waypoints[i][11]}
-3-
/* This is a javascript map configuration file for the Leeds Blimp It defines the map used, makes markers on click events, lets you define the markers, stores marker data and uploads it to the server (ServeMaps.py). It also loads the waypoints off the server and prints a little blimp where the blimp is. Fun! File by Leo Rampen, 2012 */ //make the map! var map = new L.Map('map'); var cloudmade = new L.TileLayer( 'http://{s}.tile.cloudmade.com/aab6906c5c674866b4ffe070cb508b43/997/256/{z}/{x}/{y}.png', { attribution: 'tim', maxZoom: 18 }); var leeds = new L.LatLng(53.8081524683, -1.55937194824); // geographical point (longitude and latitude) map.setView(leeds, 16).addLayer(cloudmade);
//declare some waypoint management variables var markers = new Array(); var marker_counter = 0; var all_waypoint_data = new Array(); var waypoint_order = new Array(); var polyline = new L.Polyline(leeds, {color: 'red'}); var blimpline = new L.Polyline(leeds, {color: 'blue'}); //make an icon var blimpIcon = new L.Icon(); blimpIcon.iconUrl = '/static/blimp.gif'; blimpIcon.iconSize = new L.Point(43, 23); blimpIcon.iconAnchor = new L.Point(21, 18); blimpIcon.popupAnchor = new L.Point(-2, 0); //create the blimp icon var blimp_marker = new L.Marker(leeds, {icon: blimpIcon}); //new marker from blimp location var checkBlimpLocation = setInterval(getBlimpLocation, 5000); loadPreviousWaypoints() //get the previous waypoints map.on ('click', function(e) { var marker_id = marker_counter; //unique marker ID var waypoint_data = new Array(); //to store the waypoint data waypoint_data["order"] = (waypoint_order.length); //set the order as last waypoint_order[(waypoint_order.length)] = marker_id; //Set the last waypoint as the one we just created. waypoint_data["latitude"] = e.latlng['lat']; //store lat and long waypoint_data["longitude"] = e.latlng['lng'];
-1-
//keep zeroed until defined. waypoint_data["altitude"] = '0'; waypoint_data["hover"] = '0'; waypoint_data["acceptance"] = '5'; waypoint_data["yaw"] = '0'; waypoint_data["viewpoint"] = '0'; waypoint_data["passthrough"] = false; waypoint_data["launchpoint"] = false; waypoint_data["land"] = false; modifyMarker(waypoint_data, marker_id, true); marker_counter ++; });
function removeMarker(marker_id) { map.removeLayer(markers[marker_id]); var order_index = include(waypoint_order, marker_id); if ( typeof order_index !== "undefined" ) waypoint_order.splice(order_index, 1); updateAllMarkers() } function clearAllWaypoints() { for (var i = 0; i < waypoint_order.length; i++) { map.removeLayer(markers[waypoint_order[i]]); } all_waypoint_data.length = 0; waypoint_order.length = 0; updateAllMarkers(); } function getBlimpLocation() { var url = "/map/blimp-loc?_=" + new Date().getTime(); $.ajax({ cache: false, success: function(data){ var blimp_location = new Array(); var past_locations = new Array(); blimp_location['latitude'] = data['0'].latitude; blimp_location['longitude'] =data['0'].longitude; blimp_location['altitude'] = data['0'].altitude; var new_lat_long = new L.LatLng(blimp_location.latitude, blimp_location.longitude ); map.removeLayer(blimp_marker); blimp_marker = new L.Marker(new_lat_long, {icon: blimpIcon}); //new marker from blimp location map.addLayer(blimp_marker); //add it to the map //draw the line if there's more than 1 marker. map.removeLayer(blimpline); for (var c = 0; c<20;c++) { if (typeof data[c] !== "undefined") {
-2-
if (data[c].latitude !== "") { past_locations.push(new L.LatLng(data[c].latitude, data[c].longitude )); //store the lat/long of each marker } } } blimpline = new L.Polyline(past_locations, {color: 'blue'}); map.addLayer(blimpline); }, url: url}); }
function loadPreviousWaypoints() { var url = "/map/wp-json?_=" + new Date().getTime(); $.ajax({ cache: false, success: function(data){ clearAllWaypoints(); //remove any old waypoints var wp_length = data.total; //get the number to load for (var i = 0; i < wp_length; i++) { var wp_id = "wp-" + i; var marker_id = i; //unique marker ID var waypoint_data = new Array(); //to store the waypoint data var order = marker_id; waypoint_data["order"] = order; //set the order as last waypoint_order[order] = marker_id; //Set the last waypoint as the one we just created. waypoint_data["latitude"] = data[wp_id].latitude; //store lat and long waypoint_data["longitude"] = data[wp_id].longitude; //keep zeroed until defined. waypoint_data["altitude"] = data[wp_id].altitude; waypoint_data["hover"] = data[wp_id].hover; waypoint_data["acceptance"] = data[wp_id].acceptance; waypoint_data["yaw"] = Math.round(data[wp_id].yaw * 57.2957795*1000)/ 1000; //convert back to degrees waypoint_data["viewpoint"] = data[wp_id].viewpoint; waypoint_data["passthrough"] = data[wp_id].passthrough; waypoint_data["launchpoint"] = data[wp_id].passthrough; waypoint_data["land"] = data[wp_id].passthrough; modifyMarker(waypoint_data, marker_id, true); }}, url: url }); } function updateFormData(marker_id) { var waypoint_data = new Array(); //store the waypoint data waypoint_data = all_waypoint_data[marker_id]; //get the existing data (in case the new data is undefined
-3-
//get the data from the form when the user clicks "save" waypoint_data["order"] = (document.getElementById('order').value == "") ? '0' : document. getElementById('order').value; //record the new waypoint position waypoint_data["altitude"] = (document.getElementById('altitude').value == "") ? '0' : document.getElementById('altitude').value; waypoint_data["hover"] = (document.getElementById('hover').value == "") ? '0' : document. getElementById('hover').value; waypoint_data["acceptance"] = (document.getElementById('acceptance').value == "") ? '0' : document.getElementById('acceptance').value; waypoint_data["yaw"] = (document.getElementById('yaw').value == "") ? '0' : document. getElementById('yaw').value; waypoint_data["viewpoint"] = (document.getElementById('viewpoint').value == "") ? '0' : document.getElementById('viewpoint').value; waypoint_data["passthrough"] = document.getElementById('passthrough').checked; waypoint_data["launchpoint"] = document.getElementById('launchpoint').checked; waypoint_data["land"] = document.getElementById('land').checked; modifyMarker(waypoint_data, marker_id, false); } function modifyMarker(waypoint_data_array, marker_id, newMarker) { all_waypoint_data[marker_id] = waypoint_data_array; //Set the global waypoint data variable to the data being passed if (newMarker) { var new_lat_long = new L.LatLng(waypoint_data_array["latitude"],waypoint_data_array[ "longitude"]) //the latitude and longitude of the marker markers[marker_id] = new L.Marker(new_lat_long); //new marker from the click event map.addLayer(markers[marker_id]); //add it to the map } //if there's more than one marker and the order has changed, *or* it's a new marker, reshuffle the order array var order_index = include(waypoint_order, marker_id); //find the marker's location if (markers.length > 1 && (waypoint_data_array.order !== order_index || newMarker) ) { waypoint_order.splice(order_index, 1); // remove the marker from the old position waypoint_order.splice(waypoint_data_array.order, 0, marker_id); //add the marker into the order array } updateAllMarkers() } function updateAllMarkers() { var update_order_popup_form = new Array(); //an array to hold popup form data var path_latlngs = new Array(); //iterate over each marker in order, updating the popup for it for (var i = 0; i < waypoint_order.length; i++) { //set the new order in the main waypoint array all_waypoint_data[waypoint_order[i]].order = i; //update the popup html with the new order (and anything else) update_order_popup_form[0] = "<form name='waypoint_settings' id='waypoint_settings_frm' action='#'>Waypoint Order: <input type='text' id='order'
-4-
size='4' value='" + all_waypoint_data[waypoint_order[i]].order + "'/><br />"; update_order_popup_form[1] = "Altitude: <input type='text' id='altitude' size='4' value='" + ( typeof all_waypoint_data[waypoint_order[i]].altitude !== "undefined" ? all_waypoint_data[waypoint_order[i]].altitude : "" ) + "'/><br />Hold Time: <input type='text' id='hover' size='4' value='" + ( typeof all_waypoint_data[waypoint_order[ i]].hover !== "undefined" ? all_waypoint_data[waypoint_order[i]].hover : "" ) + "' /><br />"; update_order_popup_form[2] = "Acceptance Radius: <input type='text' id='acceptance' size='4' value='" + ( typeof all_waypoint_data[waypoint_order[i]].acceptance !== "undefined" ? all_waypoint_data[waypoint_order[i]].acceptance : "" ) + "' /><br />Yaw Angle (Degrees): <input type='text' id='yaw' size='4' value='" + ( typeof all_waypoint_data[waypoint_order[i]].yaw !== "undefined" ? all_waypoint_data[ waypoint_order[i]].yaw : "" ) + "' /><br />"; update_order_popup_form[3] = "Camera Viewpoint: <input type='text' id='viewpoint' size='4' value='" + ( typeof all_waypoint_data[waypoint_order[i]].viewpoint !== "undefined" ? all_waypoint_data[waypoint_order[i]].viewpoint : "" ) + "' /><br />Pass Through: <input type='checkbox' id='passthrough' size='4' " + ( all_waypoint_data[waypoint_order[i]].passthrough == true ? "checked" : "" ) + " /><br />"; update_order_popup_form[4] = "Return to Launch Point: <input type='checkbox' id='launchpoint' size='4' " + ( all_waypoint_data[waypoint_order[i]].launchpoint == true ? "checked" : "" ) + " /><br />Land at Coordinates: <input type='checkbox' id='land' size='4' " + ( all_waypoint_data[waypoint_order[i]].land == true ? "checked" : "" ) + " /><br /></form>"; markers[waypoint_order[i]].bindPopup("Marker ID: " + waypoint_order[i] +"<p>" + update_order_popup_form.join("") + "</p><a href='javascript:updateFormData(" + waypoint_order[i] + ")'>Update</a> - <a href='javascript:removeMarker(" + waypoint_order[i] + ")'>Delete</a>").closePopup(); path_latlngs[i] = markers[waypoint_order[i]].getLatLng(); each marker } //draw the line if there's more than 1 marker. map.removeLayer(polyline); if (markers.length > 1) { polyline = new L.Polyline(path_latlngs, {color: 'red'}); map.addLayer(polyline); } //update the list of markers var wp_list_interface = new Array(); var list_contents = new Array(); for (var i = 0; i < waypoint_order.length; i++) { var wp = all_waypoint_data[waypoint_order[i]]; list_contents[0] = "Alt: " + wp.altitude + " m, "; list_contents[1] = (parseInt(wp.hover) > 0) ? ("Hover: " + wp.hover + " s, Yaw: " + wp.yaw + " deg, ") : (""); list_contents[2] = "Accept Radius: " + wp.acceptance + " m, "; list_contents[3] = "Viewpoint: " + wp.viewpoint + " "; list_contents[4] = (wp.passthrough == true) ? "+Pass Through " : ""; list_contents[5] = (wp.launchpoint == true) ? "+Return to Launch Point " : ""; list_contents[6] = (wp.land == true) ? "+Land " : ""; list_contents[7] = "<br />[<a href='javascript:openPopup("+waypoint_order[i]+ ")'>open</a>, <a href='javascript:removeMarker(" + waypoint_order[i] + ")'>delete</a>]";
-5-
list_contents[8] = ""; wp_list_interface.push(list_contents.join("")); } clear_list("wp-list"); load_list("wp-list", wp_list_interface); } function openPopup(marker_id){ markers[marker_id].openPopup(); } function exportWaypointData() { //this function takes the all_waypoint_data array and posts it to the server. //The server then makes it available for Labview to read var url = "/map/post"; //URL to post to $.post( url, { "new_save" : 1 }); //before we post the first waypoint, tell the server to forget the old ones //loop over the waypoints in order for (var i = 0; i < waypoint_order.length; i++) { var waypoint_id = waypoint_order[i]; var waypoint_data = all_waypoint_data[waypoint_id]; //get the waypoint waypoint_data['yaw'] = waypoint_data['yaw'] * 0.0174532925; //convert to radians before sending var data = {} //initialise empty array for sending for (var key in waypoint_data) { data[key] = waypoint_data[key]; //put each key into the data array } $.post( url, data); //send to the server (add acknowledge function?) } } //helper functions //get the size of an array of arrays Object.size = function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; //find the location of the object in the array function include(arr,obj) { for (var i = 0; i < arr.length; i++) { if (arr[i] == obj) return i; } } function add_li(list, text) { var list = document.getElementById(list); var li = document.createElement("li"); li.innerHTML = text; list.appendChild(li); } function load_list(list, list_array) { for (var i = 0; i < list_array.length; i++) { add_li (list, list_array[i]);
-6-
} } function clear_list (list) { var list = document.getElementById(list); while( list.hasChildNodes() ) { list.removeChild( list.lastChild ); } }
-7-
<!DOCTYPE html> <!-- This is a template for the ServeMaps.py bottle-based server. It's for the Leeds Blimp project --> <html> <head> <title>Waypoint Selector - Leeds University Blimp</title> <link rel="stylesheet" href="http://code.leafletjs.com/leaflet-0.3.1/leaflet.css" /> <!--[if lte IE 8]> <link rel="stylesheet" href="http://code.leafletjs.com/leaflet-0.3.1/leaflet.ie.css" /> <![endif]--> <script src="/static/jquery-1.7.2.min.js"></script> <!-- hide scrollbars, and simple page formatting --> <style type="text/css"> html { overflow:hidden; } body { margin: 0; padding: 0; } #left { width: 600px; position: relative; float: left; } #right { margin-left: 5px; width: 300px; position: relative; float: left; } #right ol { font-size: 70%; } #frame { } </style>
</head> <body> <script src="http://code.leafletjs.com/leaflet-0.3.1/leaflet.js"></script> <div id="frame"> <div id="left"> <div id="map" style="height: 600px"></div> </div> </div> <div id="right"> <p><strong>List of Waypoints</strong></p> <p><a href='javascript:exportWaypointData()'>Save to Labview</a> - <a href=
-1-
'javascript:clearAllWaypoints()'>Clear All</a> - <a href='javascript:loadPreviousWaypoints()' >Load Previous</a></p> <ol id="wp-list"></ol> </div> <script src='/static/MapConfiguration.js'></script> </body> </html>
-2-