<<

Autonomous Rendezvous and Docking with Tumbling, Uncooperative, and Fragile Targets under Uncertain Knowledge by Hailee Elida Hettrick B.S., Cornell University (2017) Submitted to the Department of Aeronautics and Astronautics in partial fulfillment of the requirements for the degree of Master of Science in Aeronautics and Astronautics at the MASSACHUSETTS INSTITUTE OF TECHNOLOGY June 2019 © Massachusetts Institute of Technology 2019. All rights reserved.

Author...... Department of Aeronautics and Astronautics May 10, 2019

Certified by...... David W. Miller Professor, Aeronautics and Astronautics Thesis Supervisor

Accepted by ...... Sertac Karaman Chairman, Department Committee on Graduate Theses 2 Autonomous Rendezvous and Docking with Tumbling, Uncooperative, and Fragile Targets under Uncertain Knowledge by Hailee Elida Hettrick

Submitted to the Department of Aeronautics and Astronautics on May 10, 2019, in partial fulfillment of the requirements for the degree of Master of Science in Aeronautics and Astronautics

Abstract As efforts to expand humanity’s presence in space continue to increase, aneedfor to autonomously perform in-space close proximity maneuvers without a human operator increases, as well. Such in-space close proximity maneuvers include active debris removal, satellite servicing, and in-space assembly. Active debris removal will facilitate the continued use and access to low Earth , mitigating the expo- nential debris growth occurring due to decrepit satellites and rocket bodies colliding. Satellite servicing will provide the capability to repair and refurbish spacecraft, elon- gating the lifetime of valuable assets both locally orbiting Earth and on routes further out in the solar system. In-space assembly is the means by which large space struc- tures are developed in orbit. Currently, such feats occur with the help of and robotic arms (i.e. the continued development of the International ). However, for increased benefit, in-space assembly must occur autonomously, without a human in-the-loop, in order to create large structures in locations unideal for hu- mans or with a non-negligible communication latency. These three reference missions need the software enabling autonomous rendezvous and docking to reach a technical readiness level to be employed with confidence. In-space close proximity maneuvers share a standard sequence of events described in this thesis. The focus of this thesis address the terminal approach trajectory to soft docking, the contact dynamics of docking between two spacecraft, the optimization of the detumble procedure to bring the Target to stabilization, and adaptive control techniques to handle uncertainties in spacecraft knowledge. The software developed in support of these subproblems is included in the appendices and is largely based on implementation with the Synchro- nized Position Hold Engage Reorient Experimental Satellites (SPHERES) platform or with the characteristics of SPHERES considered.

Thesis Supervisor: David W. Miller Title: Professor, Aeronautics and Astronautics

3 4 Acknowledgments

This research was conducted primarily under the support of the Massachusetts Insti- tute of Technology Department of Aeronautics and Astronautics through a research assistantship. The author thanks the department for its support and Dr. David Miller for his guidance through the research. Additional gratitude is expressed to the SPHERES team and former postdoc Danilo Roascio for assistance with using the SPHERES testbed. Lastly, many thanks to the never-ending support and wisdom from family and the friendship and community provided by Jess, Alexa, Cadence, and Golda.

5 6 Contents

1 Introduction 21 1.1 Motivation for Autonomous Rendezvous & Docking ...... 21 1.1.1 History of Rendezvous and Docking ...... 21 1.1.2 Reference Missions for Autonomous Rendezvous & Docking . . 24 1.2 SPHERES Platform ...... 30 1.2.1 Status of Testbed ...... 32 1.3 Relative Operations for Autonomous Maneuvers ...... 33 1.4 Research Objective ...... 34 1.5 Thesis Roadmap ...... 35

2 Literature Review 37 2.1 Trajectory Optimization ...... 37 2.2 Nonlinear Control ...... 38 2.2.1 Sliding Mode Control ...... 39 2.2.2 Adaptive Control ...... 39 2.3 Attitude Stabilization under Actuator Loss-of-Effectiveness ...... 43 2.4 Soft Docking & Stabilization of a Tumbling Target ...... 44

3 Trajectory Optimization 47 3.1 Stage Description ...... 47 3.2 Synchronous Radial Approach via Second Order Differential Equation 48 3.3 Differential Equation Propagator Architecture ...... 56 3.3.1 R-Bar Alignment ...... 57

7 3.3.2 Forward Propagation ...... 59 3.3.3 Determine Final Position ...... 59 3.3.4 Backwards Propagation ...... 60 3.3.5 Radial Shift ...... 62

4 Adaptive Control for Thrust and Inertia Uncertainties 67 4.1 Thruster Degradation Characterization ...... 67 4.1.1 Thruster Characterization in Test Session 97 ...... 68 4.1.2 Thruster Force Characterization ...... 70 4.1.3 Maintenance Session ...... 73 4.2 In-Flight Adaptive PID Sliding Mode Position and Attitude Controller 82 4.2.1 Problem Formulation ...... 83 4.2.2 Software and Hardware Implementation ...... 88 4.2.3 Results & Discussion ...... 90

5 Docked Dynamics 101 5.1 Contact Dynamics of Docking ...... 101 5.2 Modeled Docked Dynamics ...... 105 5.3 Discrete Solver for Docked Dynamics ...... 110 5.4 Detumble Optimization ...... 112 5.4.1 Indirect Optimization on Angular Acceleration Profiles . . . . 113 5.4.2 Direct Optimization Approach ...... 117 5.4.3 Comparison of Optimization Results ...... 120

6 Conclusions and Future Work 123 6.1 Summary of Thesis ...... 123 6.2 Contributions ...... 126 6.3 Recommendations for Future Work ...... 127

A Trajectory Optimization 129 A.1 Fuel-Optimal Trajectory Optimization Functions ...... 129 A.2 Synchronous Radial Approach Propagator ...... 135

8 B Adaptive Control for Uncertainty 149 B.1 Thruster Characterization Plots ...... 149 B.2 Thruster Characterization Functions ...... 150 B.3 Adaptive PID SMC Controller ...... 165

C Docked Dynamics Functions 171 C.1 Contact Dynamics of Docking Event ...... 171 C.2 Setting up Target and Chaser ...... 174 C.3 Discrete Solver ...... 177 C.4 Direct Optimization Using GPOPS ...... 184

9 10 List of Figures

1-1 Remote Manipulator System on STS-125, Hubble berthed to Shuttle [8] 23 1-2 Mission: ASTRO and NEXT [13] ...... 23 1-3 Effective number of LEO objects larger than 10 cm [15] . . 25 1-4 Conceptual diagram of potential capturing methods [17] ...... 26 1-5 Conceptual diagram of potential removal methods [17] ...... 26 1-6 13-year construction of the International Space Station . . . 27 1-7 Astronauts install set of corrective lenses for flawed mirror in HST on first servicing mission (STS-61) [25] ...... 28 1-8 Canadarm2 post-releasing Dragon spacecraft [27] ...... 29 1-9 Two SPHERES equipped with UDPs performing docking maneuver onboard the ISS ...... 30 1-10 Expanded view of SPHERES ...... 32 1-11 Spatial representation of the stages of ROAM ...... 33

2-1 Diagram of a generic adaptive control system configuration from Lan- dau’s textbook [44] ...... 40 2-2 Diagram of a model reference adaptive control system ...... 41 2-3 Diagram of a self-tuning control system ...... 42 2-4 Diagram of a gain scheduling control system ...... 42

3-1 Reference frames used in discussion of trajectory generation . . . . . 48 3-2 Sequence of optimizations and function-fitting that led to a trajectory- generation differential equation from [38] ...... 49 3-3 Δ푉 of five trajectory optimizations with fixed final time . 50

11 3-4 Euclidean norm of acceleration components as fraction of the Euclidean norm of total acceleration ...... 51 3-5 Sum of Euclidean norm of radial and tangential acceleration compo- nents as fraction of the Euclidean norm of total acceleration . . . . . 52 3-6 Vector elements of acceleration components for each generated trajectory 54 3-7 Chaser’s trajectory from call to ode45 using Listing 3.1 ...... 56 3-8 Illustrating the necessary initial conditions for the propagator i.e. the Chaser is at the desired radius and the Chaser is along the Target’s R-bar ...... 58 3-9 Timeline illustrating the Chaser’s intersections with the Target’s R-bar at the desired initial radial length away from the Target ...... 58 3-10 Forward propagate Target’s orientation and rotation rate for 푛 periods 59

3-11 Generated trajectory yielded from 푡푓 from forward propagation prior to radial shift to align initial position with Chaser’s current position . 63 3-12 Generated trajectory after radial shift with initial position aligned with Chaser’s current position ...... 64 3-13 Illustration of timeline shift after shifting the radial approach to align with the Chaser’s current position ...... 65

4-1 Location and indices of thrusters on satellite with noted exhaust direction 68 4-2 Thruster characterization: raw accelerometer and gyroscope data from IMU in test session 97 ...... 69 4-3 Thruster characterization: 200 ms impulse accelerometer data sepa- rated by axis ...... 70 4-4 Calculated force magnitude of each thruster on Blue and Orange satellites 73 4-5 Test session 101: calculated force of each thruster and each satellite . 75 4-6 Test 11: closed-loop x-translation telemetry ...... 77 4-7 Test 12: closed-loop y-translation telemetry ...... 78 4-8 Test 13: closed-loop z-translation telemetry ...... 79 4-9 Test 14: closed-loop x-rotation telemetry ...... 80

12 4-10 Test 15: closed-loop y-rotation telemetry ...... 80 4-11 Test 16: closed-loop z-rotation telemetry ...... 81 4-12 Flowchart of the in-flight adaptive PID sliding mode controller asim- plemented in C-code ...... 91 4-13 A comparison of commanded position and attitude vs. measured teleme- try from simulation ...... 92 4-14 Adaptive PID SMC time histories corresponding to position and atti- tude from simulation ...... 93 4-15 Trajectories plotted in the 푥-푦 plane from simulation ...... 95 4-16 Trajectories plotted in the 푥-푦 plane from hardware tests ...... 96 4-17 A comparison of commanded position and attitude vs. measured teleme- try from hardware tests ...... 97 4-18 Adaptive PID SMC time histories corresponding to position and atti- tude from hardware tests ...... 98

5-1 Chaser and Target during instance before docking occurs denoted with separate position, velocity, and attitude vectors ...... 102 5-2 Chaser and Target in the instance after docking denoted with aggre- gated translational and attitude velocity ...... 103 5-3 Chaser and Target as docked, aggregated system with denoted body- fixed frame at Target’s center of mass and the force and torque direc- tions of the Chaser ...... 106 5-4 Free body diagram of the Chaser displaying Chaser’s abilities to impart force and torques and its internal loads and moments from interacting with the Target ...... 107 5-5 Expected angular velocity time histories from integration of selected angular acceleration functional forms ...... 114 5-6 Angular acceleration profiles as axisymmetric spacecraft initially rotate about all three axes ...... 120 5-7 Angular acceleration profiles as spacecraft initially rotate about 휓-axis 121

13 5-8 Angular acceleration profiles as axisymmetric spacecraft initially nutate 121

B-1 Thruster Characterization: 50 ms and 100 ms Impulses ...... 149

14 List of Tables

3.1 Inputs to propagateToTarget function with descriptions ...... 61

4.1 Thruster force and torque directions in SPHERES body-fixed frame . 69 4.2 Calculated thruster forces for each satellite and ratios of calculated thruster force divided by expected force for each satellite ...... 74 4.3 Test session 101 descriptive list of tests executed ...... 75 4.4 Sequential series of maneuvers and corresponding commanded position and quaternion ...... 89

5.1 Notation for contact dynamics of two spacecraft docking to one another102 5.2 fmincon optimization options used in the indirect optimization of an- gular acceleration profiles ...... 113 5.3 Method 1 optimization results of optimal Δ푡 and associated cost . . . 116 5.4 Method 2 optimization results of optimal Δ푡 and associated cost . . . 119

15 16 Nomenclature

Acronyms

ATV

CM Center of mass

DART Demonstration of Autonomous Rendezvous Technology

DOF Degree-of-freedom

EVA Extravehicular Activity

GN&C Guidance, Navigation, & Control

HST

IMU Inertial measurement unit

ISS International Space Station

JEM Japanese Exploration Module

LEO

MIT Massachusetts Institute of Technology

MRAC Model reference adaptive control

PADS Position and Attitude Determination System

PID Proportional-Integral-Derivative

17 ROAM Relative Operations for Autonomous Manev

SLV Satellite

SMC Sliding mode control

SPHERES Synchronized Position Hold Engage Reorient Experimental Satellites

SSL Space Systems Laboratory

SSRMS Space Station Remote Manipulator System

TS Test Session

UDP Universal Docking Port

VERTIGO Visual Estimation for Relative Tracking and Inspection of Generic Ob- jects

XSS Experimental Satellite System

Coordinate Frames

CHA Chaser body-fixed frame

INT Inertial frame

TAR Target body-fixed frame

Variables

Δ푉 Fuel consumption metric represented by sum of velocity of a maneuver

휆 Wavelength

R퐵2퐼 Sliding variable associated with state 푝

휑 Roll angle

휓 Yaw angle

18 휃 Pitch angle

⃗훼 Angular acceleration vector

⃗휔 Angular velocity vector

⃗푟 Position vector

⃗푢 Control input vector

푞 Quaternion

푠푝 Sliding variable associated with state 푝

D Aperture diameter

19 20 Chapter 1

Introduction

1.1 Motivation for Autonomous Rendezvous & Dock- ing

As manned and unmanned space missions become more complex, the need for reli- able autonomous rendezvous and docking capabilities becomes paramount. Missions that will benefit from autonomous rendezvous and docking include in-space assembly, satellite servicing, and active debris removal. Mankind’s history of space missions is already rich with human-assisted instances of in-space assembly and satellite servic- ing, hinting at a wider set of capabilities that will be enabled by removing humans from the loop.

1.1.1 History of Rendezvous and Docking

Initial interest in spacecraft rendezvous coincided with the beginning of the in the late 1950s [1]. Technical adeptness at in- improved through the course of the Gemini program in preparation for the program. and 7 achieved the first space rendezvous using a concentric orbit rendezvous plan [2]. ’s sequences were a repeat of the previous mission with the Agena Target Vehicle (ATV) with the addition of humans-in-the-loop for docking the two vehicles [3]. Additional rendezvous sequences were tested in missions 9 through 12 of the

21 Gemini program, proving in-space rendezvous feasible in preparation for the Apollo missions. Rendezvous and capture were necessary functionalities for the to satisfy its mission objectives, as the Lunar Excursion Module had to rendezvous and dock with the Command Service Module [4]. The coelliptic rendezvous scheme was utilized for and 12 [5], and the lessons learned from those missions as well as 7, 9, and 10 led to the utilization of a shorter rendezvous profile in missions 14 through 17 that increased time on the lunar surface [6]. In this manner, rendezvous and docking were essential maneuvers that facilitated visiting the . The era of the ushered in new rendezvous, capture, and docking approaches necessitated by the target spacecraft. Shuttle’s onboard guidance, naviga- tion, and control (GN&C) subsystem autonomously performed rendezvous functions but required the crew to be in-the-loop for docking maneuvers [4]. Additionally, the Shuttle program was the first to make use of a robotic arm (the Remote Manipulator System) for capture and berthing (see Figure 1-1) [7]. Therefore, the Shuttle did not only advance the software capabilities critical for autonomous rendezvous and docking, but it also had a significant impact on the hardware that facilitates such maneuvers. The Demonstration of Autonomous Rendezvous Technology (DART) was the first US effort to perform rendezvous and docking without an piloting thema- neuver. Its mission objectives included demonstrating R-bar, V-bar, and circumnavi- gation approach methods [9]. Launched in April 2005, the rendezvous maneuvers were completed successfully. Unfortunately, DART’s mission was not entirely successful as consequence of a sensor anomaly resulting in more fuel usage and a collision with the secondary spacecraft, indicating necessary system engineering improvements for a fully autonomous rendezvous mission [10]. XSS-10 and Orbital Express represented a focus shift towards satellite servicing. The Air Force Research Laboratory’s XSS-10, which was deployed from a Delta II vehicle in January 2003, successfully semi-autonomously maneuvered around the sec- ond stage, performing close-proximity inspection of the stage [11]. Launched in March

22 Figure 1-1: Remote Manipulator System on STS-125, Hubble berthed to Shuttle [8]

2007, DARPA’s Orbital Express demonstrated the hardware and software abilities to autonomously capture the Target and to autonomously service the Target [12]. Or- bital Express was a key milestone in validating these technologies, illustrating the technical feasibility of satellite servicing [10].

Figure 1-2: Orbital Express Mission: ASTRO and NEXT [13]

23 1.1.2 Reference Missions for Autonomous Rendezvous & Dock- ing

Technology demonstration missions for autonomous rendezvous and docking have so far not demonstrated the ability to handle non-ideal conditions, such as would be expected for realistic in-space close proximity operations. These types of missions include in-space assembly, satellite servicing, and active debris removal. Of these types of missions, it is expected that the target spacecraft or object would not be well-understood and is likely to be uncooperative.

Active Debris Removal

In 1978, Kessler predicted that by the year 2000, existing pieces of small debris will exponentially increase via collisions even without additional debris being added from orbit. As of 2010, Kessler’s prediction has proven true – the exponential increase of small debris from collisions is coined the Kessler Syndrome [14]. Specifically, the debris population of low Earth orbit (LEO) is at risk of reaching a capacity of decrepit spacecraft and launch vehicle stages that satellites will no longer be able to be placed in LEO [15]. Kessler also emphasized the need to implement mitigation practices in the wake of inadequate collision avoidance by not leaving future payloads and rocket bodies in orbit once deprecated. Figure 1-3 illustrates the effective number of objects in LEO that are 10 cm or larger based on simulation. "Effective number" refers to the fraction of time per orbit period than an object spends within the altitude range of 200 km to 2000 km [15]. Figure 1-3 indicates the steady growth of collision fragments as collision-created debris causes more collisions. Motivated by the dire situation the Kessler Syndrome presents, software develop- ment has begun to make feasible active debris removal. Bonnal et al. highlight the general high-level functions agnostic to the Chaser that are necessary for de-orbiting debris. In summary, these functions are

1. Far-range rendezvous between Chaser and debris

24 Figure 1-3: Effective number of LEO objects larger than 10 cm[15]

2. Short-range rendezvous between Chaser and debris – a potentially more complex task based on the nature of the debris object (i.e. non-cooperative and tumbling)

3. Mechanical interfacing – docking, grappling, electromagnets, net

4. Control, detumbling, and re-orientation of the debris

5. De-orbitation

Details of each function is further elaborated in Bonnal et al’s paper. In addition to outlining these necessary functionalities for an active debris removal mission, Bonnal also stresses the need for more technical studies that investigate realistic solutions and the political minefield that is inherent in using such technology [16]. Despite being past the tipping point of spacecraft density in LEO, no active debris removal missions have launched. The literature provides a thorough review of existing technology or concepts that would support such missions. Figure 1-4 illustrates the proposed capture methods, and Figure 1-5 presents the proposed removal methods [17].

25 Figure 1-4: Conceptual diagram of potential capturing methods [17]

Figure 1-5: Conceptual diagram of potential removal methods [17]

In-Space Assembly

Most spacecraft are limited in size and functionality by the size of the payload fairing of the launch vehicle. One workaround for this issue are utilizing complex deployable systems, a methodology the James Webb Space Telescope has employed [18]. In-space assembly with a human operator has occurred and is a continued possibility; however, such an operation has inherent limitations. The International Space Station (ISS) is a noteworthy example of in-space assembly with humans-in-the-loop (see Figure 1- 6). Lessons learned from the assembly of the ISS emphasized the importance of offloading the work placed on the EVA astronaut as advances in computer vision, remote operations, and autonomy occur [19]. According to Mohan, the feasibility of future space missions depends on the tech- nical advancement of in-space assembly to facilitate the next-generation of space

26 (a) Zarya and Unity on December 13, 1998 (b) ISS on March 7, 2011 [21] [20] Figure 1-6: 13-year construction progress of the International Space Station telescopes, fuel depots, and solar power stations [22]. The next-generation of space telescopes presents the most pressing case for robotic in-space assembly. Complex deployable systems present a high risk to the mission, and desirable locations for space telescopes are not necessarily in locations accessible by astronauts [23]. For space telescopes (and other payload equipment that utilize apertures), the angular

휆 resolution improves as the aperture diameter improves according to 휃 = 1.22 퐷 , where 퐷 is the aperture diameter and 휆 is the wavelength [24]. A higher angular resolution is desirable as it allows for more precise imaging. The disadvantages of human-assisted assembly are communication latencies (for tele-operation), a lengthy lead time of roughly a decade before a mission occurs, limited locations based on where humans can travel, and increased costs of assembly due to human involvement. Robotic in-space assembly offers a low-cost and low- risk alternative; however, technological progress in the use of space robotics and autonomous rendezvous and docking methodologies is necessary for feasibility [22].

Satellite Servicing

Satellite servicing offers several benefits scientifically and economically. As humanity expands outward, infrastructure must exist for refueling, repairing, and refurbishing spacecraft. Not only would satellite servicing offer the means to extend the lifetime of satellites that have already been significantly invested in, but it is reasonable to

27 claim it will also be a necessity as spacecraft systems become more complicated [10]. Astronaut-assisted satellite servicing has already proven its use with respect to re- pairing and the Hubble Space Telescope (HST). The first instance of servicing occurred shortly after Skylab’s launch in 1973. The micrometeroid shield failed and a main solar array panel failed to deploy. The crew performed a series of extravehicular activities (EVAs) to replace the shield. More notorious were the issues with HST, which was designed to support on-orbit servicing via astronaut support. On initial checkout, an optical flaw was discovered in HST’s primary mirror and it experienced thermal jittering during orbital sunrise and sunset. Five servicing missions were de- signed and executed to repair, replace, or augment various aspects of HST, the first of which is depicted in Figure 1-7 [10].

Figure 1-7: Astronauts install set of corrective lenses for flawed mirror in HST on first servicing mission (STS-61) [25]

The Space Station Remote Manipulator System (SSRMS), also known as Canadarm2

28 (see Figure 1-8), is a fully operational, 17-meter long robotic arm attached to the Inter- national Space Station that offers seven degrees of freedom and is capable of handling payloads up to 100,000 kg of mass [26]. Canadarm2 assists in maintaining the ISS, grappling resupply spacecraft and berthing them to the ISS, and moving equipment. Not only is Canadarm2 an example of the use of robotics in satellite servicing, but it is also the recipient of servicing from astronauts. For example, in 2002, one of its wrist roll joints was replaced and it received new latching end effectors in 2017 and 2018 [27]. Robotic arms are expected to continue and serve in a critical capacity for future satellite servicing missions.

Figure 1-8: Canadarm2 post-releasing Dragon spacecraft [27]

Designing spacecraft to be serviced has already shown promising results, how- ever, that is only part of the satellite servicing equation. Fully autonomous satellite servicing requires the continued development of hardware and software capable of autonomous rendezvous and docking as well as the advancement of utilizing robotic manipulators. Removing the astronaut involvement from the satellite servicing sce- nario will permit servicing on assets deployed in locations currently unreachable by astronauts. Additionally, a dependence on such autonomy will be integral as our space exploration aspirations become more complex and occur over distances where communication latencies are a hindrance.

29 1.2 SPHERES Platform

SPHERES (see Figure 1-9) is a platform for the development and validation of for- mation flying, docking, control, estimation, navigation, and guidance algorithms for separated and aggregated spacecraft systems [28], [29]. There are three testbeds for SPHERES – the Japanese Exploration Module (JEM) in the International Space Station (ISS), the glass table in the Space Systems Laboratory (SSL) at the Mas- sachusetts Institute of Technology (MIT), and the flat floor facility at MIT. The testbed aboard the ISS allows for six degree-of-freedom testing because of the micro- gravity environment – a unique feature this program offers for spacecraft algorithm development. The two testbeds at MIT – the glass table and the flat floor – offer three degree-of-freedom environments for SPHERES testing. Although this is a more constrained environment, these testbeds are easier to access and all intended ISS test sessions are first implemented on either the glass table or the flat floor.

Figure 1-9: Two SPHERES equipped with UDPs performing docking maneuver on- board the ISS

There are three satellites aboard the ISS and three satellites in the SSL at MIT.

Each satellite is equipped with 12 CO2 thrusters that provide full translational and ro- tational actuation. For ground-based testing, the satellites are placed on air carriages

30 that use CO2 to produce a thin film of air underneath the pucks. In this manner, the satellites can translate in 푥 and 푦 and rotate about 푧 nearly frictionlessly. These coordinates are defined in the body-fixed reference frame of each satellite. Theorigin is defined as the geometric center of the satellite. The +푥 axis goes through the ex- pansion port, +푦 is opposite of the control panel, and +푧 goes through the regulator knob.

The satellites were designed to limit astronaut and research accessibility to only the battery compartment, the CO2 tank, the expansion port, and the regulator knob. The internal structure is an aluminum frame that all the internal devices are mounted to. The external assembly is a polycarbonate shell, called out in Figure 1-10. The 12 thrusters operate based on on/off commands and offer full controllabil- ity in six degrees-of-freedom. Each thruster produces a nominal force of 0.1 N, and these thrusters are not throttleable. The satellite determines its metrology via the Position and Attitude Determination System (PADS). Five ultrasound beacons are wall-mounted about the test volume, and each satellite is equipped with ultrasound receivers enabling global position knowledge. Additionally, each satellite has three single-axis rate gyroscopes to measure body-axis angular rates and three single-axis accelerometers to measure its linear acceleration. In this manner, each satellite is controllable and observable.

Over the course of the satellites’ lifetime, several peripherals have been developed and validated, expanding the capabilities of the satellites aboard the ISS. These pe- ripherals include Halo, Universal Docking Port (UDP), and Visual Estimation for Relative Tracking and Inspection of Generic Objects (VERTIGO). Halo is a struc- tural attachment that expands the single expansion port of SPHERES to six expan- sion ports, enabling a single satellite to use both UDP and VERTIGO at the same time. The UDP is an attachment that permits unidirectional docking between two satellites. Prior to the development of UDP, the satellites "docked" via Velcro straps. With UDP, the satellites can autonomously dock and undock via the metal lance and opening. The UDP is equipped with a photosensor that determines when the lance is fully inserted. Then, a motor closes two metal cams around the lance, locking it in

31 Figure 1-10: Expanded view of SPHERES place. Moreover, the UDP has a camera and fiducial marker parallel to the lance and opening to enable autonomous docking maneuvers. Lastly, VERTIGO enables vision- based navigation and estimation using a 1.2 GHz x86Linux computer and two stereo cameras. These peripherals enable more science to be conducted with SPHERES but also change the well-understood inertial properties of the satellites [30].

1.2.1 Status of Testbed

The SPHERES platform on ISS has been operating for 13 years and has almost performed 110 test sessions. As a consequence of this usage, several thrusters across the three satellites have become degraded. An analysis and initial attempt at a workaround are documented in this thesis. It is also hypothesized that the knowledge of inertial properties of the satellite with an attachment may be inaccurate based on the poor test results yielded from autonomous docking tests. The inability for the satellites to dock to one another may be a consequence of both these issues though. In order to address the possibility of inaccurate knowledge of inertial properties of an

32 aggregated system, a controller resilient to mass properties for position and attitude of a free-flyer was developed.

1.3 Relative Operations for Autonomous Maneu- vers

The majority of the research described herein developed from subproblems of the SSL’s Relative Operations for Autonomous Maneuvers (ROAM) project. Figure 1- 11 illustrates Stages zero through three of a typical in-space close proximity mission between a Chaser spacecraft and a Target. This research developed from focusing on Stage 2, the terminal approach to soft landing, and the beginning of Stage 3, joint maneuvering of the aggregated system.

Figure 1-11: Spatial representation of the stages of ROAM

Stage 2 warrants trajectory generation to facilitate the Chaser’s terminal approach to the Target’s docking port. This is addressed via some observations of previous tra- jectory optimization work performed in the lab in addition to the necessary software framework for implementation with SPHERES. Both Stage 2 and 3 are vulnerable to uncertainties in either actuator force or torque and inertial properties knowledge of the individual or aggregated systems. An existing case with SPHERES is analyzed

33 and an adaptive control methodology to overcome such uncertainties is presented. Lastly, since active debris removal is a type of in-space close proximity missions are a problem of interest, a fragile Target at risk of breaking apart further is the subject of the beginning of Stage 3 – detumbling the uncooperative Target. Therefore, in addition to modeling the docked dynamics of the aggregated system, two different optimization methods are employed to minimize a cost function of both fuel and imparted loads and moments via optimizing the angular acceleration profile.

1.4 Research Objective

While facilitating in-space close proximity maneuvers encapsulate a breadth of engi- neering disciplines, the focus of the research described herein is only concerned with control, guidance, and autonomy algorithms with respect to specific subproblems. Several supporting engineering disciplines are applicable with other fields and prob- lems, as well, whereas the listed topics are discussed specifically with respect to such proximity maneuvers. The objective of this thesis is summarized as follows:

• To contribute towards the feasibility of regular and repeatable in-space close proximity missions where a Chaser spacecraft is interacting with an uncooper- ative, tumbling Target

• By utilizing adaptive control and optimization to enable in-flight parameter estimation, trajectory generation, and detumbling procedures

• Using Chaser’s tracking error and information regarding the Target’s pose from estimation

• While ensuring stability and both minimum fuel and minimum loads and mo- ments imparted on the Target.

34 1.5 Thesis Roadmap

Six chapters constitute this thesis. Chapter 1 motivated the research documented herein; provided a literature review of existing autonomous rendezvous and dock- ing work; and outlined the research objective. Chapter 2 formulated the in-space close proximity operations problem and gave an overview of the approaches em- ployed. Chapter 3 detailed observations regarding existing trajectory optimization research and described the framework for a trajectory propagator. Chapter 4 dis- cussed an in-flight adaptive proportional-integral-derivative sliding mode controller and the thruster degradation analysis of the SPHERES aboard the International Space Station. Chapter 5 described modeling of contact dynamics from dancing, dy- namics of two docked spacecraft, and the optimization of the detumbling procedure. Lastly, Chapter 6 summarized the result of the aforementioned chapters and outlined future work to be completed.

35 36 Chapter 2

Literature Review

2.1 Trajectory Optimization

Aspects of Stage 2, the terminal approach to soft docking, of the ROAM mission has previously been discussed in the literature, although it remains the topic of ongoing research. It is desired for such a terminal approach to be optimal and ensure the safety of both the Chaser and the Target. Often, the terminal approach trajectory is optimized to minimize fuel, time, thruster impingement, or a combination of these factors. DiGirolamo proposed an RRT* algorithm as an offline trajectory planner that minimized fuel and time and avoided thruster plume impingement from the Chaser on the Target [31]. Jackson developed an offline planner that used* anA node search to optimize a trajectory that minimized the combined plume and fuel cost for a close proximity maneuver [32]. Miele et al. investigated several variants of the optimal trajectory for the terminal approach of two spacecraft including time-optimal and fuel-optimal [33]. Additionally, Lee described the development and evaluation of an integrated guidance, navigation, and control system for autonomous proximity operations and docking from a Chaser to a cooperative Target using linear quadratic Gaussian controls and a V-bar hopping approach. This V-bar hopping approach had the Chaser approach the Target from the −V-bar direction, occasionally moving to a lower altitude orbit in order to speed up, and then shifting back to the same altitude as the Target to station-keep briefly, ensuring the approach scheme was advancing

37 as expected [34]. These examples of existing research in the literature made use of offline methods that are too computational expensive to occur in-flight.

Research in the literature has also focused on employing path planning techniques that can produce trajectories more rapidly. Virgili-Llop et al. presented an onboard algorithm to capture a tumbling Target via solving a series of convex programming problems [35]. Munoz developed a rapid path-planning algorithm for the terminal approach trajectory via an adaptive artificial potential function methodology that produced a near-optimal trajectory yielding a near-minimum time or fuel cost [36]. Moreover, Zappulla et al. validated a real-time trajectory planner for spacecraft ren- dezvous via harmonic potential functions and an RRT* algorithm for fuel optimality [37]. In addition to the aforementioned literature, research in the SSL at MIT has also focused on developing and validating in-flight optimal trajectory planners. Sternberg investigated the autonomous docking approach problem that is complicated by an uncooperative and tumbling Target, uncertainty in the knowledge of the tumble, and required the Chaser to use an accelerated approach trajectory. Sternberg produced a computationally efficient solver for determining a fuel-optimal approach trajectory robust against uncertainty in the Target’s tumble. This solver utilized a synchronous R-bar (where R-bar is defined as the docking port axis) approach for docking with the rigid body Target [38]. However, there were some fundamental issues with the technique Sternberg employed that are discussed at length later in this thesis.

2.2 Nonlinear Control

Driven by the need of application to real-world systems, nonlinear control theory was applied in the research documented herein. Nonlinear control theory utilizes rigorous mathematical techniques for nonlinear differential equations (i.e. Lyapunov stability theory and limit cycle theory). Sliding mode control and adaptive control are discussed in detail in this section, as they were employed in the research completed.

38 2.2.1 Sliding Mode Control

Sliding mode control is a straightforward technique of robust control that consists of a nominal feedback controller and additional terms that handle the uncertainty of the system. Such uncertainties can either be unmodelled dynamics or inaccuracies in the system order. Sliding mode control allows 푛푡ℎ-order systems to be replaced by 1푠푡-order problems, which are generally easier to control. Therefore, after trans- forming such problems, "perfect" tracking performance can be achieved in the face of uncertainties at the cost of high control effort. This control technique simplifies 푛−1 (︁ 푑 )︁ the system dynamics by using the sliding variable 푠 = 푑푡 + 휆 푥˜, where 푛 is the order of the system, 푥˜ = 푥 − 푥푑 is the tracking error, and 휆 is a user-defined positive constant [39]. Often, a boundary layer is applied to the sliding mode control scheme in order to trade some tracking performance to eliminate chattering and lower control cost [40]. Chapter 4 contains a detailed derivation of a sliding mode controller. The literature contains several applications of sliding mode control for different disciplines. A proportional-integral sliding mode control was applied to an active suspension system and proved to be more robust compared a linear quadratic reg- ulator [41]. A proportional-integral-derivative sliding mode controller was used to control the speed of an electromechanical plant and showed superior performance compared to a conventional PID controller [42]. Time-varying terminal sliding mode techniques have been employed for attitude control of rigid spacecraft with inertia uncertainties and external disturbances [43]. These examples represent a sample of the existing research regarding applying sliding mode control to ensure robustness to uncertainties.

2.2.2 Adaptive Control

Adaptive control offers a set of control methods for handling uncertainty in either sys- tem parameters or the control parameters. This uncertainty arises from both a lack of knowledge and from a system whose parameters vary with time. Therefore, adap- tive control techniques provide the means for performing online parameter estimation

39 that consequently decreases a controller’s tracking error [44]. A basic adaptive control setup is displayed in Figure 2-1. Only nondual adaptive control techniques were con- sidered for the research documented in this thesis. Such control techniques include model reference adaptive control (MRAC), self-tuning control, gain scheduling, and adaptive sliding mode.

Figure 2-1: Diagram of a generic adaptive control system configuration from Landau’s textbook [44]

MRAC systems are composed of a plant with unknown system parameters, a reference model encompassing the desired output response, a feedback control law with tunable parameters, and an adaptation law that updates the tunable parameters. The unique elements of this adaptive control system are the reference model and adaptation law. The reference model is designed with performance specifications in mind (e.g. rise time, overshoot, settling time) that the system will be driven towards. The adaptation law updates the tunable parameters based on the commanded state to drive the tracking error to zero. The necessary adaptation laws for an MRAC system fall out of applying Lyapunov stability theory to the closed-loop adaptive control system [39]. A block diagram of a typical MRAC system is shown in Figure 2-2.

40 Figure 2-2: Diagram of a model reference adaptive control system

The literature is rich with applications of MRAC systems and discussions of MRAC’s robustness and stability under varying conditions [45], [46], [47], [48]. For instance, MRAC was implemented on SPHERES to perform on-board parameter estimation and yielded improved control on the SPHERES-Halo configuration [49]. Additionally, adaptive PD and PID MRAC controllers have been developed for an open loop unstable Satellite Launch Vehicle (SLV) system. Both controllers yielded improved tracking performance during the atmospheric flight stage over their gain- scheduled counterparts due to their ability to account for unmodelled dynamics [50].

A self-tuning controller, depicted in Figure 2-3, consists of a controller and an estimator that create a closed-loop with a plant. The estimator updates the un- known parameters 푎^ for a system that is continuously time-varying. These unknown parameters may be of the plan (an indirect approach) or of the controller (a direct approach) [51]. Different choices may be selected for both the controller and thees- timator. For instance, the most straightforward estimator option would be recursive least squares. A sample control method is deterministic pole placement but may also be proportional-derivative [52]. The goal of self-tuning control is to minimize the data-fitting error in input/output measurements whereas MRAC attempts todrive the tracking error performance to zero [53]. MRAC and self-tuning control are similar

41 in several respects despite their varying motivations, as illustrated by their respective block diagrams (Figures 2-2 and 2-3).

Figure 2-3: Diagram of a self-tuning control system

Gain scheduling represents another category of adaptive control. Gain schedul- ing makes use of auxiliary variables correlated to the plant dynamics. By changing the controller parameters as a function of the auxiliary variables, gain scheduling minimizes the effect of variations of those plant parameters [51]. Knowledge ofthe dynamics of the plant helps in determining scheduling variables. The key advantage of gain scheduling is that plant parameters can be changed rapidly in response to output changes. However, gain scheduling has the drawback of a time-consuming design process and performing open-loop.

Figure 2-4: Diagram of a gain scheduling control system

42 The adaptive control scheme employed and documented later in this thesis is adaptive sliding mode control. Adaptive sliding mode control uses the sliding mode variable previously described in combination with adaptation laws that fall out of Lya- punov stability theory. Slotine and Coetsee detail how coupling adaptive control with sliding mode control offers improved performance using the boundary layer concept to limit control authority and chattering [54], [55]. Research furthering the robustness of adaptive sliding mode control utilizes estimating the boundary of perturbations and applying a low-pass filter in addition to the boundary layer described by Slotine [56]. Technical details of this type of controller and a derivation of necessary adaptation laws is discussed in Chapter 4.

2.3 Attitude Stabilization under Actuator Loss-of- Effectiveness

Formation flying has motivated the research to develop methods for persisting through sensor or actuator failures. Godard and Kumar develop and present two adaptive fault-tolerant control laws – continuous sliding mode and nonsingular terminal slid- ing mode – as a software solution to an onboard sensor and actuator failure in order to maintain a spacecraft clusters ability to fly in formation. They show via sim- ulation that both methodologies were able to stabilized the formation and execute maneuvers despite the failures; specifically, the nonsingular terminal sliding mode had a faster convergence rate, was more effective in minimizing the tracking erros, and limited fuel consumption compared to the continuous sliding mode [57]. Li et al. demonstrate the robustness of a second-order sliding mode control algorithm against sensor and actuator failure but with limited performance [58]. Moreover, Hu and Xiao apply a sliding mode controller to a flexible spacecraft experiencing actuator loss-of- effectiveness and demonstrate its ability to recover from the fault and achieve mission objectives [59]. Henceforth, the existing literature suggests sliding mode control is a promising method for stabilizing a spacecraft under actuator loss-of-effectiveness.

43 2.4 Soft Docking & Stabilization of a Tumbling Target

At the end of the terminal approach stage (Stage 2) of ROAM occurs the soft dock, after which both spacecraft act as a single system. Sternberg’s soft dock stage contin- ued with the approach along the Target’s R-bar and assumed a mechanical clasping between the docking ports of the Chaser and the Target [38]. Contrastingly, the Orbital Express Demonstration System used a robotic arm to capture its stable and cooperative Target and berth it to the Chaser for servicing [12]. Similarly, the Japan Aerospace Exploration Agency’s Kounotori Integrated Tether Experiment is a low- cost active debris removal system that uses an electrodynamic tether to capture an object of debris and deorbit it [60]. Nguyen-Huynh developed an adaptive algorithm for a space manipulator during the capture of an unknown, tumbling, rigid object to create a reactionless motion, thus, perturbing the base of the manipulator minimally during the transient period between capture and stabilizing the Target [61]. Zhang et al. utilized an inter-satellite electromagnetic force and proposed a nonlinear 6-DOF control (via linear quadratic regulator and an extended state observer) coupled with the method of soft docking [62]. These different methods are appropriate for their relative missions of capturing and becoming one system with a rigid Target. Once a Chaser has docked to an uncooperative and tumbling Target, the Chaser must stabilize the tumble that is occurring. Katz investigated the stabilization of an uncooperative, flexible Target in 2D using an adaptive control law, which had better performance than a PD controller and partial feedback linearization controller [63]. Aghili presented a closed-form solution for time-optimal controlling of a tumbling, rigid Target that satisfied a constraint to maintain the norm of the braking torques below a specified value correlating to the limits of an actuator’s torque [64]. Avanzini and Giuletti developed a B-dot control law to detumble a spacecraft solely using mag- netic actuators and confirmed its validity and convergence via Monte Carlo analysis [65]. Coverstone-Carroll discussed a variable structure controller used to detumble underactuated spacecraft, validated through detumbling simulations [66]. Several of

44 these methods have been posed as detumbling means for a spacecraft to detumble itself, rather than for a Chaser docked to a Target and needing to detumble the ag- gregated system. The same methodologies can be applied to this scenario. However, the primary concern would be the limited actuator force available to the Chaser since the Target is assumed to be uncooperative.

45 46 Chapter 3

Trajectory Optimization

This chapter will focus on the trajectory optimization approach of the in-space close proximity operations mission (i.e. Stage 2 of ROAM). Stage 2 is the terminal ap- proach to soft docking that begins when the Chaser is approximately 10 meters from the Target spacecraft. It occurs after the angles-only rendezvous that gets the Chaser into the desired proximity of the Target before a terminal approach with an end state of the Chaser docking to or grappling the Target. An expansion of previous trajec- tory optimization research was attempted, but that attempt led to some noteworthy observations of the previous work, documented in this chapter. Additionally, the at- tempt at the expansion resulted in a software framework for finding the waypoints of a trajectory by propagating a given differential equation.

3.1 Stage Description

The Chaser approaches the Target along its R-bar, maintaining a synchronous radial approach to the Target’s docking port. In the context of this chapter, R-bar refers to the body-fixed, radial axis of the Target’s docking port expressed in the UDP reference frame. In discussing the dynamics of the Chaser and Target, four reference frames are used – INT, the inertially-fixed frame; TAR, the Target’s body-fixed frame centered at its center of mass; UDP, the body-fixed frame located at the docking port’s lance; and CHA, the body-fixed frame of the Chaser centered at its center of mass. These

47 reference frames are illustrated in Figure 3-1.

Figure 3-1: Reference frames used in discussion of trajectory generation

It is assumed that the Target is tumbling and uncooperative. The Chaser de- termines the Target’s orientation and rotation rate via a model delivered by the estimation stage of the mission. Additional assumptions include rigid body dynamics and that the Chaser has full control authority to translate and rotate. This stage begins when the Chaser is relatively close to the Target (on the order of magnitude of 10 meters away) and has zero initial velocity.

3.2 Synchronous Radial Approach via Second Or- der Differential Equation

Initially, the trajectory optimization subproblem focused on utilizing the contributions from Sternberg’s Sc.D. thesis. This section will overview Sternberg’s contributions and hypotheses and the corresponding observations and reasons his work could not be implemented. To support his efforts of finding an optimal, minimum-fuel synchronous radial approach of a Chaser to a Target, Sternberg developed three hypotheses:

1. All possible tumbles are a function of inertia ratios and angular rate components; therefore, a minimum parametrization exists.

48 2. A fuel optimal approach is analogous with the tangential and radial acceleration components of a trajectory being equivalent between initial and final transients.

3. A reduction in optimization complexity falls out as a consequence of this equal- ity and minimum parametrization.

The first hypothesis is well supported by Sternberg [38]; the second and third hy- potheses will be discussed in-depth here. Following Sternberg’s optimization process detailed in his thesis and illustrated by Figure 3-2, the following plots were produced using a final time array of [1, 20, 33, 55, 240] seconds. The spacecraft has an inertia deg ratio of [1, 1, 1] and an angular velocity of [0, 0, 5] s . The optimization options uti- lized were: OptimalityTolerance = 1e-3, MaxFunctionEvaluationss = 1e6, MaxIterations = 1e7, StepTolerance = 1e-8, and Algorithm ='sqp' . Two of the primary functions for running this optimization are included in this thesis in Appendix A.1. Contact the author for access to the numerous supporting functions.

Figure 3-2: Sequence of optimizations and function-fitting that led to a trajectory- generation differential equation from [38]

49 Figure 3-3: Δ푉 of five trajectory optimizations with fixed final time

Figure 3-3 illustrates the resulting Δ푉 of the trajectory optimizations correspond-

m ing the value to the fixed final time. The lowest Δ푉 is 2.183 s , yielded from the op-

timization with 푡푓 = 33 seconds. This figure indicates that the optimal minimum fuel trajectory exists in the middle of the duration spectrum of final times. Intuitively, it is reasonable that slower trajectories require more fuel as the Chaser circumnavigates the Target repeatedly; rapid trajectories burn fuel at a faster rate to meet the desired final time. According to Sternberg’s second hypothesis, this trajectory’s tangential and radial acceleration components should be equivalent. At least, these components should be closer to equivalent to the others when taking into consideration that the optimization process used here likely is not identical to Sternberg’s. The acceleration components are labeled and determined as such:

¨퐶퐻퐴 Linear: ⃗푎푙푖푛 = ⃗푟푇 퐴푅 (3.1a)

푇 퐴푅 푇 퐴푅 퐶퐻퐴 Centripetal: ⃗푎푐푒푛푡 = ⃗휔퐼푁푇 × (⃗휔퐼푁푇 × ⃗푟푇 퐴푅 ) (3.1b) ˙ 푇 퐴푅 퐶퐻퐴 Angular: ⃗푎푎푛푔 = ⃗휔퐼푁푇 × ⃗푟푇 퐴푅 (3.1c) 푇 퐴푅 ˙퐶퐻퐴 Coriolis: ⃗푎푐표푟 = 2(⃗휔퐼푁푇 × ⃗푟푇 퐴푅 ). (3.1d)

The radial acceleration components are the linear and centripetal accelerations and the tangential acceleration components are angular and Coriolis.

50 In Figure 3-4, the Euclidean norm of each component as a fraction of the Euclidean norm of the total acceleration is represented. Since the Target is in a flat spin with deg angular velocity [0, 0, 5] s , the angular acceleration component is zero throughout ˙ 푇 퐴푅 ⃗ the time duration since ⃗휔퐼푁푇 (푡) = 0. The time histories of the remaining three acceleration components differ based on the fixed final time inputted in the trajectory optimization for minimizing Δ푉 . The corresponding Δ푉 is labeled at the top of each plot.

(a) 푡푓 = 1 s (b) 푡푓 = 20 s (c) 푡푓 = 33 s

(d) 푡푓 = 55 s (e) 푡푓 = 240 s Figure 3-4: Euclidean norm of acceleration components as fraction of the Euclidean norm of total acceleration

Figure 3-5 illustrates the sum of the radial acceleration components with respect to the sum of the tangential acceleration components. According to the second hy- pothesis, these sums should be equivalent between initial and final transients for the fuel-optimal trajectory. The lowest Δ푉 cost is when 푡푓 = 33 seconds, corresponding to Figure 3-6c. Clearly, the radial and tangential accelerations are not equivalent; however, that may be a consequence of the optimization setup. Thus far, Stern- berg’s results supporting his second hypothesis have not been able to be reproduced, which is a matter that requires further investigation to yield any decisive conclusions.

51 Regardless, these plots display a sum of the norms of the acceleration components rather than a comparison of the vector elements. A comparison of the vector ele- ments of the acceleration components is a more physically intuitive relationship to turn to in hopes of deriving any physical relationship between fuel optimality and the acceleration components.

(a) 푡푓 = 1 s (b) 푡푓 = 20 s (c) 푡푓 = 33 s

(d) 푡푓 = 55 s (e) 푡푓 = 240 s Figure 3-5: Sum of Euclidean norm of radial and tangential acceleration components as fraction of the Euclidean norm of total acceleration

It is evident in Figure 3-6 that it is impossible for the vector tangential acceleration to be equivalent to the vector radial acceleration, regardless of if the trajectory is fuel- optimal or not. For a synchronous radial approach, the Chaser is along the Target’s R-bar corresponding to its docking port axis. Thus,

⎡ ⎤ 푥¨ ⎢ ⎥ ⎢ ⎥ ¨퐶퐻퐴 ⎢ ⎥ ⃗푎푙푖푛 = ⃗푟푇 퐴푅 = ⎢ 0 ⎥ . (3.2) ⎢ ⎥ ⎣ ⎦ 0

52 The centripetal acceleration for a flat spin is calculated as

푇 퐴푅 푇 퐴푅 퐶퐻퐴 ⃗푎푐푒푛푡 = ⃗휔퐼푁푇 × (⃗휔퐼푁푇 × ⃗푟푇 퐴푅 ) (3.3a) ⎛⎡ ⎤ ⎡ ⎤⎞ 0 푥 ⎜⎢ ⎥ ⎢ ⎥⎟ ⎜⎢ ⎥ ⎢ ⎥⎟ 푇 퐴푅 ⎜⎢ ⎥ ⎢ ⎥⎟ ⃗푎푐푒푛푡 = ⃗휔퐼푁푇 × ⎜⎢ 0 ⎥ × ⎢ 0 ⎥⎟ (3.3b) ⎜⎢ ⎥ ⎢ ⎥⎟ ⎝⎣ ⎦ ⎣ ⎦⎠ 휔푧 0 ⎡ ⎤ ⎡ ⎤ ⎡ ⎤ 0 0 −휔2푥 ⎢ ⎥ ⎢ ⎥ ⎢ 푧 ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⃗푎푐푒푛푡 = ⎢ 0 ⎥ × ⎢ 휔푧푥 ⎥ = ⎢ 0 ⎥ (3.3c) ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎣ ⎦ ⎣ ⎦ ⎣ ⎦ 휔푧 0 0

Therefore, the radial acceleration components (linear and centripetal) are only nonzero in 푥. It has been established that the angular acceleration is zero for all time

(⃗푎푎푛푔 = ⃗0). The Coriolis acceleration is displayed in the following equations.

푇 퐴푅 ˙퐶퐻퐴 ⃗푎푐표푟 = 2(⃗휔퐼푁푇 × ⃗푟푇 퐴푅 ) (3.4a) ⎡ ⎤ 0 ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⃗푎푐표푟 = ⎢ 휔푧푥˙ ⎥ (3.4b) ⎢ ⎥ ⎣ ⎦ 0

Hence, the tangential acceleration is only nonzero in 푦. Since the elements of the vectors are not equivalent, it cannot be deduced that the tangential and radial accel- eration vectors are equivalent for a fuel-optimal trajectory.

The last set of plots (Figure 3-6) were not presented in Sternberg’s Sc.D. thesis – the vector representation of the radial and tangential accelerations were not shown. The plots in Figure 3-6 indicate that the elements of the radial and tangential ac- celerations are not equivalent for any of the optimizations. In the absence of this information, Sternberg developed his third hypothesis that the first two hypotheses lead to a reduction in optimization complexity. The reduction he refers to is a vector second order differential equation equating the tangential and radial accelerations, shown in Equation 3.5 (equivalent representation in Equation 3.6). The appealing

53 (a) 푡푓 = 1 s (b) 푡푓 = 20 s (c) 푡푓 = 33 s

(d) 푡푓 = 55 s (e) 푡푓 = 240 s Figure 3-6: Vector elements of acceleration components for each generated trajectory

nature of this hypothesis was that a second order differential equation is more com- putationally efficient to solve in-flight than an optimization. Therefore, whilethe equation was promising in terms of in-flight feasibility, it is fundamentally incorrect.

¨퐶퐻퐴 푇 퐴푅 (︁ 푇 퐴푅 퐶퐻퐴)︁ ˙ 푇 퐴푅 퐶퐻퐴 푇 퐴푅 ˙퐶퐻퐴 ⃗푟푇 퐴푅 + ⃗휔퐼푁푇 × ⃗휔퐼푁푇 × ⃗푟푇 퐴푅 = ⃗휔퐼푁푇 × ⃗푟푇 퐴푅 + 2(⃗휔퐼푁푇 × ⃗푟푇 퐴푅 ) (3.5)

To further illustrate that this equation does not produce a fuel-optimal, radial synchronous approach from the Chaser to the Target, a simple simulation was exe- cuted via MATLAB’s ode45. The right-hand side function is shown in Listing 3.1 with the angular velocity hard-coded since the example is a flat spin case and the angular acceleration is zero.

54 ⎡ ⎤ 0 −휔 휔 ⎢ 3 2 ⎥ ⎢ ⎥ ¨퐶퐻퐴 ⎢ ⎥ ˙퐶퐻퐴 I3⃗푟푇 퐴푅 − 2 ⎢ 휔3 0 −휔1 ⎥ ⃗푟푇 퐴푅 + ... ⎢ ⎥ ⎣ ⎦ −휔2 휔1 0 ⎡ ⎤ −휔2 − 휔2 휔˙ + 휔 휔 −휔˙ + 휔 휔 ⎢ 3 2 3 1 2 2 1 3 ⎥ ⎢ ⎥ ⎢ 2 2 ⎥ 퐶퐻퐴 ⃗ ⎢ −휔˙ 3 + 휔1휔2 −휔1 − 휔3 휔˙ 1 + 휔2휔3 ⎥ ⃗푟푇 퐴푅 = 0 (3.6) ⎢ ⎥ ⎣ 2 2 ⎦ 휔˙ 2 + 휔1휔3 −휔˙ 1 + 휔2휔3 −휔1 − 휔2

Listing 3.1: Right-hand side function for call to ode45 to demonstrate the second- order differential equation

1 function zdot = RHS(t,z)

2 omega_TAR_INT=deg2rad( 5/norm([0 0 1])*[0 0 1]');

3 w1 = omega_TAR_INT(1); w2 = omega_TAR_INT(2); w3 = omega_TAR_INT(3);

4 w1dot = 0; w2dot = 0; w3dot = 0;

5

6 w_skew = [0 -w3 w2 ; w3 0 -w1 ; -w2 w1 0];

7 wdot_skew = [0 -w3dot w2dot ; w3dot 0 -w1dot ; -w2dot w1dot 0];

8

9 B = 2*w_skew;

10 C = (wdot_skew - w_skew*w_skew);

11

12 A = [zeros(3), eye(3);

13 C B];

14

15 zdot = A*z;

The initial translational position was [10, 0, 0] and the initial translational velocity was [0, 0, 0]. The simulation was run for 100 seconds and produced the following trajectory in Figure 3-7. The trajectory spirals away from the Target at (0, 0). This example shows that Equation 3.5 does not produce a synchronous radial approach for a Chaser with respect to a tumbling Target.

55 Figure 3-7: Chaser’s trajectory from call to ode45 using Listing 3.1

3.3 Differential Equation Propagator Architecture

A supporting propagator architecture was developed to yield the waypoints of the Chaser’s trajectory to a tumbling Target along the Target’s R-bar provided by solving a given differential equation. This architecture was motivated by Sternberg’s differ- ential equation. Although Equation 3.5 has been proved to be invalid, the propagator architecture is generalizable to any differential equation that results in a synchronous radial approach trajectory. The propagator architecture is documented in this section and was developed to run in the SPHERES simulation. The propagator architecture consists of five sequential steps and outputs the waypoints the Chaser needs to follow. The following subsections elaborate on each of the five steps. In short, the propagator architecture (1) determines when the Chaser should hop along the Target’s R-bar, (2) creates future knowledge of the Target’s rotation in the absence of estimation

56 software, (3) determines the Chaser’s final position of the end of the approach, (4) backwards propagates the differential equation from the final position, and then (5) radially shifts the trajectory of waypoints such that the initial position aligns with the Chaser’s current position. This all occurs before the Chaser aligns itself with the Target’s R-bar and begins the approach. The propagator architecture is encompassed in the file propagator.c, shown in Appendix A.3.

3.3.1 R-Bar Alignment

Figure 3-8 illustrates the necessary initial conditions for starting the propagator: (1) the Chaser is at the desired radial length from the Target, and (2) the Chaser is along the Target’s R-bar. If provided with a model of the Target’s rotation, the propagator can use this information for identifying intersections of the Target’s R-bar with the Chaser at the desired radial length. Alternatively, if the Chaser is not approaching in the correct plane, this step also identifies the future intersection location that requires minimal state change for the Chaser. Provided with a model of the Target’s rotation based on the Chaser’s estimation capabilities, the Chaser can create a future history of the Target’s rotation (Figure 3-9). This future history is multiplied by 180 deg about the Target’s docking axis and is compared with the Chaser’s static quaternion. When the difference between these two quaternions is zero, the Chaser will be aligned with the Target’s R-bar for the associated points in time. For example, if the Target’s docking port is on its x-axis, the propagator finds the quaternion rotated about the z-axis via Equation 3.7.

*,퐶퐻퐴 푇 퐴푅 푞퐼푁푇 = 푞퐼푁푇 ⊗ [0, 0, −1, 0] (3.7)

*,퐶퐻퐴 0,퐶퐻퐴 The times associated with the minimum of 푞퐼푁푇 − 푞퐼푁푇 indicate the future intersection times – these are the times in which the Chaser should start moving synchronously with the Target’s R-bar. The times associated with the intersection locations are graphically illustrated in Figure 3-9. In the current implementation of the propagator architecture, the propagator develops a future history rotation model

57 Figure 3-8: Illustrating the necessary initial conditions for the propagator i.e. the Chaser is at the desired radius and the Chaser is along the Target’s R-bar

Figure 3-9: Timeline illustrating the Chaser’s intersections with the Target’s R-bar at the desired initial radial length away from the Target

of the Target in the absence of the estimation software. Therefore, instead of com- paring the Chaser’s quaternion with each future Target quaternion, the propagator ⃒ ⃒ *,퐶퐻퐴 ⃒ *,퐶퐻퐴 0,퐶퐻퐴⃒ identifies the value of 푞퐼푁푇 and checks at 1 Hz if ⃒푞퐼푁푇 − 푞퐼푁푇 ⃒ < 훿, where 훿 is a user-defined margin. The next step starts once this is satisfied.

58 3.3.2 Forward Propagation

For the full in-space close proximity operations mission, the estimation portion of the software infrastructure will work in-the-loop with this trajectory generator. Based on its observations, it will develop a rotation model of the Target that includes the expected future ⃗휔, ⃗휔,˙ 푞, 푞˙. In the absence of that rotation model, the propagator currently creates its own forward propagation of the Target (up to three periods) based on the Target’s current rotation rate. This forward propagation is graphically depicted by Figure 3-10.

Figure 3-10: Forward propagate Target’s orientation and rotation rate for 푛 periods

The future estimates of the Target’s rotation are found by numerically solving the following equations for up to three periods of rotation.

˙ 푇 퐴푅 −1 푇 퐴푅 푇 퐴푅 ⃗휔퐼푁푇 = 퐼 (푀 − (⃗휔퐼푁푇 × 퐼⃗휔퐼푁푇 )) (3.8a) ⎛⎡ ⎤ ⎞ 1 ⃗휔푇 퐴푅 푇 퐴푅 ⎜⎢ 퐼푁푇 ⎥ 푇 퐴푅⎟ 푞˙퐼푁푇 = ⎝⎣ ⎦ ⊗ 푞퐼푁푇 ⎠ (3.8b) 2 0

푇 퐴푅 푇 퐴푅 For each time step, Euler integration solves the associated ⃗휔퐼푁푇 and 푞퐼푁푇 values. At the end of this step in the propagator architecture, there are three periods worth of 푇 퐴푅 ˙ 푇 퐴푅 푇 퐴푅 푇 퐴푅 future estimates of ⃗휔퐼푁푇 , ⃗휔퐼푁푇 , 푞퐼푁푇 , and 푞˙퐼푁푇 .

3.3.3 Determine Final Position

If the Target has a complex tumble, it may take more than one period of rotation for the Chaser to be able to dock to it. However, for flat spins, the Chaser should be able to dock to the Target in less than one period of rotation. Based on this information,

59 a desired final time (푡푓 ) is selected. The corresponding final Target quaternion is 푇 퐴푅 푞퐼푁푇 (푡푓 ). Therefore, the corresponding final position of the Chaser is determined by

퐶퐻퐴 푇 퐴푅 ⃗푟퐼푁푇 (푡푓 ) = 퐷퐶푀(푞퐼푁푇 (푡푓 ))⃗푟푠푡푎푛푑표푓푓 (3.9)

where ⃗푟푠푡푎푛푑표푓푓 is the user-defined desired position away from the Target at 푡푓 . The variable 퐷퐶푀 denotes the operation that yields a direction cosine matrix provided a quaternion. The relative position of the Chaser to the Target is

퐶퐻퐴 푇 퐴푅 퐶퐻퐴 ⃗푟푇 퐴푅 (푡푓 ) = 푞퐼푁푇 (푡푓 ) ⊗ ⃗푟퐼푁푇 (푡푓 ) (3.10)

The final position of the Chaser relative to the Target is a necessary boundary con- dition for the following step.

3.3.4 Backwards Propagation

퐶퐻퐴 퐶퐻퐴 Now that the necessary boundary conditions have been determined, ⃗푟푇 퐴푅 (0), ⃗푟푇 퐴푅 (푡푓 ), ˙퐶퐻퐴 ⃗푟푇 퐴푅 (푡푓 ) = 0, the backwards propagation – the part of the propagator software that generates the trajectory – is ready to be utilized. This part of the software is currently implemented as a C-function named propagateToTarget and takes eight arrays as inputs. These inputs are described in Table 3.1; the "to-be-trimmed" arrays are short- ened to match the filled-in length of the future Target histories since all arrays were initialized with a length of 2000. After trimming the quaternion and denoting the index corresponding to the filled- in length, the function uses ctrlState and tgtState to compute the Chaser’s position relative to the Target at the current time step. The expected final Target quaternion is converted to a direction cosine matrix and is multiplied by the desired radial standoff

of the Chaser during the last time step. The resulting array is the desired ⃗푟푓 of the Chaser with respect to the inertial frame. Having denoted the desired final position and the initial position, the function enters into a while loop that it can only exit once the radial position is greater

60 Table 3.1: Inputs to propagateToTarget function with descriptions

Input Name Description ctrlState 13-element state array of Chaser tgtState 13-element state array of Target To-be-trimmed 2000 by 3 array of radial_profile radial positions along the trajectory To-be-trimmed 2000 by 3 array of velocity_profile velocity commands along the trajectory To-be-trimmed 2000 by 4 array of Target’s q_TAR_INT_array future quaternions from forward propagation To-be-trimmed 2000 by 4 array of Target’s omega_TAR_INT_array future angular velocity from forward propagation To-be-trimmed 2000 by 4 array of Target’s q_dot_TAR_INT_array future quaternion derivatives from forward propagation To-be-trimmed 2000 by 4 array of Target’s omega_dot_TAR_INT_array future angular acceleration from forward propagation

than 푟0 (the initial radial distance between the Target and Chaser) or the counter of iterations has exceeded the user-defined maximum. The procedure that occurs inthe while loop is

1. Update local variables associated with the Target’s quaternion, quaternion derivative, angular velocity, and angular acceleration using the arrays computed from forward propagation.

2. The skew symmetric matrices for the Target’s angular velocity and angular acceleration are constructed.

3. The A, B, and C matrices from Equation 3.5 are constructed as

퐵 = 2휔× (3.11a)

퐶 =휔 ˙ × − 휔×휔× (3.11b) ⎡ ⎤ 0 ⎢ I ⎥ 퐴 = ⎣ ⎦ (3.11c) 퐶 퐵

where the subscript × indicates the skew-symmetric matrix.

61 4. The state vector ⃗푥 is populated using the current iteration of the Chaser’s posi- 푇 [︁ 퐶퐻퐴 ˙퐶퐻퐴]︁ tion and velocity with respect to the inertial frame, such that ⃗푥 = ⃗푟퐼푁푇 , ⃗푟퐼푁푇 .

5. The computation ⃗푥˙ = 퐴⃗푥 occurs to populate ⃗푥˙. Euler integration then creates 퐶퐻퐴 ˙퐶퐻퐴 an updated ⃗푟퐼푁푇 and ⃗푟퐼푁푇 .

퐶퐻퐴 ˙퐶퐻퐴 푇 퐴푅 6. To find the corresponding ⃗푟푇 퐴푅 and ⃗푟푇 퐴푅 , the quaternion conjugate of 푞퐼푁푇 is determined and used:

퐶퐻퐴 퐼푁푇 퐶퐻퐴 푟푇 퐴푅 = 푞푇 퐴푅 ⊗ 푟퐼푁푇 (3.12a)

퐶퐻퐴 퐼푁푇 퐶퐻퐴 푟˙푇 퐴푅 = 푞푇 퐴푅 ⊗ 푟˙퐼푁푇 (3.12b)

퐶퐻퐴 ˙퐶퐻퐴 7. The updated ⃗푟푇 퐴푅 and ⃗푟푇 퐴푅 values are stored in the variables radial_profile and velocity_profile to be implemented as commands for the Chaser.

3.3.5 Radial Shift

An essential point to consider in implementing the propagator architecture is the choice of the "final states" of the Target based on the future time history constructed in the forward propagation step. For simple rotations (i.e. flat spin), this choice does not matter. However, for complex rotations, this choice becomes more selective in order to maintain minimal fuel cost (an idea left for future work). For simple rotations, the propagator picks the final state from forward propagation. However, backwards propagating from this state will not necessarily yield a radial approach that aligns with the Chaser’s current position (see Figure 3-11). A radial shift must occur in order to align the trajectory’s initial position with the Chaser’s current position. The propagator’s initial position and the Chaser’s initial position are vectors in the inertial frame. The following procedure occurs within the propagateToTarget function to find the rotation matrix. Let the propagator’s position vector be denoted as 퐴 and the Chaser’s current position vector be denoted as 퐵.

62 Figure 3-11: Generated trajectory yielded from 푡푓 from forward propagation prior to radial shift to align initial position with Chaser’s current position

1. Find the unit vector of 퐴 and 퐵.

퐴 퐴^ = (3.13a) ||퐴|| 퐵 퐵^ = (3.13b) ||퐵||

2. Calculate the dot product and the magnitude of the cross product of the unit vectors.

^ ^ 퐴 · 퐵 = 푎1푏1 + 푎2푏2 + 푎3푏3 (3.14a) ⎡ ⎤ 푎 푏 − 푎 푏 ⎢ 2 3 3 2 ⎥ ⎢ ⎥ ^ ^ ⎢ ⎥ 퐴 × 퐵 = ⎢ 푎3푏1 − 푎1푏3 ⎥ (3.14b) ⎢ ⎥ ⎣ ⎦ 푎1푏2 − 푎2푏1 √︁ ^ ^ 2 2 2 ||퐴 × 퐵|| = (푎2푏3 − 푎3푏2) + (푎3푏1 − 푎1푏3) + (푎1푏2 − 푎2푏1) (3.14c)

63 3. Construct the matrix 퐺.

⎡ ⎤ 퐴^ · 퐵^ −||퐴^ × 퐵^|| 0 ⎢ ⎥ ⎢ ⎥ ⎢ ^ ^ ^ ^ ⎥ 퐺 = ⎢ ||퐴 × 퐵|| 퐴 · 퐵 0 ⎥ (3.15) ⎢ ⎥ ⎣ ⎦ 0 0 1

4. Construct the basis change matrix 퐹 .

−1 [︂ ^ ^ ^ ^ ]︂ 퐹 = 퐴^ 퐵−(퐴·퐵)퐴 퐴^ × 퐵^ (3.16) ||퐵^−(퐴^·퐵^)퐴^||

5. Calculate the rotation matrix 푈 = 퐹 −1퐺퐹 .

* * 퐶퐻퐴 * 6. Find 퐴 = 푈퐴, where 퐴 is the updated trajectory position (푟퐼푁푇 (푡) = 퐶퐻퐴 푈푟퐼푁푇 (푡)).

Figure 3-12: Generated trajectory after radial shift with initial position aligned with Chaser’s current position

This is repeated for each position in the radial profile array and is the final output for the propagateToTarget function. Figure 3-12 illustrates the radially-shifted trajectory. Figure 3-13 depicts what this radial shift means in the scheme of the

64 timeline of the synchronous radial approach. This radially-shifted trajectory is used as a series of commanded positions for the Chaser to follow along with the velocity profile that commands the corresponding velocities at each position.

Figure 3-13: Illustration of timeline shift after shifting the radial approach to align with the Chaser’s current position

65 66 Chapter 4

Adaptive Control for Thrust and Inertia Uncertainties

The motivation for the topics discussed in this chapter is the inability for the SPHERES to dock to one another with the UDPs attached aboard the ISS. Moreover, this is- sue is relevant to the ROAM project as a practical application to one of the three reference missions – active debris removal. Realistically, an effective active debris removal effort will involve interacting with unknown Targets or Targets whose well- characterized properties will have changed due to collisions with other debris. This chapter first discusses the test design, results, and analysis of thruster characteriza- tion for the SPHERES free-flyers on the ISS. Second, this chapter provides a detailed description of an adaptive controller robust to uncertainty in knowledge of inertial properties.

4.1 Thruster Degradation Characterization

The addition of the UDP as a peripheral to the SPHERES program inspired hopes of demonstrating the ability for the SPHERES to dock and undock without astronaut involvement. However, the SPHERES team has been unable to demonstrate this capability since checking out the UDPs on station in Test Session 78 in September 2015. The SPHERES team has been investigating this matter and there are two

67 favored possibilities for what is causing the issue: 1) the inertial properties of the aggregated system are incorrect and/or 2) the thrusters have degraded significantly enough that it is causing nontrivial performance issues. This section will focus on the investigation into possible thruster degradation on the satellites on station.

4.1.1 Thruster Characterization in Test Session 97

The thruster dance – a series of commanded thrusts used to characterize the cur- rent performance – was conducted as Test 18 on Test Session 97 (TS97) using the SPHERES platform on the ISS. The thruster dance consisted of pulsing each thruster individually and then the pairs that create torques for three time segments: 50 ms, 100 ms, and 200 ms. As mentioned previously, each satellite has 12 thrusters and are indexed from 0 to 11. The location of each thruster is indicated by its index on Figure 4-1. The thruster force and torque directions (and torque couplings) are shown in Table 4.1.

Figure 4-1: Location and indices of thrusters on satellite with noted exhaust direction

The raw data from this test is shown in the following Figures 4-2a and 4-2b. To better understand and gauge if each thruster is producing a similar level of thrust, the raw accelerometer data was separated by axis and by the duration of the thrust impulse. Figures 4-3a and 4-3b are a series of segregated data plots, separated by satellite, by direction, and by impulse series. The associated thruster with a commanded

68 Table 4.1: Thruster force and torque directions in SPHERES body-fixed frame

Thruster Force Direction Torque Direction Index x y z x y z 0 1 0 0 0 1 0 1 1 0 0 0 -1 0 2 0 1 0 0 0 1 3 0 1 0 0 0 -1 4 0 0 1 1 0 0 5 0 0 1 -1 0 0 6 -1 0 0 0 -1 0 7 -1 0 0 0 1 0 8 0 -1 0 0 0 1 9 0 -1 0 0 0 -1 10 0 0 -1 -1 0 0 11 0 0 -1 1 0 0

Raw IMU data for Sphere logical ID 1 0.1

] x -2

s y 0.05 z

0

-0.05 Accelerometers [m -0.1 10 20 30 40 50 60 70

0.2

0.1

0

x -0.1 y Gyroscopes [rad/s] z

-0.2 10 20 30 40 50 60 70 Test time, s

(a) SPH1 (Blue) (b) SPH2 (Orange) Figure 4-2: Thruster characterization: raw accelerometer and gyroscope data from IMU in test session 97 impulse is denoted on each plot by its thruster index (described in Table 4.1). There are significant spikes in data associated with another thruster’s impulse – thisisa consequence of the impulse ringing the system and can effectively be ignored. The 200 ms accelerometer data provides the cleanest impulse image; the following deductions are based off of the 200 ms plots (Figures 4-3a and 4-3b). Qualitatively, half of the thrusters produce a similar impulse in both Blue and Orange. Orange’s thrusters 0, 6, and 7 produce an impulse larger than their counterparts on Blue; Blue’s

69

] ] -2 -2 Raw IMU data for Sphere logical ID 1 Raw IMU data for Sphere logical ID 2 0.05 0 1 0.05 0 1

0 0

-0.05 6 7 -0.05 6 7

38 40 42 44 46 48 38 40 42 44 46 48

X-Accelerometers [m s [m X-Accelerometers s [m X-Accelerometers

] ]

-2 -2 0.05 2 3 0.05 2 3

0 0

-0.05 8 9 -0.05 8 9

38 40 42 44 46 48 38 40 42 44 46 48

Y-Accelerometers [m s [m Y-Accelerometers s [m Y-Accelerometers

] ]

-2 -2 0.05 4 5 0.05 4 5

0 0

-0.05 10 11 -0.05 10 11 Z-Accelerometers [m s [m Z-Accelerometers Z-Accelerometers [m s [m Z-Accelerometers 38 40 42 44 46 48 38 40 42 44 46 48 Test time, s Test time, s

(a) SPH1 (Blue) (b) SPH1 (Orange) Figure 4-3: Thruster characterization: 200 ms impulse accelerometer data separated by axis

thrusters 3, 4, and 9 produce an impulse larger than their counterparts on Orange. Based on these results, it was concluded that the thrust levels varied between thrusters and more characterization tests were required to more accurately determine the force per thruster.

4.1.2 Thruster Force Characterization

In order to characterize each thruster’s force, existing MATLAB functions developed by the SPHERES team originally used for characterizing the inertial properties of SPHERES satellites with attached peripherals were modified to output the measured force of each thruster of a stand-alone satellite.

Methodology

Three MATLAB functions were used to characterize thruster force: pulse_extraction.m, process_pulses_sph.m, and plot_pulses.m. Additionally, a function revise_pulses.m was created to allow the user to re-do the processing function for specific pulses rather than the whole set. These functions can be found in Appendix B.2. Within pulse_extraction.m, the raw IMU data from Test 18 in TS97 was extracted from its .mat file and placed in various data arrays and organized by

70 its satellite number. The accelerometer data was interpolated to match the length of the gyroscope data and both accelerometer and gyroscope data were smoothed. The thruster commands were extracted from the test data, as well, – the thruster commands are a series of on and off commands to each thruster. Based on this information, time history vectors of when the thrusters were commanded on were constructed for each satellite. The function then determines the maximum pulse length across all the thrusters to use for extracting each pulse. It does so by identifying six stages of the pulse: pre-pulse start, pre-pulse end, during pulse start, during pulse end, post-pulse start, and post-pulse end. The user is then presented with a series of plots of the accelerometer data and is asked to select the start and end of the peak of the impulse (the pulse period). Contrastingly, the function uses the gyroscope data without user input. The function pulse_extraction.m determines acceleration, angular accelera- tion, angular velocity, and change in angular velocity. The average of the accelerom- eter data in the user-selected pulse period is the acceleration (⃗푎푚푒푎푠). The angular acceleration (⃗훼) is determined as the difference between the final gyroscope data and the initial gyroscope data divided by the time period during the user-selected pulse period. The angular velocity (⃗휔) is simply the average of the gyroscope data, and the change in the angular velocity (Δ⃗휔) is the average of the difference of gyroscope data before the pulse and after. This information is stored in a struct for each pulse for each thruster and outputted as a .mat file for each satellite. The function process_pulses_sph.m takes in the pulse .mat files that were created in pulse_extraction.m and outputs the force of each thrusters for each satellite. In order to find the force 퐹푡ℎ푟푢푠푡 = 푚*⃗푎, ⃗푎 must be computed. The function iterates through each pulse and separates this problem into solving for the acceleration in each direction. Thus, for each pulse (푝), the following is computed (using only the 푥-direction in this example):

× × × 푏푥(푝) = 푎푚푒푎푠,푥 − (훼 + 휔 휔 )(1,:)⃗푟푔푐,푥 (4.1a)

퐴푥(푝, :) = 퐴푡ℎ푟푢푠푡(1, [1, 2, 7, 8]) (4.1b)

71 where row 1 of 퐴푥(푝, :) corresponds to the 푥-direction and the columns correspond to 3×12 thrusters acting in 푥, 퐴푡ℎ푟푢푠푡 ∈ R with a 1 corresponding to the thruster direction × and zeros otherwise, 훼 is the skew symmetric matrix of ⃗훼푝 from pulse_extraction.m, × Δ⃗휔 pulse_extraction.m 휔 is the skew symmetric matrix of 2 푝 from , and ⃗푟푔푐,푥 is the position of the 푥-axis accelerometer in SPHERES. Once each pulse is looped through,

12×4 there are three completed matrices (퐴푥, 퐴푦, 퐴푧 ∈ R ) and three completed vectors 12×1 (푏푥, 푏푦, 푏푧 ∈ R ). The calculated acceleration is found via

−1 4×1 푥¨ = 퐴푥 푏푥 ∈ R (4.2) where the first two elements correspond to the thruster’s imparted force andthe second two elements correspond to the thruster’s imparted torque. This calculation occurs for each direction and the first two elements are extracted into a vector of forces associated with the corresponding thruster indices. Additionally, 퐴푥, 퐴푦, 퐴푧,

푏푥, 푏푦, 푏푧, 푎푚푒푎푠, 훼푚푒푎푠, and 휔푚푒푎푠 are placed in a struct and are outputs of this function. Lastly, the function plot_pulses.m takes the results struct created in process_pulses_sph.m and plots the thruster force for each satellite according to thruster index. If the user has low confidence in the result for a thruster or fora handful but does not wish to re-do the entire extraction process, they can utilize revise_pulses.m and re-extract and re-process a selected number of pulses.

Results

Using the aforementioned MATLAB functions and test data from Test 18 in TS97, Figure 4-4 was produced. It is evident that each satellite has thrusters that are per- forming poorly. Each computed thruster force and the ratio of computed to expected is shown in Table 4.2. (Note: the expected thruster force is 0.098 N.) Ratios of less than 0.5 are highlighted in red on the table and ratios between 0.5 and 0.75 are high- lighted in yellow. Of note are the thrusters whose performance is denoted by the red.

72 Thruster Force 0.1

0.09

0.08

0.07

0.06

0.05 Thrust [N] 0.04

0.03

0.02

0.01 Blue Orange 0 0 1 2 3 4 5 6 7 8 9 10 11 Thruster Number

Figure 4-4: Calculated force magnitude of each thruster on Blue and Orange satellites

For Blue, this means that two +푦 torques, two −푥 forces, one +푥 force, and one −푦 torque are performing poorly. For Orange, this indicates that one −푧 torque, one +푧 torque, one −푦 force, and one +푦 force are under-performing. These results are concerning since they imply that the satellites have an insignificant amount of control authority in the noted directions. Based on these conclusions, a maintenance session was designed to perform a thruster characterization test for Blue, Orange, and Red in addition to testing new mixers (via a handful of translational and attitude sequences) the SPHERES team designed based on knowledge of thruster characterization before the session.

4.1.3 Maintenance Session

Three types of tests were designed and run during the maintenance session: open-loop thruster characterizations, closed-loop translational and orientation maneuvers with new mixers, and a thruster manifold test. For this test session, three satellites were used (Blue, Orange, Red). The goals of the maintenance session were threefold:

(1) to produce a secondary thruster characterization for Blue and Orange and a

73 Table 4.2: Calculated thruster forces for each satellite and ratios of calculated thruster force divided by expected force for each satellite

Force Torque Blue: Blue: Orange: Orange: Thr. # Direction Direction Force [N] Ratio Force [N] Ratio 0 +x +y 0.020 0.204 0.0851 0.868 1 +x -y 0.0853 0.870 0.0903 0.921 2 +y +z 0.0794 0.810 0.0681 0.695 3 +y -z 0.0873 0.891 0.0089 0.091 4 +z +x 0.0993 1.1013 0.0907 0.925 5 +z -x 0.0784 0.800 0.0766 0.782 6 -x -y 0.0223 0.228 0.0709 0.723 7 -x +y 0.0402 0.410 0.0795 0.811 8 -y -z 0.0759 0.774 0.0711 0.725 9 -y +z 0.0946 0.965 0.0150 0.153 10 -z -x 0.0935 0.954 0.0895 0.913 11 -z +x 0.0632 0.645 0.0563 0.574

primary one for Red since it had not been utilized in several years

(2) to evaluate the performance of new mixers designed for each satellite based on previous thruster characterization

(3) to evaluate if the thruster manifolds in each satellite were behaving as expected.

In this section, the first two points are discussed but no analysis has occurred for the thruster manifold test at this time. This maintenance session occurred as Test Session 101 (TS101) in June 2018 and consisted of 16 tests, described in Table 4.3.

Thruster Characterization

Tests 1-9 were simply thruster characterization tests split into the separate planes and for three different lengths of time: 50 ms, 100 ms, and 200 ms. The SPHERES team performed the analysis on the resulting sets of data using the functions described in Section 4.1.2. This analysis culminated in Figure 4-5, which shows the measured thruster force per thruster per satellite and references the nominal force as 0.088 N (an already degraded value from the thruster’s datasheet value of 0.098 N). Illustratively, it is clear that each satellite suffers from at least one seriously degraded thruster. For Red, thruster 0 outputted 0.002 N, meaning its ability to thrust in the +푥 direction

74 Table 4.3: Test session 101 descriptive list of tests executed

Test # Description 1 Open-Loop X-Y Plane (200 ms) 2 Open-Loop X-Z Plane (200 ms) 3 Open-Loop Y-Z Plane (200 ms) 4 Open-Loop X-Y Plane (100 ms) 5 Open-Loop X-Z Plane (100 ms) 6 Open-Loop Y-Z Plane (100 ms) 7 Open-Loop X-Y Plane (50 ms) 8 Open-Loop X-Z Plane (50 ms) 9 Open-Loop Y-Z Plane (50 ms) 10 Thruster Manifold Test 11 Closed-Loop X Translate 12 Closed-Loop Y Translate 13 Closed-Loop Z Translate 14 Closed-Loop X Rotate 15 Closed-Loop Y Rotate 16 Closed-Loop Z Rotate

and torque about +푦 is severely crippled. For Orange, thruster 3 outputted 0.008 N and thruster 9 outputted 0.014 N – its ability to thrust in +푦 and −푦 is limited and is crippled for torquing about −푧. For Blue, thruster 0 outputted 0.023 N, thruster 6 outputted 0.015 N, and thruster 7 outputted 0.032 N, meaning it has limited ability to thrust in +푥 and −푥 and is at a disadvantage for torquing about −푦 and +푦. These conclusions are based on the force and torque directions outlined in Table 4.2.

Figure 4-5: Test session 101: calculated force of each thruster and each satellite

75 Mixer Validation

Based on the thruster characterization results prior to this test session, the SPHERES team developed an individual mixer for Blue, Orange, and Red. Similar to the pre- vious standard mixer, these individualized mixers took in the desired control effort from the controller and outputted the necessary thruster on/off commands. However, the team modified each one to consider the limited performance of certain thrusters on the different satellites, thereby changing the force matrix for each one. Hypothet- ically, this would help in achieving the desired position or orientation. In order to test these mixers, a series of closed-loop tests for each translation and orientation direction were completed in TS101.

Each closed-loop test consisted of four maneuvers. For all tests, maneuver 1 was 10 seconds allotted for estimator convergence and the satellite’s initial position was copied to memory as the position to return to in maneuver 4. For all tests, maneuver 2 commanded each satellite to hold its initial position and orientation. Maneuver 3 varied for each test as it consisted of the translational or reorientation command. For the translation tests, maneuver 3 commanded each satellite to translate by +0.3 m in the respective direction of the test. For the rotation tests, maneuver 3 commanded each satellite to rotate +90 deg about the respective rotation axis. For all tests, maneuver 4 commanded each satellite back to its original position and orientation.

The following portion of this section will discuss the results of each closed-loop test in turn. First, two instances of the closed-loop translation in 푥 were run, both of which yielded poor results. The best results for each satellite are presented in the following figures. From Figure 4-6a, it is shown that Blue did not reachthe commanded 푥-position in the allotted time. By the end of maneuver 3, it should have moved +0.3 m from its initial position in maneuver 1, and then returned to that initial position by the end of maneuver 4. At the end of maneuver 4, it is still increasing in +푥 and does not return to its initial position. This indicates that the mixer was not able to compensate for the thruster degradation in thruster 0, as illustrated in Figure 4-5. Orange’s performance during this test is shown in Figure 4-6b. During

76 maneuver 3, it is hypothesized that the satellite would have been able to reach the commanded position if more time had been permitted. Not surprisingly based on Figure 4-5, Red struggled to move in the +푥 direction but quickly translated in −푥 (Figure 4-6c), indicating that the mixer was not able to compensate for its crippled +x thruster (thruster 0). The results for the closed-loop test for translation in 푥 were underwhelming in part due to too little time allotted for the maneuver and crippled thrusters. It would be worthwhile to investigate the performance with more permitted time per maneuver.

(a) Blue: position telemetry (b) Orange: position telemetry

(c) Red: position telemetry Figure 4-6: Test 11: closed-loop x-translation telemetry

The closed-loop translation in 푦 test yielded more promising results. Figure 4-7a illustrates the results for Blue. Blue was able to translate +0.3 m in the 푦-direction and then −0.3 m back. This is not surprising based on the thruster characterization results indicating no issues with Blue’s ±푦 thrusting prior to the new mixer. Or- ange’s results are shown in Figure 4-7b and indicate that the new mixer was able to overcome Orange’s limited thrust capability in +푦 but not in −푦, evident by no indication that Orange started to move in −푦 before the test ended. Lastly, Red’s performance is illustrated by Figure 4-7c, which indicates Red was able to complete

77 the commanded maneuvers without any issue – unsurprising since its ±푦 thrusters were without significant degradation.

(a) Blue: position telemetry (b) Orange: position telemetry

(c) Red: position telemetry Figure 4-7: Test 12: closed-loop y-translation telemetry

Similarly, the closed-loop translation in 푧 test yielded acceptable results as ex- pected since there was minimal degradation in any of the ±푧 thrusters; the mixers were modified minimally. Figure 4-8a indicates that Blue completed the +0.3 m translation and −0.3 m translation back to its original position without issue in the allotted maneuver time. According to Figure 4-8b, Orange smoothly followed the +0.3 m command but struggled to return to its initial position. Since the thruster characterization did not indicate a significant thruster degradation in Orange’s −푦 thrusters, a potential solution is to tweak Orange’s mixer appropriately. Lastly, Fig- ure 4-8c indicates that Red fell short of meeting the commanded position due to the maneuver ending, but it was able to return to its initial position in the allotted time. Overall, these results were acceptable and a validation of each mixer in terms of 푧-translation capabilities. For each rotation test, each satellite was commanded to rotate +90 deg about the relevant axis and then −90 deg back to its original orientation. From Figure 4-9a,

78 (a) Blue: position telemetry (b) Orange: position telemetry

(c) Red: position telemetry Figure 4-8: Test 13: closed-loop z-translation telemetry it is evident that Blue had no issue performing the desired roll maneuver, indicating that with its new mixer it is able to overcome any torque deficiencies from thruster loss-of-effectiveness. Similarly, Orange completed the roll maneuver in the allotted time with slightly more trouble than Blue – an issue that can be resolved by revising its mixer (Figure 4-9b). Figure 4-9c also displays that Red had no issue meeting the commanded roll maneuver in the allowed time. Overall, all three satellites were able to complete roll maneuvers with their individualized mixers. The next rotation test was the pitch maneuver. Based on the thruster character- ization, Blue (prior to the mixer revision) was expected to perform poorly. However, Figure 4-10a indicates that the updated mixer helped Blue complete the ±90 deg pitch maneuver. Orange’s position and attitude telemetry in Figure 4-10b suggests a collision or manual impulse occurred at the beginning of the test. However, Orange still satisfactorily completed the commanded attitude changes in maneuvers 3 and 4 of this test. Red’s performance during the pitch maneuver proved to be particularly interesting. As displayed on Figure 4-5, Red’s thruster 0 practically produced no thrust, which is of concern for a pitch maneuver since it is one of the +푦 torquers.

79 (a) Blue: attitude telemetry (b) Orange: attitude telemetry

(c) Red: attitude telemetry Figure 4-9: Test 14: closed-loop x-rotation telemetry

Despite this handicap and in combination with Red’s updated mixer, Red completed the pitch maneuver within the timeframe of the maneuvers (Figure 4-10c).

(a) Blue: attitude telemetry (b) Orange: attitude telemetry

(c) Red: attitude telemetry Figure 4-10: Test 15: closed-loop y-rotation telemetry

80 The last closed-loop test conducted on TS101 was the yaw maneuver, in which each satellite was commanded to rotate ±90 deg about its 푧-axis. Figure 4-11a shows that Blue performed the yaw maneuver well and finished with a few seconds to spare. Unfortunately, Orange performed poorly, taking a longer period of time to reach the +90 deg rotation and overshooting the command, leaving little time to return to the original orientation (Figure 4-11b). This suggests that Orange’s thruster degradation cannot be compensated for by a modified mixer. Lastly, Red’s yaw maneuver is shown in Figure 4-11c, which performed exceptionally.

(a) Blue: attitude telemetry (b) Orange: attitude telemetry

(c) Red: attitude telemetry Figure 4-11: Test 16: closed-loop z-rotation telemetry

Conclusively, the modified mixers proved to help complete desired maneuvers de- spite thruster degradation for Blue and Red in all tests except 푥-translation. Orange, however, struggled in several of the maneuvers despite the new mixer. From this test session, Orange was elected to return to ground for thruster replacement.

81 4.2 In-Flight Adaptive PID Sliding Mode Position and Attitude Controller

Future spacecraft operations, such as debris capture and autonomous in-orbit ser- vicing, will require spacecraft to interact with objects with poorly defined inertial properties which introduce a large degree of uncertainty into the dynamics of such operations. To handle this uncertainty, this section describes the development and validation of a mass property-resilient controller for position and attitude control of a free-flying spacecraft. Specifically, the proportional-integral-derivative (PID) sliding mode controller (SMC) was developed to account for inaccurate knowledge of mass properties of small spacecraft, using sliding mode variables for each axis and an adap- tive determination of the appropriate integral and derivative gains to achieve a com- manded motion. The controller was validated both in simulation and in ground-based tests on the SPHERES (Synchronized Position Hold Engage Reorient Experimental Satellites) platform, small free-floating autonomous satellites used to study precision navigation and maneuvering. The SPHERES was commanded to follow a specified series of maneuvers using the PID SMC, to assess the convergence time of the sliding variables, gain values and commanded state parameters in each maneuver. In order to provide resilience to mass properties, sliding mode control and adaptive control were utilized. By using sliding mode and adaptive control techniques, the controller gains and the characteristic coefficients of the system’s equations of motion were found in-flight using adaptation equations (differential equations that update the gains and coefficients based on a sliding variable). These values updated throughout the course of each test to converge the system to the desired state [39]. The controller detailed in this section was designed using the linearized SPHERES’s translational dynamics (equivalent to that of a mass-spring-damper system) and the linearized SPHERES’s attitude dynamics (a double integrator). Although this con- troller was designed specifically for SPHERES, a similar derivation process canbe performed based on the dynamics of the system in question. Additionally, this type of controller has wider applications in the field of autonomous free-flying spacecraft

82 beyond the SPHERES program. Autonomous spacecraft proximity operations such as docking, in-orbit servicing, and space debris capture, will comprise a large part of future space operations. In such cases, inertial properties of the spacecraft or compo- nent being interacted with may not be fully defined and will impact the dynamics of the free-flying satellite. Use of a mass property resilient-controller allows the system to adaptively adjust its gains to account for this uncertainty. To illustrate the performance of the PID SMC under unknown or uncertain mass property knowledge, the static PID controller with incorrect mass property knowledge was used for the same tests. This comparison for both the simulation and hardware tests emphasizes that the PID SMC offers significantly better performance overa static PID controller under the circumstance of incorrect/uncertain mass property knowledge since the PID SMC does not rely on this information.

4.2.1 Problem Formulation

In constructing a mass property-resilient controller, an intuitive approach was to apply sliding mode control since SMCs reduce a system to first order. SMC forces a system’s trajectory to slide along a subspace 푠 ≡ 0, where 푠 is the sliding mode variable of the

푑 푛−1 form 푠 = ( 푑푡 +휆) 푥˜ and 푛 is the order of the system. The variable 푥˜ is the difference between the current position and the desired position and 휆 is a strictly positive, user-defined constant that is experimentally selected. Once the sliding variable is equivalent to zero, the system continues to slide along that subspace until a new state is commanded. Moreover, adaptive control used with SMC is advantageous since it allows for updating controller gain values and mass property parameters [39]. The derivation for the controllers was completed for a six degree of freedom en- vironment, since SPHERES has a microgravity testbed aboard the ISS, as discussed previously. The following derivation used a proportional-integral-derivative (PID) control law and yielded three adaptation laws for both position and attitude control, resulting in a total of eight laws implemented into the final aggregated control system. Each law has a tunable, positive parameter selected via repetitive experimentation to determine which value provided rapid convergence. Stability of the control and

83 adaptation laws was verified by applying Barbalat’s Lemma to a candidate Lyapunov function [39]. In this section, the derivation of the eight laws are detailed as well as the verification that stability is ensured.

Position Control

The translation dynamics in 푥, 푦, and 푧 of a SPHERES satellite are described by the following system (푚⃗푎 = 푢 decomposed into axis-specific equations), where 푢 repre- sents the control input. The 훼 and 훽 constants represent the spring and dampening coefficients (normalized by the mass) for a SPHERES’s satellite.

푥¨ + 훼푥푥˙ + 훽푥푥 = 푢푥 (4.3a)

푦¨ + 훼푦푦˙ + 훽푦푦 = 푢푦 (4.3b)

푧¨ + 훼푧푧˙ + 훽푧푧 = 푢푧 (4.3c)

As seen from the above equations of motion, this system is order 푛 = 2, so the general form of the sliding variable is

푠 = 푥˜˙ + 휆푥˜ =푥 ˙ − 푥˙푟 (4.4)

where 푥˜ is the difference between the current position and the desired position (푥푑)

and 푥˙푟 =푥 ˙ 푑 − 휆푥˜. The following derivation is for the translation in the 푥-axis, so 푠

is denoted as 푠푥.

푠˙푥 =푥 ¨ − 푥¨푟 (4.5a)

푠˙푥 = −훼푥푥˙ − 훽푥푥 + 푢푥 − 푥¨푟 (4.5b)

푠˙푥 = 푢푥 − 푥¨푟 − 푌푥⃗푎푥 (4.5c) ⎡ ⎤ 훼푥 ⎢ ⎥ where 푌푥 = [푥, ˙ 푥] and ⃗푎푥 = ⎣ ⎦ 훽푥

In order to drive 푠˙푥 to 0, let 푢^푥 = 푌푥푎^푥 +푥 ¨푟 to counteract the unknown constants.

84 Additionally, a PID control law is desired, so let

푢푥 =푢 ^푥 − 푢푥,푃 퐼퐷 (4.6) ∫︁ ^ ^ 푢푥,푃 퐼퐷 = 퐾푝,푥푠푥 + 퐾푖,푥 푠푥푑푡 + 퐾푑,푥푠˙푥 (4.7)

^ ^ In Equation 4.7, 퐾푝,푥 is a positive constant, but 퐾푖,푥 and 퐾푑,푥 can be either positive or negative and change via adaptation laws that are yielded from the Lyapunov

candidate function. This simplifies 푠˙푥 to Equation 4.8.

˜ 푠˙푥 = 푌푥⃗푎푥 − 푢푥,푃 퐼퐷 (4.8)

A candidate Lyapunov function for this system and its derivative are derived below. This Lyapunov function needs to be positive definite in order to use Barbalat’s Lemma to analyze the system stability.

1 1 1 1 푉 = 푠2 + 훾−1퐾˜ 2 + 훾−1퐾˜ 2 + 푎˜푇 Γ−1푎˜ (4.9a) 푥 2 푥 2 1 푖,푥 2 2 푑,푥 2 푥 1 푥 ∫︁ ˙ ˜ 2 ^ ^ 푉푥 = 푠푥푌푥⃗푎푥 − 퐾푝,푥푠푥 − 퐾푖,푥푠푥 푠푥푑푡 − 퐾푑,푥푠푥푠˙푥 + ...

−1 ˜ ^˙ −1 ˜ ^˙ ˙ 푇 −1 훾1 퐾푖,푥퐾푖,푥 + 훾2 퐾푑,푥퐾푑,푥 + 푎^푥 Γ1 푎˜푥 (4.9b) ^˙ 푇 =⇒ Adaptation Law 1: ⃗푎푥 = −Γ1푌푥 푠푥 (4.9c) ∫︁ ˙ 2 ^ ^ =⇒ 푉푥 = −퐾푝,푥푠푥 − 퐾푖,푥푠푥 푠푥푑푡 − 퐾푑,푥푠푥푠˙푥 + ...

−1 ˜ ^˙ −1 ˜ ^˙ 훾1 퐾푖,푥퐾푖,푥 + 훾2 퐾푑,푥퐾푑,푥 (4.9d)

˙ To use Barbalat’s Lemma, 푉푥 needs to be negative definite. To ensure this is always true, the following two adaptation laws are derived, as well.

∫︁ ^˙ =⇒ Adaptation Law 2: 퐾푖,푥 = 훾1푠푥 푠푥푑푡 (4.10a) ^˙ =⇒ Adaptation Law 3: 퐾푑,푥 = 훾2푠푥푠˙푥 (4.10b)

^ ^ ^ ˙ When the three adaptation laws are used to update the values of ⃗푎푥, 퐾푑, and 퐾푖, 푉푥 is guaranteed to be negative definite.

85 ˙ Since 푉푥 is negative definite and 푉푥 is positive definite, it is determined that 푉푥 ˜ ˜ is bounded, and therefore, 푠푥, 퐾푖,푥, 퐾푑,푥, and 푎˜푥 are bounded. It is straightforward ¨ to show that 푉푥 is bounded based on the previously determined bounded variables ˙ from 푉푥. By Barbalat’s Lemma, 푉푥 → 0 as 푡 → ∞, which implies that 푠푥 → 0, as well [39]. Thus, these three adaptation laws in addition to the PID control provide a stable sliding mode controller solution for position control. The same proof can be used for the 푦 and 푧 position dynamics and would produce the same result for appropriately subscripted terms unique to 푦 and 푧.

Attitude Control

The attitude dynamics of the satellite are described by 퐽⃗훼¨ = ⃗휏, where ⃗훼 = [휓, 휃, 휑]푇 (which correspond to roll, pitch, and yaw, respectively) and ⃗휏 is the control input. This is decomposed into the following equations per axis.

¨ ¨ ¨ 퐽11휓 + 퐽12휃 + 퐽13휑 = 휏휓 (4.11a) ¨ ¨ ¨ 퐽21휓 + 퐽22휃 + 퐽23휑 = 휏휃 (4.11b) ¨ ¨ ¨ 퐽31휓 + 퐽32휃 + 퐽33휑 = 휏휑 (4.11c)

The following derivation is for the attitude about the 푧-axis, denoted by 휑. Similar to the derivation for position, this system has order 푛 = 2, so the sliding variable is ˜˙ ˜ ˙ ˙ defined as 푠휑 = 휑 + 휆휑 = 휑 − 휑푟. For increased simplicity in the derivation, the term

퐽33푠휑 is used in the derivation.

¨ ¨ 퐽33푠˙휑 = 퐽33휑 − 퐽33휑푟 (4.12a) ¨ ¨ ¨ 퐽33푠˙휑 = 휏휑 − 퐽31휓 − 퐽32휃 − 퐽33휑푟 (4.12b) ⃗ 퐽33푠˙휑 = 휏휑 − 푌휑퐽휑 (4.12c) ⎡ ⎤ 퐽 ⎢ 31 ⎥ [︁ ]︁ ⎢ ⎥ ¨ ¨ ¨ ⃗ ⎢ ⎥ where 푌휑 = 휓, 휃, 휑푟 and 퐽휑 = ⎢ 퐽32 ⎥ ⎢ ⎥ ⎣ ⎦ 퐽33

86 ⃗^ In order to drive 푠˙휑 to 0, let 휏^휑 = 푌휑퐽휑. Since a PID control law is desired, let

휏휑 =휏 ^휑 − 휏휑,푃 퐼퐷 (4.13) ∫︁ ^ ^ 휏휑,푃 퐼퐷 = 퐾푝,휑푠휑 + 퐾푖,휑 푠휑푑푡 + 퐾푑,휑푠˙휑 (4.14)

^ ^ In Equation 4.14, 퐾푝,휑 is a positive constant, but 퐾푖,휑 and 퐾푑,휑 can be either positive or negative and change via adaptation laws yielded from the Lyapunov candidate function.

⃗ 퐽33푠˙휑 =휏 ^휑 − 휏휑,푃 퐼퐷 − 푌휑퐽휑 (4.15a) ⃗^ ⃗ 퐽33푠˙휑 = 푌휑퐽휑 − 푌휑퐽휑 − 휏휑,푃 퐼퐷 (4.15b) ⃗˜ 퐽33푠˙휑 = 푌휑퐽휑 − 휏휑,푃 퐼퐷 (4.15c)

A candidate Lyapunov function for this system and its derivative are derived below.

1 1 1 1 ˜ ˜ 푉 = 퐽 푠2 + 훾−1퐾˜ 2 + 훾−1퐾˜ 2 + 퐽⃗푇 Γ−1퐽⃗ (4.16a) 휑 2 33 휑 2 3 푖,휑 2 4 푑,휑 2 휑 2 휑 ∫︁ ˙ ⃗˜ 2 ^ ^ 푉휑 = 푠휑푌휑퐽휑 − 퐾푝,휑푠휑 − 푠휑퐾푖,휑 푠휑푑푡 − 푠휑퐾푑,휑푠˙휑 + ... ˙ −1 ˜ ^˙ −1 ˜ ^˙ ⃗^푇 −1 ⃗˜ 훾3 퐾푖,휑퐾푖,휑 + 훾4 퐾푑,휑퐾푑,휑 + 퐽휑 Γ2 퐽휑 (4.16b) ^˙ 푇 =⇒ Adaptation Law 1: 퐽휑 = −Γ2푌휑 푠휑 (4.16c) ∫︁ ˙ 2 ^ ^ =⇒ 푉휑 = −퐾푝,휑푠휑 − 푠휑퐾푖,휑 푠휑푑푡 − 푠휑퐾푑,휑푠˙휑 + ...

−1 ˜ ^˙ −1 ˜ ^˙ 훾3 퐾푖,휑퐾푖,휑 + 훾4 퐾푑,휑퐾푑,휑 (4.16d)

˙ To ensure that 푉휑 is negative definite, the following two adaptation laws are derived, as well.

∫︁ ^˙ =⇒ Adaptation Law 2: 퐾푖,휑 = 훾3푠휑 푠휑푑푡 (4.17a) ^˙ =⇒ Adaptation Law 3: 퐾푑,휑 = 훾4푠휑푠˙휑 (4.17b)

87 ^ ^ ^ When the three adaptation laws are used to update the values of 퐽휑, 퐾푖,휑, and 퐾푑,휑, ˙ 푉휑 is guaranteed to be negative definite. Therefore, by the same logic as from the position control derivation, these three adaptation laws in addition to the PID control law provide a stable sliding mode controller solution for attitude control.

The same proof can be used for 휓 and 휃 attitude dynamics and would produce the same result with appropriately subscripted terms unique to 휓 and 휃.

4.2.2 Software and Hardware Implementation

To validate the control and adaptation laws, a sequence of maneuvers, described in Table 4.4, were defined and conducted both in simulation and on a ground-based testbed with three degrees of freedom (two translational and one rotational). Each maneuver commanded the SPHERES to reach a certain (푥, 푦) position on the glass table, while maintaining a commanded attitude, before moving on to the next ma- neuver. To allow flexibility in how long the satellite took to reach the maneuver’s endpoint, the software terminated a current maneuver and commanded the next ma- neuver only if the satellite stayed within 2.5 cm of the desired endpoint (in both 푥- and 푦-directions) for 5 seconds. Each maneuver also had an upper time limit, after which the maneuver was terminated and the satellite was commanded to the next position. Note that Maneuver 1 was an estimator convergence maneuver, where the satellite remained stationary to allow for accurate localization of its position and attitude before beginning the commanded maneuvers.

An extensive sweep of possible parameter values via numerous simulation runs was used to determine the final parameter values used for the simulation and hardware testing based on which provided the best performance. The following parameters yielded the quickest response time without overshooting in simulation. Note that in the 3-DOF implementation of this controller, the user-defined position control

88 Table 4.4: Sequential series of maneuvers and corresponding commanded position and quaternion

Maneuver Position (x,y) [m] Quaternion 1 N/A (1, 0, 0, 0) 2 (0, -0.25) (1, 0, 0, 0) 3 (0, 0) (1, 0, 0, 0) 4 (0, 0.25) (1, 0, 0, 0) 5 (0.25, 0.25) (1, 0, 0, 0) 6 (0.25, 0) (1, 0, 0, 0) 7 (0, -0.25) (1, 0, 0, 0) 8 (0.125, 0) (1, 0, 0, 0) 9 (0.25, 0.25) (1, 0, 0, 0)

parameters were used for both the 푥 and 푦 translation.

Position Control

휆1 = 0.085, 훾1 = 60, 훾2 = 80, ⎡ ⎤ 10 0 0 ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ 퐾푝,푥 = 1000, Γ1 = ⎢ 0 10 0 ⎥ ⎢ ⎥ ⎣ ⎦ 0 0 10

Attitude Control

휆2 = 0.10, 훾3 = 4, 훾4 = 2, ⎡ ⎤ 10 0 0 ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ 퐾푝,휑 = 50, Γ2 = ⎢ 0 10 0 ⎥ ⎢ ⎥ ⎣ ⎦ 0 0 10

The control and adaptation laws described in the previous section were imple- mented within the SPHERES framework as a substitution for the default controller. The sequence of maneuvers described in Table 4.4 was defined as a test file that in- corporated the standard infrastructure of the SPHERES programming. Therefore, during the execution of this test, the standard infrastructure handled the satellite’s state vector and computed the state error. Once the state error was calculated, a call to the PID SMC was made. A high-level description of the sequence of computations

89 that occurred in the controller is displayed in Figure 4-12. In this figure (and in the subsequent sections of this paper), 푝 is used as a generic variable representing 푥, 푦, and 휑 for brevity. Note that the flowchart provides the numerical equations implemented for computing the integral term of the sliding variable as well as the derivative. Specifically, the integral terms are not integrated in addition to thenu- merical integration equation, but are provided as a reference to the terms derived in the previous section.

4.2.3 Results & Discussion

This section describes the results yielded from the previously derived position and attitude PID SMC with the above parameters. First, the results from simulation are shown and discussed, and then the results from hardware testing are shown and discussed.

Simulation

Simulation tests were run using the SPHERES simulation and flight software together with the implemented PID SMC. The simulation was limited to a three degrees of freedom test using a mass model that incorporated the air bearing stand that the SPHERES are held on for ground tests. Thus, the simulation aligns with the hardware ground test as closely as possible. Figure 4-13a shows the 푥-position, 푦-position, and 푦푎푤 attitude commands and response of the satellite during the simulation. The vertical magenta lines indicate a new maneuver has been commanded (i.e. a new commanded position and attitude). As described in the previous section, the satellite is permitted to move on to the next maneuver once it stays within a 2.5 cm tolerance of the commanded position for 5 seconds. In the simulation the satellite was consistently able to meet this condition, converging to the commanded position and attitude and subsequently terminating each maneuver after 5 seconds. This is evident in Figure 4-13a where the satellite takes approximately 20 seconds to converge to the commanded state and holding for

90 Start Controller Call

Convert quaternions to Euler angles

Compute Δt ( spdt) = ( spdt) + (sp,j−2 + sp,j−1) ∫ j ∫ j−1 2

Compute. sp,j = ˜pj + λ˜pj

Compute. . . . ˜pj − ˜pj−1 sp,j = + λ˜p Δt j

Construct Yp matrix

Compute . . . ˆ ˆ ˆap, K i,p, K d,p

Numerically integrate to find ˆ ˆ ˆap, K i,p, K d,p

Compute control laws up = ˆup − up,PID

End Controller Call

Figure 4-12: Flowchart of the in-flight adaptive PID sliding mode controller asim- plemented in C-code

5 seconds before moving on.

In order to verify that the PID SMC provides a better control solution to the scenario in which uncertain mass properties exist, the PID SMC results are com- pared against results from the static PID controller given incorrect mass properties. The position and attitude results from such a scenario are shown in Figure 4-13b.

91 Time vs. X-Position 0.5

0

Position [m] Measured Commanded Maneuver -0.5 0 50 100 150 200 250 300 350 400 Time [s] Time vs. Y-Position 0.5

0 Position [m]

-0.5 0 50 100 150 200 250 300 350 400 Time [s] Time vs. Yaw 200

150

100

50

0 Attitude [deg] -50

0 50 100 150 200 250 300 350 400 Time [s]

(a) Adaptive PID SMC (b) Static PID Figure 4-13: A comparison of commanded position and attitude vs. measured teleme- try from simulation

Note that with this static PID controller, the test took roughly 425 seconds to reach completion — 200 seconds longer than it took for the PID SMC. Additionally, the position and attitude overshoot on every new command.

Recall that the sliding variable is found via

푠푝 = 푝˜˙ + 휆푝˜ (4.18)

where 푝˜ = 푝 − 푝푑.

Additionally, recall that the goal of the sliding mode controller is for the sliding variable to converge to zero (indicating that the system has converged to the desired position/attitude). Thus, when viewing the time history of the sliding variables (i.e. Figure 4-14a), the goal is for the variable to converge to zero by the end of the maneuver. When the position or attitude command between maneuvers changes, it is expected for the sliding variable to jump to a new value. Naturally, this change is proportional in magnitude and direction as the new command compared to the old command.

92 (a) Sliding Variables (b) Gain Values Figure 4-14: Adaptive PID SMC time histories corresponding to position and attitude from simulation

Figure 4-14a illustrates how the 푠푝 variable changes throughout the course of the test. Since the sliding variable was not used during the first maneuver (estimator convergence) of the test, this maneuver is not included in the figure. The sliding variables associated with the 푥 and 푦 positions are consistent with the desired behavior whereas the sliding variable associated with the 푦푎푤 attitude is not. The sliding variables 푠푥 and 푠푦 converge to zero by the end of each maneuver and reset as expected per new command at a new maneuver. However, 푠휑 exhibits significant chattering about 푠휑 = 0, indicating that the variable overshoots zero and enters a limit cycle as it repeats the overshoot. This behavior was not fixable via parameter tuning, but itis expected that if the attitude sliding mode controller was re-designed with a boundary layer in the sliding variable, this behavior would subside.

The adaptation laws are of the following form:

^˙ 푇 ⃗푎푝 = −Γ푌푝 푠푝 (4.19)

∫︁ ^˙ 퐾푖,푝 = 훾푖푠푝 푠푝푑푡 (4.20)

93 ^˙ 퐾푑,푝 = 훾푑푠푝푠˙푝. (4.21)

Each adaptation law contains the sliding variable; therefore, as the sliding variable converges to zero, it is expected that these derivative terms converge to zero, meaning the adaptation term and gain values converge to some constant value per command. Figure 4-14b illustrates how the 퐾^ values change for each degree of freedom through the course of the test. Convergence to a constant value is evident for the ^ ^ 퐾푑 and 퐾푖 values for the 푥 and 푦 positions. However, for the 푦푎푤 attitude gains, ^ the 퐾푑 value keeps increasing across all maneuvers. This issue is correlated with the chattering behavior in Figure 4-14a and is discussed in more detail later in this paper. The 푥-푦 plot in Figure 4-15 shows the satellite’s trajectory as it attempted to reach each position for both the PID SMC and the default PID controller. In the figure, the asterisk markers indicate the satellite’s position at the beginning ofeach maneuver. Although the commands are only associated with specific positions the satellite is to reach by the end of each maneuver without explicitly defining the trajectory, there exists an implied commanded trajectory, i.e. the shortest distance between the position of the previous maneuver with that of the current maneuver. With the PID SMC, the satellite closely matches this implicit trajectory as it reaches each commanded position. However, when the satellite is equipped with the default PID controller, it overshoots each commanded endpoint, illustrating that the PID SMC offers better performance.

Hardware

Hardware tests were run using the glass table for SPHERES testing in the Space Systems Laboratory. The satellite was fastened to an air bearing stand in order to minimize friction with the table. The same flight software was loaded on the SPHERES as was used in the simulation. Again, this setup is restricted to three degrees of freedom (푥, 푦 and 푦푎푤). From this testing, four datasets were produced, all of which are shown in Figure 4-16a; however, only dataset 4 is discussed in detail presently as it yielded the best results (and the corresponding data is shown in Figures

94 X vs. Y 0.4 PID SMC Default PID Commanded

0.3 Man 5 ManMan 6 6 Man 5

0.2

0.1

Man 4 Man 9 Man 7 0 Man 2 Man 4 Man 9 Y [m] Man 7

-0.1

-0.2

Man 8 Man 3 Man Man8 3 -0.3

-0.4 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4 X [m]

Figure 4-15: Trajectories plotted in the 푥-푦 plane from simulation

4-17a, 4-18a, and 4-18b).

It is clear from Figure 4-16b that the static PID controller performed poorly on the table in comparison to the adaptive PID SMC in Figure 4-16a. It was expected that the performance would be poor based on the simulation results. However, it is hypothesized that the imperfections of the glass table coupled with the inferior controller resulted in the inability of the PID controller to meet the desired endpoints.

Figure 4-17a illustrates the 푥-position, 푦-position, and 푦푎푤 attitude commands and response of the satellite during the hardware test corresponding to dataset 4. The same time tolerance as the simulation case was set for completing a maneuver. For this hardware test, the maximum time the satellite was allowed to spend in each maneuver was 100 seconds, before the satellite would terminate its effort to converge and move on to the next maneuver. In maneuvers 4, 5 and 9 it can be seen that while the satellite converges to the commanded 푥-position and 푦푎푤, it struggles to converge to the commanded 푦-position. From Figure 4-16a it is evident that this inability to reach the commanded 푦-position in maneuvers 4, 5 and 9 (푦 = 0.25 cm) occurred across all four hardware tests. However, this was clearly not an issue in the simulation tests. There are several possible explanations for this result. The simulation likely has a poor model of the true system, particularly with respect to

95 X vs. Y 0.4 Default PID Commanded

0.3

0.2

0.1

Man 7 Man 8 Man 6 0 Man 5 Man 9 Y [m] Man 4 Man 3

-0.1

-0.2

-0.3

Man 2

-0.4 -0.4 -0.3 -0.2 -0.1 0 0.1 0.2 0.3 0.4 X [m] (a) Four datasets from adaptive PID SMC (b) Static PID Figure 4-16: Trajectories plotted in the 푥-푦 plane from hardware tests

thruster performance. The simulation assumes all thrusters thrust at a constant value over time, however in practice this does not occur. Some thrusters on the hardware have suffered degradation over the years and therefore thrust inconsistently. The air bearings that move the SPHERES across the glass table require an extremely smooth surface to operate, so any small imperfections in the glass table could result in additional friction when moving the SPHERES in that area. As the problem seems to be consistent with a particular 푦 position across the table, the more likely explanation is that the glass table was not perfectly level at that point and consequently the thrusters had difficulty moving the satellite in this region.

In all four datasets, maneuvers 4, 5 and 9 timed-out (seen in Figure 4-17a where the maneuvers automatically terminate after 100 seconds). It is also important to note that for datasets 1 and 2, the final maneuver was not completed. This was due to depletion of the CO2 tanks used for thruster propellant before the final maneuver. Lastly, the large jumps in data in Figure 4-16a is indicative of a combination of some data dropping across communications in addition to some estimation error rather than the satellite performing large oscillations as it translated.

96 Time vs. X-Position 0.5

0

Position [m] Measured Commanded Maneuver -0.5 0 100 200 300 400 500 600 700 800 Time [s] Time vs. Y-Position 0.5

0 Position [m]

-0.5 0 100 200 300 400 500 600 700 800 Time [s] Time vs. Yaw 200

150

100

50

0 Attitude [deg] -50

0 100 200 300 400 500 600 700 800 Time [s] (a) Adaptive PID SMC (b) Static PID Figure 4-17: A comparison of commanded position and attitude vs. measured teleme- try from hardware tests

Figure 4-17b illustrates the position and attitude time history of the satellite completing the test maneuvers using the static PID controller with incorrect mass knowledge. It is evident that the controller struggles to complete the test, timing out in each maneuver rather than meeting the desired endpoint. Comparing Figure 4-17b with Figure 4-17a supports the conclusion that the PID SMC offers superior performance to the default PID controller when there exists incorrect mass property knowledge because the adaptive PID SMC controller is able to meet the commands whereas the defualt PID controller cannot.

Figure 4-18a depicts the 푠푝 sliding variable time history for dataset 4. As men- tioned previously, since the sliding variable was not used during the first maneuver (estimator convergence), the maneuver is not included in the figure. Recall that for each maneuver, the sliding variable should converge to 푠푝 = 0, corresponding to the system converging to the commanded position (or attitude). Compared to the time history of sliding variables in Figure 4-14a, the sliding variables for 푥 and 푦 positions appear to chatter slightly around 푠푝 = 0. This behavior is consistent with the slow convergence to the commanded positions in Figure 4-17a. In fact, the slow conver-

97 (a) Sliding Variables (b) Gain Values Figure 4-18: Adaptive PID SMC time histories corresponding to position and attitude from hardware tests

gence to the commanded position is a consequence of this sliding variable behavior. Of greater significance is the chattering of the 푦푎푤 sliding variable. As mentioned in the discussion of the simulation results, this chattering indicates that the sliding variable is limit cycling about 푠푝 = 0. An attempt to resolve this issue with parame- ter tuning was not fruitful, and it is expected that adding a boundary layer into the attitude controller’s sliding variable would alleviate the issue.

Figure 4-18b shows the time history of the derivative and integral gains for the 푥 and 푦 positions and the 푦푎푤 attitude. Recall that the desired behavior of these 퐾^ values is convergence to some constant value per commanded position; however, this convergence is dependent on the sliding variable converging to 푠푝 = 0. Of particular interest is the sliding variable time history for the 푦 position during maneuvers 4 and 5. From Figure 4-17a, it is clear that the satellite moves on to the next maneuver due to reaching the maximum time limit rather than spending 5 seconds within a tolerance of 2.5 cm of the commanded position. Thus, the corresponding time history in Figure 4-18b indicates that the slowly changing gains were insufficient for controlling the satellite to its desired position. Similar to the simulation results, the gain values

98 ^ for the yaw attitude exhibit poor convergence. The 퐾푖 value does not manage to converge to a constant value during the maneuvers; however, the range over which the value changes is an order of magnitude smaller than the corresponding position integral gain values. This indicates a negligible impact on the system. Again, the ^ ever-increasing 퐾푑 value is a consequence of the chattering 푦푎푤 sliding variable that is discussed in more depth in the following section.

Considerations & Conclusions

When conducting hardware tests of the PID sliding mode attitude and position con- trollers, the decision was made to increase the test from five maneuvers to nine in order to add waypoints between particularly distant endpoints of maneuvers. This was an attempt to force the satellite to more closely follow the trajectory that the simulation mapped out (i.e. a straight line between endpoints). Prior to these ad- ditional waypoints, the satellite followed semicircular-like curves between endpoints during hardware testing due to imperfections in the glass table that inadvertently af- fected the satellite’s path. The addition of these waypoints decreased the initial value of the sliding variable per new command, which translates into smaller necessary gain values per maneuver. In order for a sliding mode controller to operate correctly, chattering must be eliminated in order to limit the necessary control activity. As mentioned previously, chattering of the 푦푎푤 attitude sliding variable occurred in both simulation and in hardware testing. A thin boundary layer can be applied to 푠푝 = 0 in an attempt to smooth out this chattering. The addition of a thin boundary layer to the sliding variable trades "perfect" tracking for tracking with a guaranteed precision proportional to the width of the boundary layer. This implementation changes the definition of the sliding variable and the subsequent derivation of the adaptation laws. The implementation of a boundary layer in the attitude controller is future work for this research. Both hardware and simulation tests were used to validate the PID sliding mode controllers for position and attitude. Results show that with experimentally tuned

99 parameters, the adaptive controller enabled the satellite to sufficiently converge to commanded positions and attitudes over a series of maneuvers. The performance of the PID SMC was compared with a PID controller designed with incorrect mass property knowledge (the SPHERES’s default PID controller). The results of both simulation and hardware tests for each controller supports the conclusion that the PID SMC provides resilience to incorrect mass properties knowledge and superior performance. Future work will address the chattering of the attitude controller via the addition of a boundary layer to the sliding variable (and the subsequent effects that will have on the adaptation laws). Altogether, the PID SMC is a promising control scheme for offering resilience to systems with uncertainty in mass properties, and continued efforts are necessary to more finely tune its capabilities.

100 Chapter 5

Docked Dynamics

The focus of this chapter is the beginning of Stage 3 of the ROAM project – soft docking between the Chaser and the Target and the detumbling procedure that brings the aggregated system to a standstill. In this stage, the Chaser has instantaneously docked to the Target by maintaining synchronous motion on its approach. The goal is for the Chaser to detumble the Target while minimizing fuel, loads, and moments imparted on the Target. This chapter will overview the contact dynamics of docking, the docked dynamics of maintaining synchronous motion, and an optimization for the detumble procedure. Because active debris removal presents scenarios in which Targets will be fragile, the imparted loads and moments on the Target are considered in the cost of the detumbling maneuver.

5.1 Contact Dynamics of Docking

For the scenario in which the Target spacecraft is fragile, the user is interested in de- termining the loads and moments imparted on the Target during the docking process and detumbling maneuver. The contact dynamics of docking are provided from the literature and applied to this problem [67]. Figure 5-1 indicates the Chaser and Target the instant before docking, in which both spacecraft still have their separate linear and angular velocity. Refer to Table 5.1 regarding the notation used in the figure. This problem is more constrained than

101 Figure 5-1: Chaser and Target during instance before docking occurs denoted with separate position, velocity, and attitude vectors

the original problem cited in the literature [67], since the trajectory approach of the mission is limited to a synchronous radial approach. This implies that the angular velocity of the Chaser is equivalent to that of the Target. Figure 5-2 illustrates the aggregated system immediately after docking.

Table 5.1: Notation for contact dynamics of two spacecraft docking to one another

Variable Description ⃗푣푡,⃗푣푐 Independent linear velocity ⃗휔푡, ⃗휔푐 Independent angular velocity ⃗푟푡, ⃗푟푐 Position from system center of mass ⃗푟푡푐 Distance from Target’s CM to Chaser’s CM ⃗푟푙푡 Distance from docking interface to Target’s CM 푚푡, 푚푐 Spacecraft mass ⃗ Ω퐶푀퐶 System angular velocity ⃗ 푉퐶푀퐶 System linear velocity 휖 = 푚푐 Mass ratio 푚푡

In order to yield expressions for the impulsive force and torque imparted during docking, several geometric relationships are defined. The position vectors are related

via ⃗푟푐 = ⃗푟푡 +⃗푟푡푐. The definition of the center of mass of the aggregated system implies that 푚푐⃗푟푐 + 푚푡⃗푟푡 = 0. Therefore, both position vectors can be expressed in terms of

102 Figure 5-2: Chaser and Target in the instance after docking denoted with aggregated translational and attitude velocity

휖 and ⃗푟푡푐.

−1 ⃗푟푐 = (1 + 휖) ⃗푟푡푐 (5.1)

−1 ⃗푟푡 = −(1 + 휖) 휖⃗푟푡푐 (5.2)

˙ Differentiating Equation 5.2 yields an expression for ⃗푟푡.

˙ ⃗ ⃗푟푡 = ⃗푣푡 − 푉퐶푀퐶 (5.3a) ˙ −1 ˙ ⃗푟푡 = −(1 + 휖) 휖⃗푟푡푐 (5.3b)

Thus, the independent velocity of the Target relative to the aggregated system linear ˙ velocity after docking is found by equating the two ⃗푟푡 expressions and rearranging.

⃗ −1 ˙ ⃗푣푡 = 푉퐶푀퐶 − (1 + 휖) 휖⃗푟푡푐 (5.4)

By conservation of linear momentum, the linear momentum of the Chaser and the Target before docking must be equivalent to the linear momentum of the aggregated system after docking. From this relationship, an expression for the linear velocity of

103 the aggregated system is determined.

⃗ 푚푐⃗푣푐 + 푚푡⃗푣푡 = (푚푐 + 푚푡)푉퐶푀퐶 (5.5a) ⃗ 푚푐⃗푣푐 + 푚푡⃗푣푡 =⇒ 푉퐶푀퐶 = (5.5b) 푚푐 + 푚푡

The Target’s impulsive velocity due to docking is

⃗ + ⃗ ⃗ 푉푡 = 푉퐶푀퐶 + Ω퐶푀퐶 × ⃗푟푡. (5.6)

Using the velocity relationships already defined, the impulsive force is determined in Equation 5.7c.

⃗ ⃗ + ⃗ 퐹퐼 = 푚푡(푉푡 − 푉푡) (5.7a) ⃗ ⃗ −1 ˙ 퐹퐼 = 푚푡(Ω퐶푀퐶 × ⃗푟푡 + (1 + 휖) 휖⃗푟푡푐) (5.7b) ⃗ −1 ˙ ⃗ 퐹퐼 = 푚푐(1 + 휖) (⃗푟푡푐 − Ω퐶푀퐶 × ⃗푟푡푐) (5.7c)

˙ ⃗ Equation 5.7c indicates that ⃗푟푡푐, Ω퐶푀퐶 , and ⃗푟푡푐 are the state variables contributing to the impulsive force. Conservation of angular momentum of the system before and after docking is ⃗ utilized for determining the angular velocity of the system (Ω퐶푀퐶 ).

⃗ ˙ ⃗ ˙ ⃗ 퐻푡+⃗푟푡 × 푚푡⃗푟푡 + 퐻푐 + ⃗푟푐 × 푚푐⃗푟푐 = 퐼퐶푀퐶 Ω퐶푀퐶 (5.8a) ⃗ −1 [︁ ⃗ ⃗ −1 ˙ ]︁ Ω퐶푀퐶 = 퐼퐶푀퐶 퐻푡 + 퐻푐 + 푚푐(1 + 휖) ⃗푟푡푐 × ⃗푟푡푐 (5.8b) ⃗ 퐻푡 = 퐼푡⃗휔푡 ⃗ 퐻푐 = 퐼푐⃗휔푐

The impulsive torque is expressed in Equation 5.9.

⃗ ⃗ ⃗휏퐼 = 퐼푡(Ω퐶푀퐶 − ⃗휔푡) − ⃗푟푙푡 × 퐹퐼 (5.9)

⃗ Equation 5.9 indicates that Ω퐶푀퐶 , ⃗휔푡, ⃗푟푙푡, and the variables from Equation 5.7c are

104 the state variables contributing to the impulsive torque imparted on the spacecraft. Based on the aforementioned analysis of the impulsive forces and torques imparted in docking, it is evident that, in the scenario of a fragile Target, the Chaser must con- tinue to thrust such that the spin axis remains at the Target’s center of mass. These equations illustrated that with the constraint that the Chaser radially approaches the Target while maintaining synchronicity, no state variable in this process can be mod- ified to limit the impulses. This is a consequence of the synchronous radial approach constraint offering no flexibility in the state variables that constitute Equations 5.7c and 5.9. Therefore, a solution is to command the Chaser to thrust while docking such that the angular velocity of the system is moved to be about the Target’s center of mass as the Chaser starts the detumble procedure. A script that symbolically solves for the impulsive force and torque can be found in Appendix C.1, Listing C.1. A function to numerically solve for the impulsive force and torque based on a given Chaser and Target is given in Appendix C.1, Listing C.2.

5.2 Modeled Docked Dynamics

The body-fixed frame is located at the Target’s center of mass (CM), with theaxis 푒^푟 going through its docking port, and axes 푒^휃 and 푒^푧 mutually perpendicular creating a right-handed system (see Figures 5-3a and 5-3b). The inertial frame is the mutually perpendicular, right-handed system 푥^, 푦^, 푧^ that is equivalent to the body-fixed frame at the start of the docked stage. It is assumed that the Chaser has thrusters that exert force in the 푒^휃 and 푒^푧 directions and a reaction wheel to torque about 푒^푟. Since the Chaser must be synchronous with the Target’s rotation, the Chaser’s translational dynamics in this stage are sufficiently characterized by the following equation. ¨ ˙ ⃗푟퐼 = R퐵2퐼 [(⃗휔 × (⃗휔 × ⃗푟퐵) + (⃗휔 × ⃗푟퐵)] (5.10)

In Equation 5.10, ⃗푟퐵 is the distance from the Target’s CM to the Chaser’s CM, which does not change in the body frame since the spacecraft stays docked. The variable ⃗휔

is the angular velocity expressed in the body axes of the Target and Chaser, and R퐵2퐼

105 (a) Top-down view (b) Side view Figure 5-3: Chaser and Target as docked, aggregated system with denoted body-fixed frame at Target’s center of mass and the force and torque directions of the Chaser is the rotation matrix from the body frame to the inertial frame. While this equation sufficiently defines the translation motion of the Chaser, it can be equivalently ex- pressed via the following linear momentum balance, which illustrates the tensile and shear loads applied to the Target during the detumbling procedure.

⃗ ¨ Σ퐹 = 푚⃗푟퐵 (5.11a) ¨ ˙ 푚⃗푟퐵 = 푚(⃗휔 × (⃗휔 × ⃗푟퐵) + (⃗휔 × ⃗푟퐵)) (5.11b) ⃗ Σ퐹 = (퐹푟 + 푇 )^푒푟 + (퐹휃 + 푆휃)^푒휃 + (퐹푧 + 푆푧)^푒푧 (5.11c)

Equating Equation 5.11b with Equation 5.11c and representing the relationship in matrix form yields Equation 5.12.

⎡ ⎤ ⎡ ⎤ 퐹 + 푇 −푟 (휔2 + 휔2) + 푟 (휔 휔 − 휔˙ ) + 푟 (휔 휔 +휔 ˙ ) ⎢ 푟 ⎥ ⎢ 푟 휃 푧 휃 푟 휃 푧 푧 푟 푧 휃 ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ 2 2 ⎥ ⎢ 퐹휃 + 푆휃 ⎥ = 푚 ⎢ 푟푟(휔푟휔휃 +휔 ˙ 푧) − 푟휃(휔푟 + 휔푧 ) + 푟푧(휔휃휔푧 − 휔˙ 푟) ⎥ (5.12) ⎢ ⎥ ⎢ ⎥ ⎣ ⎦ ⎣ 2 2 ⎦ 퐹푧 + 푆푧 푟푟(휔푟휔푧 − 휔˙ 휃) + 푟휃(휔휃휔푧 +휔 ˙ 푟) − 푟푧(휔푟 + 휔휃 )

In Equation 5.12, 푇 , 푆휃, and 푆푧 are the tensile and shear loads expressed in the body frame of the docking interface. This linear momentum balance uses the free body diagram of the Chaser only (Figure 5-4b and 5-4a). In order to determine the values of 푇 , 푆휃, and 푆푧, the necessary torques for changing the Target’s rotation in the desired manner are considered. Now, the angular momentum balance for the Target and Chaser combined sys- tem is constructed to determine the desired torques to detumble the Target. Let 휌

106 (a) Top-down view of Chaser (b) Side view of Chaser Figure 5-4: Free body diagram of the Chaser displaying Chaser’s abilities to impart force and torques and its internal loads and moments from interacting with the Target

represent the distance between the Target CM and the Chaser CM. The following equations constitute the angular momentum balance.

˙ Σ휏푇 = 퐻퐶푀퐶/푇 퐴푅 (5.13a) ˙ Σ휏푇 = [퐼]퐶푀퐶/푇 퐴푅⃗휔 + (⃗휔 × [퐼]퐶푀퐶/푇 퐴푅⃗휔) (5.13b)

Σ휏푇 = 푀푥푒^푟 + 휌푒^푟 × 퐹휃푒^휃 + 휌푒^푟 × 퐹푧푒^푧 (5.13c) ˙ [퐼]퐶푀퐶/푇 퐴푅⃗휔 + (⃗휔×[퐼]퐶푀퐶/푇 퐴푅⃗휔) = 푀푥푒^푟 − 휌퐹푧푒^휃 + 휌퐹휃푒^푧 (5.13d)

Expanding Equation 5.13d into matrix form yields the following Equation 5.14.

⎡ ⎤ ⎡ ⎤ 푀 퐼 휔˙ + (퐼 − 퐼 )휔 휔 ⎢ 푥 ⎥ ⎢ 퐶푀퐶/푇 퐴푅,푟푟 푟 퐶푀퐶/푇 퐴푅,푧푧 퐶푀퐶/푇 퐴푅,휃휃 휃 푧 ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ −휌퐹푧 ⎥ = ⎢ 퐼퐶푀퐶/푇 퐴푅,휃휃휔˙ 휃 + (퐼퐶푀퐶/푇 퐴푅,푟푟 − 퐼퐶푀퐶/푇 퐴푅,푧푧)휔푟휔푧 ⎥ (5.14) ⎢ ⎥ ⎢ ⎥ ⎣ ⎦ ⎣ ⎦ 휌퐹휃 퐼퐶푀퐶/푇 퐴푅,푧푧휔˙ 푧 + (퐼퐶푀퐶/푇 퐴푅,휃휃 − 퐼퐶푀퐶/푇 퐴푅,푟푟)휔푟휔휃

In the above equations, [퐼]퐶푀퐶/푇 퐴푅 is defined as

[퐼]퐶푀퐶/푇 퐴푅 = [퐼]퐶 + [퐼]푇 + (푚퐶 + 푚푇 )[I3(⃗푞퐵 · ⃗푞퐵) − ⃗푞퐵 ⊗ ⃗푞퐵] (5.15)

and ⃗푞퐵 is the displacement vector from the aggregated center of mass to the Target’s CM. In general, this is not a diagonal matrix. In the context of ROAM, only inertia ratios are provided from the estimation phase, so [퐼]퐶푀퐶/푇 퐴푅 is a diagonal matrix.

107 Therefore, given a prescribed angular acceleration, the necessary forces and mo- ments that the Chaser must produce are easily determined. Combining these results

with Equation 5.12 permits the ability to determine the values of 푆휃 and 푆푧. This re-

lationship also illustrates that 퐹푟 is not restricted by the angular momentum balance

of the Target-Chaser combined system. Therefore, 퐹푟 can supply all of the necessary force on the Chaser in the 푒^푟 direction, implying that 푇 = 0 for detumbling.

In order to determine 푀푥, the angular momentum balance of the Chaser is con- structed. ˙ [퐼]퐶 ⃗휔 + (⃗휔 × [퐼]퐶 ⃗휔) = (푀푥 + 푀퐵,푟)^푒푟 + 푀퐵,휃푒^휃 + 푀퐵,푧푒^푧 (5.16)

⎡ ⎤ ⎡ ⎤ 푀 + 푀 퐼 휔˙ + (퐼 − 퐼 )휔 휔 ⎢ 푥 퐵,푟 ⎥ ⎢ 퐶,푟푟 푟 퐶,푧푧 퐶,휃휃 휃 푧 ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ 푀퐵,휃 ⎥ = ⎢ 퐼퐶,휃휃휔˙ 휃 + (퐼퐶,푟푟 − 퐼퐶,푧푧)휔푟휔푧 ⎥ (5.17) ⎢ ⎥ ⎢ ⎥ ⎣ ⎦ ⎣ ⎦ 푀퐵,푧 퐼퐶,푧푧휔˙ 푧 + (퐼퐶,휃휃 − 퐼퐶,푟푟)휔푟휔휃

The variable [퐼]퐶 is the Chaser’s inertia matrix. The variable 푀퐵,휃 is the bending

moment at the docking interface about 푒^휃; 푀퐵,푧 is the bending moment at the docking

interface about 푒^푧. Torsion about the docking axis is represented by 푀퐵,푟. Lastly,

푀푥 is the applied moment that occurs about the Chaser’s CM that acts about the 푒^푟 axis. Thus, the angular momentum balance of the Chaser provides the expressions for the torsion and bending moments that act at the docking port interface.

This exercise in analyzing the dynamics of the aggregated system and the Chaser (cut away from the Target) has provided the relationships between the loads and moments imparted on the Target. There are three internal loads (푇 , 푆휃, 푆푧) and

three moments (푀퐵,푟, 푀퐵,휃, 푀퐵,푧). Expressions for the internal loads are derived from Equations 5.12 and 5.14. As mentioned previously, the internal tension is merely

푇 = 0 (5.18)

since the applied force 퐹푟 does not show up in the system’s angular momentum

balance. An expression for 퐹휃 and 퐹푧 in terms of inertias and angular velocities and

108 accelerations fall out of Equation 5.14. Applying these expressions to 5.12 yields the following.

(︃1)︃ 푆 = 휔 휔 (푚푟 − (퐼 − 퐼 )) + ... 휃 푟 휃 푟 휌 퐶푀퐶/푇 퐴푅,휃휃 퐶푀퐶/푇 퐴푅,푟푟 (5.19) (︃1)︃ 휔˙ (푚푟 − 퐼 ) − 푚(푟 (휔2 + 휔2) − 푟 (휔 휔 − 휔˙ )) 푧 푟 휌 퐶푀퐶/푇 퐴푅,푧푧 휃 푟 푧 푧 휃 푧 푟

1 푆 = 휔 휔 (푚푟 + (퐼 − 퐼 )) + ... 푧 푟 푧 푟 휌 퐶푀퐶/푇 퐴푅,푟푟 퐶푀퐶/푇 퐴푅,푧푧 (5.20) 1 휔˙ ( (퐼 − 푚푟 ) + 푚(푟 (휔 휔 +휔 ˙ ) − 푟 (휔2 + 휔2)) 휃 휌 퐶푀퐶/푇 퐴푅,휃휃 푟 휃 휃 푧 푟 푧 푟 휃

Therefore, the internal loads during the detumbling procedure are expressed by Equa- tions 5.18, 5.19, and 5.20.

Now, expressions for the internal moments are determined from the previous dy- namics analysis. From Equation 5.17, expressions for 푀퐵,휃 and 푀퐵,푧 are clear.

푀퐵,휃 = 퐼퐶,휃휃휔˙ 휃 + (퐼퐶,푟푟 − 퐼퐶,푧푧)휔푟휔푧 (5.21)

푀퐵,푧 = 퐼퐶,푧푧휔˙ 푧 + (퐼퐶,휃휃 − 퐼퐶,푟푟)휔푟휔휃 (5.22)

Equation 5.14 yields the necessary expression for 푀푥 that simplifies the relationship between 푀퐵,푟 and the angular velocities and angular accelerations.

푀퐵,푟 = 퐼퐶,푟푟휔˙ 푟 + (퐼퐶,푧푧 − 퐼퐶,휃휃)휔휃휔푧 − 푀푥 (5.23a)

푀퐵,푟 = 퐼퐶,푟푟휔˙ 푟 + (퐼퐶,푧푧 − 퐼퐶,휃휃)휔휃휔푧 − ...

(퐼퐶푀퐶/푇 퐴푅,푟푟휔˙ 푟 + (퐼퐶푀퐶/푇 퐴푅,푧푧 − 퐼퐶푀퐶/푇 퐴푅,휃휃)휔휃휔푧) (5.23b)

푀퐵,푟 = (퐼퐶,푟푟 − 퐼퐶푀퐶/푇 퐴푅,푟푟)휔 ˙ 푟 + ...

(퐼퐶,푧푧 − 퐼퐶푀퐶/푇 퐴푅,푧푧 − 퐼퐶,휃휃 + 퐼퐶푀퐶/푇 퐴푅,휃휃)휔휃휔푧 (5.23c)

Therefore, the internal moments during the detumbling procedure are expressed by Equations 5.21, 5.22, and 5.23c.

109 5.3 Discrete Solver for Docked Dynamics

The discrete solver takes as inputs the maximum time allotted for the maneuver, the desired profile of the angular acceleration time history, a struct containing the Chaser’s parameters, and a struct containing the Target’s parameters. The Chaser and Target structs are constructed by separate functions before the discrete solver is called. Copies of these functions are in Appendix C.2, Listings C.3 and C.4. The functions that setup the Chaser and Target structs define important lengths of the spacecraft with respect to their centers of mass, define the principal axis inertia matrix with origin at the center of mass, and set up the initial conditions of both translation and attitude. Given these inputs, the discrete solver enters a while loop that it can only exit once the magnitude of every element of the angular velocity is less than a certain tolerance (tol = 0.001). A time step occurs at each iteration of the loop. If the maximum time allotted is exceeded, the loop is exited and deemed unsuccessful. Otherwise, the time span that actually occurred is recorded and outputted to the user, as well as are the time histories of all the states and their derivatives. During each iteration of the loop, the solver executes the following procedure:

1. Determine the current angular acceleration of the docked Chaser-Target system based on the previous iteration’s angular velocity.

퐼 − 퐼 휑¨ = 푦푦 푧푧 휃˙휓˙ (5.24) 퐼푥푥 퐼 − 퐼 휃¨ = 푧푧 푥푥 휑˙휓˙ (5.25) 퐼푦푦 퐼 − 퐼 휓¨ = 푥푥 푦푦 휑˙휃˙ (5.26) 퐼푧푧

2. Determine if the Target has the potential to be nutating.

(a) If the Target may be nutating, the solver counteracts the roll angular velocity first (before dealing with the pitch and yaw angular velocities) by applying the functional form of the angular acceleration (user-defined) in

110 the roll direction. Once the roll angular velocity has magnitude less than the solver’s tolerance, the solver will counteract the pitch and yaw angular velocities in the same manner.

(b) If the Target cannot be nutating, the solver counteracts the angular ve- locity in all three directions simultaneously via the user-defined functional form of the angular acceleration.

3. If the Target has any translational acceleration, the solver counteracts it using a constant acceleration functional form.

4. The solver takes the change in the three rotation angles from the previous it- eration and finds the quaternion from the last iteration using acallto quat2dcm and transposing it. This DCM is transposed and allocated as the CurrentB2IRot

for the current iteration. This matrix is R퐵2퐼 mentioned in Section 5.2. Thus, this step updates the rotation matrix relating the body frame to the inertial frame.

5. To determine what translational acceleration the Chaser needs to maintain to stay synchronous with the Target, the solver determines the centripetal and angular acceleration terms based on the current angular velocity and angular acceleration of the Target (and Chaser). Since this stage of the mission starts at when the spacecraft are already docked, the linear and Coriolis accelera- tion terms are nonzero and ignored. The equations for centripetal and angular acceleration are respectively

⃗푎푐푒푛푡 = ⃗휔퐵 × (⃗휔퐵 × ⃗푟퐵) (5.27)

⃗푎푎푛푔 = ⃗훼퐵 × ⃗푟퐵 (5.28)

6. The centripetal and angular accelerations are rotated into the inertial frame us- ing CurrentB2IRot and summed. These inertial accelerations are also summed with the desired translational deceleration from Step 3.

111 7. The solver calculates the angular momentum balance of the Target with respect

to the aggregated system and solves for 푀푥, 퐹푧, and 퐹휃 to be used in determining the imparted loads and moments on the Target (see Equation 5.14).

8. Now that the solver has determined the effect to the translation and angu- lar accelerations, it numerically integrates to solve for translation and angular velocity and position for the current iteration.

9. The current iteration ends and the exit conditions in the while loop are checked.

This discrete solver is shown in its complete form in Appendix C.5.

5.4 Detumble Optimization

This section will cover the two optimization methodologies that were employed for determining the optimal angular acceleration time history to bring the Target to standstill and the results from the optimization processes. Both optimization methods had an objective function of

∫︁ 푡푓 (︂ √︁ )︂ ¨2 ¨2 ¨2 퐽 = 푆휃(푡) + 푆푧(푡) + 푀퐵,푟(푡) + 푀퐵,휃(푡) + 푀퐵,푧(푡) + 휑 (푡) + 휃 (푡) + 휓 (푡) dt 0 (5.29) where each term is equally weighted. It is worth noting that each load and moment term can either be positive or negative, implying some magnitude cancellations may occur depending on the nature of the Target’s tumble. Future work could include re- fining this objective value to use absolute values of each load and moment. Moreover, an objective function that seeks to minimize the maximum loads and moments of the detumble would be a worthwhile case to investigate for fragile Targets. Both methods, which are discussed in detail in the following sections, minimized the objective function by optimizing the angular acceleration profiles. However, the first method achieved this through an indirect approach while the second method accomplished this directly.

112 5.4.1 Indirect Optimization on Angular Acceleration Profiles

The indirect optimization of the angular acceleration profiles minimized Equation

5.29 by optimizing the desired detumble time interval (Δ푡푑푒푠), which acted as an essential input for the angular acceleration profiles for each run. Thus, the objective function for the indirect optimization is shown by Equation 5.30.

∫︁ 푡푓 min 퐽 = ( 푆휃(푡) + 푆푧(푡) + 푀퐵,푟(푡) + 푀퐵,휃(푡) + 푀퐵,푧(푡) + ... Δ푡푑푒푠 0 √︁ ¨ 2 ¨ 2 ¨ 2 휑(푡, Δ푡푑푒푠) + 휃(푡, Δ푡푑푒푠) + 휓(푡, Δ푡푑푒푠) ) dt (5.30)

Four functional forms of the angular acceleration profiles were utilized in the optimization and the results were compared against one another to determine which provided the lowest cost. A description of these functional forms in provided in the subsequent section. This indirect optimization process used the MATLAB function fmincon. The discrete solver previously described was the function input for the call to fmincon.

Thus, the optimization iteratively called the discrete solver whilst changing (Δ푡푑푒푠) to minimize the objective function. For the sake of re-creation, the optimization settings are detailed in Table 5.2. The following section describes the angular acceleration functional forms.

Table 5.2: fmincon optimization options used in the indirect optimization of angular acceleration profiles

Algorithm TolFun MaxFunEvals MaxIter TolX TolCon sqp 1e-16 1e6 1e7 1e-16 1e-16

Angular Acceleration Functional Forms

In forming this optimization problem, angular acceleration functional forms were first selected. Simple functions for the four desired forms were implemented in the discrete solver function. These forms are denoted as Constant, Positive Linear, Negative

113 Linear, and Negative Quadratic. These functions determine the change in angular acceleration that the Chaser needs to provide to counteract the Target’s angular velocity. The effective time history in angular velocity that these functional forms

provide is qualitatively illustrated in Figures 5-5a-5-5d. In these figures, 휔푖푛푖푡푖푎푙 is the

initial angular velocity, 푡푤푎푖푡 is a user-defined variable indicating a desired time to wait before starting the detumble procedure, and Δ푡푑푒푠푖푟푒푑 is the desired time for the maneuver to complete. The angular acceleration functional forms are defined using the given variables by Equations 5.31-5.34.

(a) Constant angular acceleration (b) Positive linear angular acceleration

(c) Negative linear angular acceleration (d) Negative quadratic angular acceler- ation Figure 5-5: Expected angular velocity time histories from integration of selected angular acceleration functional forms

114 ˙ ⃗휔푖푛푖푡푖푎푙 ⃗휔푐표푛푠푡푎푛푡 = − (5.31) Δ푡푑푒푠푖푟푒푑

˙ ⃗휔푖푛푖푡푖푎푙 ⃗휔푃 퐿 = 2 2 (푡 − (Δ푡푑푒푠푖푟푒푑 + 푡푤푎푖푡)) (5.32) (Δ푡푑푒푠푖푟푒푑)

˙ ⃗휔푖푛푖푡푖푎푙 ⃗휔푁퐿 = −2 2 (푡 − 푡푤푎푖푡) (5.33) (Δ푡푑푒푠푖푟푒푑)

˙ ⃗휔푖푛푖푡푖푎푙 2 ⃗휔푁푄 = −3 3 (푡 − 푡푤푎푖푡) (5.34) (Δ푡푑푒푠푖푟푒푑) These additional angular acceleration profiles are solved for on each iteration of the discrete solver. Which profile the solver uses is selected by the user –itis an input to the function call of the discrete solver. The use of pre-defined angular acceleration profiles distinguish this optimization method from the secondary method and necessitates that the optimization occurs on the variable Δ푡푑푒푠.

Results

Using the aforementioned objective function (Equation 5.29), the following nested for loops was executed to produce the results in Table 5.3. The potential spacecraft shapes were spherical, rectangular prism, or cylindrical. The pre-defined angular 푑푒푔 푑푒푔 velocities for each type of spin were: [0, 0, 5] 푠 for flat spin, [2, 2, 2] 푠 for 3D spin, 푑푒푔 [1, 2, 3] 푠 for nutation.

Algorithm 1 Method 1 Optimization Loop 1: procedure OptimizationLoop 2: shapeLen ← length of {shapes} 3: angVelLen ← length of angVelMatrix 4: deltaTLen ← length of deltaTArray 5: loop: 6: for q=1:shapeLen do 7: ShapeType = shapes{q} 8: for r=1:angVelLen do 9: angVel = angVelMatrix(:,r) 10: for j=1:deltaTLen do 11: deltaT = deltaTArray(j) 12: Execute optimization.

115 Although two values were used in Algorithm 1 for Δ푡, the results presented in Ta- ble 5.3 are the results from providing an initial guess of Δ푡 = 150푠. The optimization routine outputted the optimal Δ푡 corresponding to the lowest cost. Only the results for the initial guess of Δ푡 = 150푠 are displayed because the initial guess of Δ푡 = 5푠 occasionally produced a nonsensically large cost, suggesting an issue with the discrete solver attempting to detumble the Target in such a short period of time.

Table 5.3: Method 1 optimization results of optimal Δ푡 and associated cost

Ang. Acceleration Form Δ푡[푠] Cost Constant 56.14 -0.034616 Sphere: Positive Linear 5.00 -0.034595 flat spin Negative Linear 149.91 -0.034608 Negative Quadratic 150.00 -0.034620 Constant 148.35 -0.046129 Sphere: Positive Linear 5.00 -0.046126 3D spin Negative Linear 149.91 -0.046144 Negative Quadratic 150.00 -0.046160 Constant 483.00 0.0151 Rect. prism: Positive Linear 150.01 0.046790 flat spin Negative Linear 150.01 0.046774 Negative Quadratic 483.00 0.001457 Constant 381.84 0.0255 Rect. prism: Positive Linear 150.01 0.063002 3D spin Negative Linear 150.01 0.062967 Negative Quadratic 381.84 0.003932 Constant 13.41 0.0308 Rect. prism: Positive Linear 96.267 0.0150 nutation Negative Linear 62.10 0.301 Negative Quadratic 37.69 0.167418 Constant 483.00 0.00375 Cylinder: Positive Linear 150.01 0.0116 flat spin Negative Linear 483.00 0.00116 Negative Quadratic 483.00 0.00036 Constant 381.84 0.00632 Cylinder: Positive Linear 150.01 0.0156 3D spin Negative Linear 381.84 0.00248 Negative Quadratic 381.84 0.00097 Constant 38.92 0.0944 Cylinder: Positive Linear 82.91 -0.0205 nutation Negative Linear 26.98 0.0871 Negative Quadratic 43.29 0.1827

116 In Table 5.3, the cost numerics nominally have three significant figures except to distinguish the difference between costs for the same shape and spin. For the spherical spacecraft, the positive linear angular acceleration functional form provides the lowest cost with a Δ푡 = 5푠 for both the flat and 3D spins. For the rectangular prism spacecraft, the negative quadratic angular acceleration functional form provided the lowest cost for the flat and 3D spins (yielding the largest Δ푡 for both). However, for the nutating spin, the positive linear form provided the lowest cost (half of the second lowest cost). Similarly, for the cylindrical spacecraft, the negative quadratic form yielded the lowest cost for the flat and 3D spins, and the positive linear form yielded the lowest cost for the nutating spin. This data suggests that if a Target is nutating, regardless of its shape, a positive linear angular acceleration profile is the optimal profile form for minimizing Equation 5.29. Additionally, these results suggest that for an axisymmetric spacecraft that is not nutating (i.e. it has a flat spin or a general 3D spin), a negative quadratic angular acceleration profile is the optimal form for minimizing Equation 5.29.

5.4.2 Direct Optimization Approach

GPOPS-II (General Purpose Optimal Control Software) was employed to produce a direct optimization of the angular acceleration profile for minimizing the objec- tive function in the subproblem of the Chaser detumbling the Target once already docked. GPOPS-II is a user-friendly numerical optimization software that uses Gaus- sian quadrature integration, works within MATLAB, and offers options for setting up the problem (NLP solver, derivative supplier, scaling, etc) [68]. For this detumble optimization, IPOPT was used with a tolerance of 10 × 10−7 [69].

117 Problem Formulation

This problem was constructed as one phase in GPOPS with the following mathemat- ical form.

∫︁ 푡푓 min 퐽 = ( 푆휃(푡) + 푆푧(푡) + 푀퐵,푟(푡) + 푀퐵,휃(푡) + 푀퐵,푧(푡) + ... ⃗훼(푡) 0 √︁ )︂ 휑¨(푡)2 + 휃¨(푡)2 + 휓¨(푡)2 dt (5.35) where

⎡ ⎤ 휑¨(푡) ⎢ ⎥ ⎢ ⎥ ⎢ ¨ ⎥ ⃗훼(푡) = ⎢ 휃(푡) ⎥ (5.36) ⎢ ⎥ ⎣ ⎦ 휓¨(푡) subject to the dynamic constraints

⎡ ⎤ 푥¨ ⎢ ⎥ ⎢ ⎥ (︁ )︁ ⎢ ⎥ ˙ ⎢ 푦¨ ⎥ = R퐵2퐼 ⃗휔 × (⃗휔 × ⃗푟퐵) + ⃗휔 × ⃗푟퐵 (5.37) ⎢ ⎥ ⎣ ⎦ 푧¨ where ⃗푟퐵 is the position vector from the Target’s CM to the Chaser’s CM in the body frame ⎡ ⎤ 푢 ⎢ 휑 ⎥ ⎢ ⎥ ˙ ⎢ ⎥ ⃗훼 = ⃗휔 = ⎢ 푢휃 ⎥ (5.38) ⎢ ⎥ ⎣ ⎦ 푢휓 ⎡ ⎤ ⎡ ⎤ 1 ˙ ˙ ˙ 푞푤 − (휑푞푥 + 휃푞푦 + 휓푞푧) ⎢ ⎥ ⎢ 2 ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ 1 ˙ ˙ ˙ ⎥ 푑 ⎢ 푞푥 ⎥ ⎢ 2 (휑푞푤 + 휃푞푧 − 휓푞푦) ⎥ ⃗푞˙ = ⎢ ⎥ = ⎢ ⎥ (5.39) ⎢ ⎥ ⎢ ⎥ 푑푡 ⎢ 푞 ⎥ ⎢ 1 (−휑푞˙ + 휃푞˙ + 휓푞˙ ) ⎥ ⎢ 푦 ⎥ ⎢ 2 푧 푤 푥 ⎥ ⎣ ⎦ ⎣ ⎦ 1 ˙ ˙ ˙ 푞푧 2 (휑푞푦 − 휃푞푥 + 휓푞푤) ⎡ ⎤ 푞2 + 푞2 − 푞2 − 푞2 2(푞 푞 − 푞 푞 ) 2(푞 푞 + 푞 푞 ) ⎢ 푤 푥 푦 푧 푥 푦 푧 푤 푥 푧 푦 푤 ⎥ ⎢ ⎥ ⎢ 2 2 2 2 ⎥ R퐵2퐼 = ⎢ 2(푞푥푞푦 + 푞푧푞푤) 푞푤 − 푞푥 + 푞푦 − 푞푧 2(푞푦푞푧 − 푞푥푞푤) ⎥ (5.40) ⎢ ⎥ ⎣ 2 2 2 2 ⎦ 2(푞푥푞푧 − 푞푦푞푤) 2(푞푦푞푧 + 푞푥푞푤) 푞푤 − 푞푥 − 푞푦 + 푞푧

118 subject to the inequality path constraints

√︁ 휁 − 1 × 10−4 ≤ 푥(푡)2 + 푦(푡)2 + 푧(푡)2 ≤ 휁 + 1 × 10−4 (5.41) √︁ 휁 = 푥(0)2 + 푦(0)2 + 푧(0)2

In order to mimic the construction of the indirect optimization process, the control

rad was constrained to be [−0.007, −0.007, −0.007] ≤ ⃗푢 ≤ [0.007, 0.007, 0.007] 푠2 .

Results

Table 5.4 indicates the resultant Δ푡 and cost from the direct optimization process. In this instance, the cost is calculated via cumtrapz in order to parallel the computation from the indirect method. GPOPS-II was not able to converge to a solution for the 3D spin of the spherical spacecraft. The hypothesized root cause is that the optimization was not able to determine which axis to prioritize detumbling since there was no difference in the axes’s inertia ratios or in the spin rate. Therefore, the optimization ends having only exceeded its iteration limits rather than finding the optimal solution.

Table 5.4: Method 2 optimization results of optimal Δ푡 and associated cost

Spacecraft Shape Spin Δ푡 [푠] Cost flat spin 14.807 -0.0518 Spherical 3D spin N/A N/A nutation N/A N/A flat spin 14.230 0.382 Rectangular 3D spin 34.217 -0.00455 Prism nutation 20.721 0.000930 flat spin 14.317 0.330 Cylindrical 3D spin 29.875 -0.0521 nutation 20.564 -0.0351

For the 3D spin, the rectangular prism and cylindrical spacecraft are initialized

푇 deg with an angular velocity vector [2, 2, 2] s . The spacecraft have the same dimensions and mass, but their moments of inertias are intrinsically different. Such a difference accounts for the slight variation in the control time history, illustrated in Figures 5-6a and 5-6b, as well as the time duration and associated cost.

119 (a) Rectangular prism spacecraft (b) Cylindrical spacecraft Figure 5-6: Angular acceleration profiles as axisymmetric spacecraft initially rotate about all three axes

For the three spacecraft – spherical, rectangular prism, cylindrical – the control effort about the 휓 axis follows a similar pattern over the time duration. The control 푢휓 initially starts at the minimum −0.007, increases in the positive direction (decreases in negative magnitude), and returns to the minimum −0.007 around 푡 = 4 seconds. The control history for the 휑 and 휃 axes of the rectangular prism and cylindrical spacecraft are nearly identical, varying slightly at a handful of time steps (see Figures 5-7b and 5-7c). This is expected since they are both axisymmetric and equivalent in mass and dimensions, yet they vary in their moment of inertia. Contrastingly, the spherical spacecraft is trisymmetric, and the control history for 휑 and 휃 are noticeably different than that of its counterparts (see Figure 5-7a). While not identical, the control history results of the rectangular prism and cylin- drical spacecraft are similar. Both are initialized with an angular velocity vector of

푇 deg [1, 2, 3] s . Similar to the 3D spin, the difference in the control time history isdue to the variation in the inertia ratios, displayed in Figures 5-8a and 5-8b, as well as the time duration and cost.

5.4.3 Comparison of Optimization Results

Generally, the optimal Δ푡 from the direct optimization was smaller across the board than that yielded from the indirect optimization. However, the minimal cost from the indirect optimization method was nominally on the order of magnitude of 10−2 or

120 (a) Spherical spacecraft (b) Rectangular prism spacecraft

(c) Cylindrical spacecraft Figure 5-7: Angular acceleration profiles as spacecraft initially rotate about 휓-axis

(a) Rectangular prism spacecraft (b) Cylindrical spacecraft Figure 5-8: Angular acceleration profiles as axisymmetric spacecraft initially nutate smaller (23 out of 24 results) whereas the direct optimization yielded five out of seven results with a cost 10−2 or smaller. This suggests that the indirect optimization can provide an optimal or near-optimal angular acceleration profile for less computation time. Additionally, this suggests that the patterns recognized from the indirect opti- mization’s yielded results would be applicable as a near-optimal angular acceleration

121 profile – no longer necessitating an optimization to occur in-flight. To further vali- date this point, more functional forms of the angular acceleration should be tested using the indirect optimization method and more experimental spacecraft should be utilized for comparison.

122 Chapter 6

Conclusions and Future Work

6.1 Summary of Thesis

In summary, the work in this thesis proposes solutions to subproblems that constitute the overall problem of autonomous rendezvous and docking with a tumbling and un- cooperative Target spacecraft. These subproblems include the soft-docking terminal approach when the Chaser is within 10 meters of the Target, an optimized detumble procedure of the Target once the Chaser is docked to it so the aggregated system can maneuver jointly, and handling uncertain knowledge with respect to both the Chaser and Target spacecraft. The goal is for all the solutions and software presented herein to be integrated with other aspects of the ROAM project, creating a cohesive software framework for in-space close proximity operations. Such a framework would assist in the technological progress towards fully autonomous rendezvous and docking procedures for satellite servicing, active debris removal, and in-space assembly. In Chapter 1, the interest in autonomous rendezvous and docking for satellite servicing, active debris removal, and in-space assembly was motivated through a dis- cussion of the avenues of science and exploration fully autonomy of each reference mission would yield. Satellite servicing would elongate the lifetime of valuable assets in orbit and facilitate further expansion outward from Earth by providing infrastruc- ture for spacecraft repair and maintenance. Active debris removal is necessary to diminish the effects of the Kessler Syndrome and allow uninhibited access tolow-

123 Earth orbit. In-space assembly would encourage science missions that require space telescopes than what can reasonably be stowed in a payload fairing of a launch vehicle and develop orbiting stations like the ISS. Moreover, autonomous in-space assembly would allow for such developments in remote locations unaccessible by astronauts. Chapter 1 also covered a discussion of the current status of the SPHERES testbed, as that motivated the work outlined in Chapter 4. Additionally, the ROAM project is briefly described, as it was the impetus for the research detailed in Chapters 3and 5. The research objective was formulated as as contributing towards the feasibility of regular and repeatable in-space close proximity missions where a Chaser spacecraft is interacting with an uncooperative, tumbling Target.

In Chapter 2, a literature review was discussed on trajectory optimization for a Chaser approaching a tumbling Target, nonlinear control methodologies relevant for handling uncertainties arising from inertial properties knowledge or actuation failure, and existing literature regarding soft docking and stabilizing a tumbling spacecraft. Several trajectory optimization techniques exist that satisfy minimum time, minimum fuel, or thruster characterizations that are primarily solved offline, although progress has occurred with respect to rapid path-planning algorithms. Popular nonlinear con- trol methods include sliding mode control, which simplifies an푡ℎ n -order system to 1푠푡-order, and adaptive control, notably model reference adaptive control where the user designs the frequency domain characteristics the system should achieve. A few methods for soft docking to a Target were discussed in addition to existing means for detumbling a spacecraft. Much of the existing literature focuses on interfacing with cooperative Targets. The research areas highlighting uncooperative Targets have not performed hardware validation tests – a necessary implementation to increase the technological readiness levels and advance towards autonomous in-space close prox- imity operations.

In Chapter 3, observations were constructed regarding a potential trajectory- generating differential equation that Sternberg proposed in [38] and a propagator was developed to support implementing that differential equation in flight. An ar- gument was constructed disproving that second-order differential equation proposed

124 by Sternberg that was hypothesized based on evidence that a fuel-optimal radially synchronous trajectory of a Chaser approaching a Target was one in which the mag- nitudes of radial and tangential acceleration components were equal. While that conclusion may be true, a vectorized differential equation that equates the radial and tangential acceleration components is not valid as shown by the simple flat spin case. Additionally, it was shown that a trajectory produced from solving this equa- tion with ode45 yielded an outward bound path. Before this conclusion was drawn, a software framework for propagating this differential equation was developed in C code for use on SPHERES. Thus, this chapter details the execution sequence of var- ious critical points in order to produce a series of waypoints that encapsulate the trajectory for a Chaser to follow. This propagator software can be applied to any trajectory-generating differential equation.

In Chapter 4, the state of thruster degradation of the ISS SPHERES free-flyers was analyzed; an in-flight adaptive PID sliding mode controller was developed and validated for use in scenarios of uncertainty due to thruster degradation or uncertainty in inertia properties. With respect to the thruster degradation issue, the thruster forces of Blue and Orange were characterized from a single thruster dance, which yielded concerning results. Thus, new mixers were developed for each satellite to accommodate the failing thrusters and closed-loop tests were designed to measure their performance. In the maintenance session (Test Session 101), Blue, Orange, and Red all performed more thruster characterization tests and their new mixers yielded promising results. Each satellite has at least one seriously crippled thruster, hindering the controllability of the system. Due to the issues the satellites had been experiencing during docking test sessions, an in-flight adaptive PID sliding mode controller was designed and validated in 3-DOF simulation and ground testing that is robust to uncertainty in mass properties knowledge and is a potential solution to the thruster degradation issue. This controller should be expanded to 6-DOF and tested on station to evaluate if it is a feasible way to overcome the actuator failures.

In Chapter 5, Stage 3 of the ROAM mission was modeled as the Chaser already docked with the Target. This modeling included the fleshed out development of the

125 contact dynamics that occur while docking. This is of particular interest for the sce- nario in which the Target is fragile, since it is undesirable to break the Target up by applying too much force or torque. This fragility is not only a concern for the contact dynamics but also when the Chaser detumbles the Target to bring it to a standstill. The Chaser maintains synchronous motion about the Target’s center of mass once it has docked, but it exerts an angular acceleration in order to bring the aggregated standstill. These dynamics were setup in a discrete solver in MATLAB. Two optimization methods were employed to optimize the angular acceleration profile in order to minimize a cost function of fuel consumption and the loads and moments imparted on the Target. Results indicated that the indirect optimization method produced near-optimal results relative to the direct optimization process. These re- sults suggested that further offline optimizations for different angular acceleration functional forms and characteristic spacecraft inertias would provide a useful lookup table for providing near-optimal in-flight solutions.

6.2 Contributions

This section briefly lists the contributions presented in this thesis, as follows:

• Correction regarding matched acceleration differential equation with respect to in-flight trajectory optimization from [38]

• Software framework for handling a trajectory-generating differential equation in C code (specifically developed with SPHERES’s core software in mind)

• A fleshed-out timeline and sequence of executions for a trajectory-generating differential equation

• MATLAB functions to quantify thruster force from SPHERES’s IMU data by smoothing, locating impulses, employing user verification, and outputting mea- sured force versus expected force

126 • Closed-loop unit tests for validating updated mixers designed with respect to specific thruster degradation

• Analysis regarding effectiveness of new mixers and state of thruster degradation of Blue, Orange, and Red SPHERES onboard the ISS

• A validated 3-DOF (with straightforward extension to 6-DOF) in-flight, adap- tive PID sliding mode controller for SPHERES that is robust to uncertainty in inertial properties knowledge

• Implementation of contact dynamics from [67] that output the impulsive force and torque a tumbling Target experiences during docking

• A (MATLAB-coded) discrete solver of a docked Chaser-Target system tumbling synchronously about the Target’s center of mass with a user-defined input to detumble the system

• An optimization methodology that indirectly optimizes the angular acceleration profile by optimizing the desired time interval of the detumble procedure inorder to minimize an objective function of fuel consumption and imparted loads and moments on the Target via looping over three different functional forms of the angular acceleration profile

• An optimization methodology that directly optimizes the angular acceleration profile in order to minimize an objective function of fuel consumption andim- parted loads and moments on the Target using direct collocation via GPOPS

6.3 Recommendations for Future Work

This section lists recommended areas that may be extensions of the work presented in this thesis:

• Invest more time in investigating the relationship Sternberg was onto regarding tangential and radial acceleration magnitudes being equivalent for fuel-optimal R-bar approaches

127 • Implement and validate the trajectory-generating differential equation propa- gator on SPHERES

• Design and implement sliding mode control methods on SPHERES on station to overcome the thruster degradation

• Employ techniques from underactuated robotics for in-flight trajectory opti- mization for SPHERES under thruster failure

• Validate the 6-DOF in-flight adaptive PID sliding mode controller in simulation and then on SPHERES onboard the ISS

• Complete Monte Carlo simulations of the in-flight adaptive PID sliding mode controller to evaluate how robustly it performs

• Test more general functional forms of angular acceleration profiles for the indi- rect optimization of the detumbling procedure between a docked Chaser-Target system

• Create a multi-objective optimization of Δ푉 and imparted loads and moments on the Target as a function of the angular acceleration profile

• From further testing, develop a lookup table of near-optimal angular accelera- tion profiles that can be validated in simulation testing and in-flight

128 Appendix A

Trajectory Optimization

A.1 Fuel-Optimal Trajectory Optimization Func- tions

Listing A.1: TrajectoryOptimizer_v1.m

1 % This script is my re-creation of Sternberg's optimization ... script he 2 % described in his ScD thesis. It performs the following: 3 % 1) An optimization to find optimal delta time spacing fora ... fuel-optimal 4 % approach. This yields an optimal time history associated witha 5 % logarithmically-spaced radial distribution. 6 % 2) Fitsa parameterized approximation to the fuel optimal ... trajectory from 7 % number1 8 % 3) Finds the 2-term Fuel Optimal Exponential Trajectory 9 % 4) Fitting the exponential optimal trajectory! 10 11 %% Set-up 12 clc; 13 close all; 14 15 %% Initialize cells and struct arrays 16 fit_error_exponential = []; 17 computational_time_exponential = []; 18 computational_DV_exponential = []; 19 run_num = 1; 20 run_num_exponential = 1; 21 RESULTS_exponential = []; 22 optimal_time_history = []; 23 optimal_radial_distribution = []; 24 25 %% Set variables 26 num_dt = 100;% Number of time steps 27 NUM_TERMS = 6;% Number of terms to use in function fitting

129 28 omega = 5/norm([0 0 1])*[0 0 1]';% Initial angular velocity of ... Target 29 r0 = 10;% Initial radial distance between Chaser and Target 30 rf = 1;% Final radial distance between Chaser and Target 31 inertia_ratio = [1 1 1]';% Diagonal of inertia matrix 32 fit_type = {'exponential'};% Options: ... {'polynomial','exponential','logistic'} 33 %Tend= 33;% Final times for optimization 34 Tend = [1 20 33 55 240]; 35 for j=1:length(Tend) 36 %% 1. Find the Fuel Optimal Trajectory 37 38 % Setup for fmincon call 39 A = ones(num_dt); 40 b = Tend(j)*ones(num_dt,1); 41 Aeq = ones(1,num_dt); 42 beq = Tend(j); 43 lb = zeros(num_dt,1); 44 ub = Tend(j)*ones(num_dt,1); 45 46 % Initial guess= uniform time step 47 x0 = Tend(j)/num_dt * ones(num_dt,1); 48 % fmincon options 49 tol = 1e-8; 50 options = optimoptions(@fmincon,'OptimalityTolerance',1e-3,... 51 'MaxFunctionEvaluations', 1e6,'MaxIterations',1e7,... 52 'Algorithm','sqp','StepTolerance',tol); 53 % Objective function for fmincon 54 f = @(dt_list)DeltaV_dt(dt_list,omega,r0,rf,inertia_ratio); 55 [dt_out, DV_out,exitflag,output] = fmincon(f,x0,A,b,Aeq,... 56 beq,lb,ub,[],options); 57 disp(['Exitflag:',num2str(exitflag)]); 58 disp(['MinimumDV=',num2str(DV_out),'m/s']) 59 60 % -----Optimal Time History----- 61 t_out = zeros(length(dt_out),1); 62 for i = 1:length(dt_out) 63 t_out(i+1) = t_out(i) + dt_out(i); 64 end 65 66 % -----Radial Distribution----- 67 r = logspace(log10(r0),log10(rf),length(t_out)); r(end) = rf; 68 69 figure(); 70 plot(t_out,r,'-*b'); 71 title({'Optimal Radial Distance ... Profile';['\DeltaV=',num2str(DV_out),'m/s']}) 72 xlabel('Time[s]') 73 ylabel('Radius[m]') 74 75 optimal_time_history = t_out; 76 optimal_radial_distribution = r; 77

130 78 DV_computed = ... DeltaV_dt_r_omega0(dt_out,optimal_radial_distribution,... 79 omega,inertia_ratio,1) 80 % Create struct 81 DV_computed_struct.dt_out(:,j) = dt_out; 82 DV_computed_struct.DV(j) = DV_computed; 83 DV_computed_struct.DV_out(j) = DV_out; 84 DV_computed_struct.Tend(j) = Tend(j); 85 DV_computed_struct.Alin(:,:,j) = Alin; 86 DV_computed_struct.Acen(:,:,j) = Acen; 87 DV_computed_struct.Acor(:,:,j) = Acor; 88 DV_computed_struct.Aang(:,:,j) = Aang; 89 end 90 save('DV_computed_final.mat','DV_computed_struct'); 91 keyboard 92 % Currently, the below code is not designed with the for loop, so ... it will 93 % just use the last optimal radial distribution and time ... distribution. 94 %% 2. Fita parameterized approximation to the fuel optimal ... trajectory 95 [fcnfit_opt,fit_error,B_list]=fit_param_approx(... 96 optimal_radial_distribution, optimal_time_history, r0, rf,... 97 fit_type,NUM_TERMS, num_dt); 98 DV_fit1 = ... DeltaV_dt_r_omega0(dt_out,fcnfit_opt(2,:),omega,inertia_ratio,1) 99 100 %% 3. Find the 2-term Fuel Optimal Exponential Trajectory 101 t_vec = linspace(0,Tend,num_dt+1); 102 dt = diff(t_vec); 103 104 % Nonlinear constrainted optimization function with argumentb- ... the coefficients. 105 nonlcon = @(b)TrajectoryOptimizerVariableStudy_nonlconfunc_B(... 106 t_vec,b,r0,rf,'exponential'); 107 108 scaling_vec = [1; 1; 1; 1]; 109 110 %f is the objective function 111 f = @(exp_coefficients)DeltaV_dt(dt,omega,r0,rf,inertia_ratio,... 112 exp_coefficients./scaling_vec); 113 x0 = B_list{2};% selecting results from step2 as initial guess 114 115 opts = optimoptions(@fmincon,'Algorithm','interior-point'); 116 problem = createOptimProblem('fmincon','objective',f,... 117 'x0',x0,'Aeq',repmat([1,0],1,2),'beq',r0,'lb',[],... 118 'ub',[],'nonlcon',nonlcon,'options',opts); 119 gs = GlobalSearch; 120 [exp_coeff_out,DV_out2] = run(gs,problem); 121 % exp_coeff_out is the value yielding DV_out(global minimum) 122 123 disp(['MinimumDV=',num2str(DV_out2),'m/s']) 124 125 t_out = zeros(length(dt),1);

131 126 for i = 1:length(dt) 127 t_out(i+1) = t_out(i) + dt(i); 128 end 129 130 % Calculates radial profile of Chaser by time history done for ... optimization 131 % of the coefficients- 2-term exponential 132 r = exp_coeff_out(1)*exp(-exp_coeff_out(2)*t_out) + ... 133 exp_coeff_out(3)*exp(-exp_coeff_out(4)*t_out); 134 135 x = t_out;% Re-naming variable 136 yx = r;% Re-naming variable; this is the optimized exp ... trajectory 137 % This is the 100 points along optimal 2-term exponential trajectory 138 figure(); 139 plot(t_out,r); 140 title({'Optimal Radial Distance ... Profile';['\DeltaV=',num2str(DV_out2),'m/s']}) 141 xlabel('Time[s]') 142 ylabel('Radius[m]') 143 144 % This is finding the deltaV from the optimal exp trajectory 145 DeltaV_Optimal = DeltaV_dt_r_omega0(dt,yx',omega,inertia_ratio,1); 146 147 %% 4. Fitting the exponential optimal trajectory! 148 [fcnfit_exp_opt,fit_error,B_list]=fit_param_approx(yx', x, r0, ... rf, fit_type,NUM_TERMS, num_dt); 149 150 num_terms = NUM_TERMS; 151 for i = 1:num_terms 152 switch i 153 case 1 154 fit_coeffs = B_list{1}(:,end); 155 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x); 156 case 2 157 fit_coeffs = B_list{2}(:,end); 158 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x) + ... fit_coeffs(3).*exp(-fit_coeffs(4).*x); 159 case 3 160 fit_coeffs = B_list{3}(:,end); 161 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x) + ... fit_coeffs(3).*exp(-fit_coeffs(4).*x) + ... fit_coeffs(5).*exp(-fit_coeffs(6).*x); 162 case 4 163 fit_coeffs = B_list{4}(:,end); 164 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x) + ... fit_coeffs(3).*exp(-fit_coeffs(4).*x) + ... fit_coeffs(5).*exp(-fit_coeffs(6).*x) +... 165 fit_coeffs(7).*exp(-fit_coeffs(8).*x); 166 case 5 167 fit_coeffs = B_list{5}(:,end); 168 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x) + ... fit_coeffs(3).*exp(-fit_coeffs(4).*x) + ... fit_coeffs(5).*exp(-fit_coeffs(6).*x) +...

132 169 fit_coeffs(7).*exp(-fit_coeffs(8).*x) + ... fit_coeffs(9).*exp(-fit_coeffs(10).*x); 170 case 6 171 fit_coeffs = B_list{6}(:,end); 172 r_fit = fit_coeffs(1).*exp(-fit_coeffs(2).*x) + ... fit_coeffs(3).*exp(-fit_coeffs(4).*x) + ... fit_coeffs(5).*exp(-fit_coeffs(6).*x) +... 173 fit_coeffs(7).*exp(-fit_coeffs(8).*x) + ... fit_coeffs(9).*exp(-fit_coeffs(10).*x) + ... fit_coeffs(11).*exp(-fit_coeffs(12).*x); 174 end 175 176 R_FIT2(:,i) = r_fit; 177 DeltaV_Fit(i) = ... DeltaV_dt_r_omega0(dt,r_fit',omega,inertia_ratio,0); 178 179 end 180 181 DeltaV_Fit_Normalized = DeltaV_Fit/DeltaV_Optimal;% optimal exp ... trajectory 182 183 % Deducing that 2-term is fit, plot radial profile using two-terms 184 figure() 185 plot(x,R_FIT2(:,2)); 186 grid on; 187 xlabel('Time[s]') 188 ylabel('Radius[m]') 189 title('Radial Distance of Exponential Fits') 190 191 figure() 192 plot(DeltaV_Fit_Normalized); 193 grid on; 194 xlabel('Number of Terms') 195 ylabel('Normalized\DeltaV') 196 title('Fit\DeltaV Normalized by Optimal\DeltaV') 197 198 DeltaV_dt_r_omega0(dt,R_FIT2(:,2)',omega,inertia_ratio,1) 199 200 %% Plot all4 201 figure 202 plot(optimal_time_history,optimal_radial_distribution,'-*b'); ... hold on; 203 plot(optimal_time_history,fcnfit_opt(2,:),'-ok'); 204 plot(t_out, yx,'-.g'); 205 plot(t_out, fcnfit_exp_opt(2,:),'--r'); grid on; 206 xlabel('Time[s]','FontSize',18); 207 ylabel('Radius[m]','FontSize',18); 208 legend({'100-Point Optimal Trajectory','2-Term Fit of ... Optimal','100 Points Along Optimal 2-Term Exponential ... Trajectory',... 209 '2-Term Fit to 2-Term Exponential Trajectory'},'FontSize',12);

133 Listing A.2: DeltaV_dt.m

1 function DeltaV = ... DeltaV_dt(dt_list,omega,r0,rf,inertia_ratio,exp_coefficients) 2 % This function is used in optimizations to determine the optimal ... dt_list 3 4 if nargin<6 5 work_with_exponentials = 0; 6 else 7 work_with_exponentials = 1; 8 end 9 10 %Clear the data vectors 11 r_SVC_INT = [r0; 0; 0];%[m] 12 r_SVC_TAR = r_SVC_INT;%A convenient assumption 13 14 I_TAR = diag(inertia_ratio); 15 omega_TAR_INT = deg2rad(omega);% rate of target in inertial frame 16 17 %linear velocity of servicer relative to static target in ... inertial frame 18 v_SVC_INT = fast_cross(omega_TAR_INT,r_SVC_INT); 19 % Make sure this is consistent with other deltaV function 20 21 q_TAR_INT = [0; 0; 0; 1];%quaternion from inertial frame to ... target frame 22 q_UDP_TAR = [0; 0; 0; 1];%quaternion from target frame to ... inertial frame 23 24 % Initialize variables 25 initialize_zeros 26 num_iter = length(dt_list); 27 28 % create the time history 29 for i=1:num_iter 30 t(i+1) = t(i) + dt_list(i); 31 end 32 33 % Define radial distribution 34 if work_with_exponentials 35 rad_dist = exp_coefficients(1)*exp(-exp_coefficients(2)*t) + ... 36 exp_coefficients(3)*exp(-exp_coefficients(4)*t); 37 else%i.e. for full optimization 38 rad_dist = logspace(log10(r0),log10(rf),num_iter+1); 39 end 40 r = r0; 41 42 % Propagate the radial approach 43 for i = 1:num_iter 44 if r(i) < rf 45 break; 46 end 47

134 48 dt = dt_list(i); 49 tumbling_dynamics 50 51 % Calculate accelerations 52 acc_DV_calculations 53 54 % Normalizer to compare against rf 55 r(i+1) = norm(r_SVC_TAR(:,i+1)); 56 57 t(i+1) = t(i) + dt; 58 end% end loop of simulating time until end of spiral 59 60 assignin('base','funcT',t) 61 assignin('base','funcR',rad_dist); 62 63 DV_TOT = DV_total(end); 64 65 DeltaV = DV_TOT; 66 67 end

A.2 Synchronous Radial Approach Propagator

Listing A.3: propagator.c

1 /∗ 2 ∗ propagator.c 3 ∗ 4 ∗ SPHERES Guest Scientist Program custom source code template. 5 ∗ 6 ∗ MIT Space Systems Laboratory 7 ∗ SPHERES Guest Scientist Program 8 ∗ http://ssl.mit.edu/spheres/ 9 ∗ 10 ∗ Copyright 2018 Massachusetts Institute of Technology 11 ∗ 12 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ 13 ∗ Propagator Functions ∗ 14 ∗ By: Hailee Hettrick ∗ 15 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ 16 ∗ Last modified: 06/17/18 ∗ 17 ∗ ∗ 18 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ 19 ∗/ 20 21 #include"propagator.h" 22 #include"spheres_constants.h" 23 #include"spheres_physical_parameters.h" 24 #include"math_quat.h" 25 #include"math_matrix.h"

135 26 #include 27 28 #ifdef SPH_MATLAB_SIM 29 #include"../ Simulation/vasSimulator.h" 30 #include"mex.h" 31 #define DEBUG(arg) mexPrintf arg 32 #else 33 #define DEBUG( arg ) 34 #endif 35 36 // Real info 37 f l o a t I_TAR[3][3] = {{0.028856093583883000f ,-0.000271760426029421f ... , 0.001061424114444470f}, 38 { -0.000271760426029421f , 0.055986602544449500f , ... 0.000183704942897512f}, 39 { 0.001061424114444470f , 0.000183704942897512f , ... 0.058822298355749900f }}; 40 // TODO: calculate this inverse in function 41 f l o a t inv_I_TAR[3][3] = {{34.679367795347211f , 0.170389611606066f , ... -0.626307024637702f}, 42 { 0.170389611606066f , 17.862436235713918f , -0.058859880828906f}, 43 {-0.626307024637702f , -0.058859880828906f , 17.011841056908086f ... }}; 44 45 // angular acceleration initial 46 f l o a t omega_dot_TAR_INT[3]= {0.0 f , 0 . 0 f , 0 . 0 f } ; 47 48 // q_dot initial 49 f l o a t q_dot_TAR_INT[4]= {1.0f, 0.0f, 0.0f, 0.0f}; 50 51 f l o a t I_by_omega[3]; 52 f l o a t new_omega_TAR_INT [ 3 ] ; 53 f l o a t new_omega_dot_TAR_INT [ 3 ] ; 54 f l o a t new_q_TAR_INT [ 4 ] ; 55 f l o a t new_q_dot_TAR_INT [ 4 ] ; 56 f l o a t int_new_q_dot_TAR_INT [ 4 ] ; 57 f l o a t cross_prod[3]; 58 f l o a t int_q_dot[4]; 59 f l o a t q_dot_TAR_INT [ 4 ] ; 60 f l o a t quat_term[4]; 61 f l o a t quat_term3[3]; 62 f l o a t quat_term_vec_norm; 63 f l o a t temp; 64 f l o a t quat_exponential_term [4]; 65 f l o a t quat_exp_sin[3]; 66 f l o a t q_TAR_INT_conj [ 4 ] ; 67 f l o a t new_q_TAR_INT_conj [ 4 ] ; 68 f l o a t array_with_zero[4]; 69 f l o a t dt_setup = -1.0f; 70 71 // Back propagate 72 f l o a t rdot_SVC_TAR[3] = {0.01f, 0.0f, 0.0f};//slow arrival 73 f l o a t B[3][3]; 74 f l o a t C[3][3];

136 75 i n t i,j,k,l,m; 76 f l o a t A[6][6]; 77 f l o a t x[6]; 78 f l o a t drdot[3]; 79 f l o a t dxdt[6]; 80 f l o a t new_r_SVC_TAR [ 3 ] ; 81 f l o a t new_rdot_SVC_TAR [ 3 ] ; 82 f l o a t new_r_SVC_INT [ 3 ] ; 83 f l o a t new_rdot_SVC_INT [ 3 ] ; 84 i n t counter; 85 f l o a t q_UDP_INT [ 4 ] ; 86 f l o a t G[3][3]; 87 f l o a t dotproduct; 88 f l o a t crossproduct; 89 f l o a t temp_radial_profile[2000][3]; 90 f l o a t x_factor; 91 i n t non_zero=0; 92 93 /∗ f o r quat check ∗/ 94 f l o a t z_rot[4] = {0.0f, 0.0f, -1.0f, 0.0f}; 95 f l o a t checkTargetQuat[4]; 96 f l o a t compWDesired; 97 //float old_compWDesired= 0.0f; 98 99 /∗∗∗∗∗∗∗ Check if quaternion is aligned ∗∗∗∗∗∗∗ / 100 void quaternionCheck(float ∗ c t r l S t a t e , float ∗ tgtState , int flag){ 101 // Is Chaser almost alongr-bar of Target? If not, it waits. 102 quatMult_noNorm(checkTargetQuat , &ctrlState [QUAT_1] , z_rot) ; 103 104 // Compare checkTargetQuat with tgtState[QUAT_2] 105 compWDesired = checkTargetQuat[1] - tgtState [QUAT_2];// TODO: ... update this so that it is flexible for axisr-bar is along 106 107 i f ((compWDesired < 0.05f) && (compWDesired > -0.05f)){ 108 f l a g = 1 ; 109 } 110 } 111

112 113 /∗∗∗∗∗∗∗ Forward Propagate for TAR' sq, qdot, omega, omegadot info ... ∗∗∗∗∗∗∗ / 114 void forwardPropagate(float ∗ tgtState , float q_TAR_INT_array... [ 2 0 0 0 ] [ 4 ] , float omega_TAR_INT_array[2000][3] ,float ... q_dot_TAR_INT_array[2000][4] , float omega_dot_TAR_INT_array... [2000][3]){ 115 // Forward propagate q_TAR_INT and omega_TAR_INTa specified ... number of time constants to determine when backwards ... propagation should start 116 // Inputs: current Target ' s quaternion and angular rate. Inertia ... from estimation process. 117 // Outputs: future quaternion and angular rates for specified ... number of periods 118 119 // rotation rate

137 120 f l o a t omega_TAR_INT [ 3 ] ; 121 memcpy(&omega_TAR_INT [ 0 ] , &t g t S t a t e [RATE_X] , sizeof(float) ∗3) ; ... //[rad/s] 122 omega_TAR_INT_array [ 0 ] [ 0 ] = omega_TAR_INT[ 0 ] ; 123 omega_TAR_INT_array [ 0 ] [ 1 ] = omega_TAR_INT[ 1 ] ; 124 omega_TAR_INT_array [ 0 ] [ 2 ] = omega_TAR_INT[ 2 ] ; 125 126 f l o a t q_TAR_INT [ 4 ] ; 127 memcpy(&q_TAR_INT[ 0 ] , &t g t S t a t e [QUAT_1] , sizeof(float) ∗3) ; 128 q_TAR_INT_array [ 0 ] [ 0 ] = q_TAR_INT [ 0 ] ; 129 q_TAR_INT_array [ 0 ] [ 1 ] = q_TAR_INT [ 1 ] ; 130 q_TAR_INT_array [ 0 ] [ 2 ] = q_TAR_INT [ 2 ] ; 131 q_TAR_INT_array [ 0 ] [ 3 ] = q_TAR_INT [ 3 ] ; 132 133 f o r(i=0; i<3; i++){ 134 omega_dot_TAR_INT_array [0][ i ] = omega_dot_TAR_INT[ i ]; 135 } 136 137 f o r(i=0; i<4; i++){ 138 q_dot_TAR_INT_array[0][ i ] = q_dot_TAR_INT[ i ]; 139 } 140 141 /∗ Determine period of rotation ∗/ 142 f l o a t T, T1, T2, T3; 143 T1 = abs(2.0f ∗3.14 f /omega_TAR_INT [ 0 ] ) ; 144 T2 = abs(2.0f ∗3.14 f /omega_TAR_INT [ 1 ] ) ; 145 T3 = abs(2.0f ∗3.14 f /omega_TAR_INT [ 2 ] ) ;//[s] time period of ... r o t a t i o n 146 147 i f (T1 < T2 && T1 < T3) { 148 T = T1 ; 149 } else if (T2 < T1 && T2 < T3) { 150 T = T2 ; 151 } else if (T3 < T1 && T3 < T2) { 152 T = T3 ; 153 } 154 155 f l o a t n_T; 156 n_T = 0.90 f ∗T; 157 158 //M and tau will be inputs eventually 159 f l o a t M_TAR[3] = {0.0f, 0.0f, 0.0f}; 160 f l o a t tau_TAR[3] = {0.0f, 0.0f, 0.0f}; 161 f l o a t dt = -dt_setup; 162 f l o a t t= 0.0f; 163 164 i n t c=1; 165 166 while( t < n_T){ 167 // Clear memory 168 memset(&I_by_omega ,0 , sizeof(float) ∗3) ; 169 memset(&new_omega_dot_TAR_INT, 0 , sizeof(float) ∗3) ; 170 memset(&new_q_dot_TAR_INT, 0 , sizeof(float) ∗4) ; 171 memset(&new_q_TAR_INT, 0 , sizeof(float) ∗4) ;

138 172 memset(&new_omega_TAR_INT, 0 , sizeof(float) ∗3) ; 173 174 /∗ Construct omegadot equation: omegadot=I^(-1)(-omega cross ... (I ∗omega+M)+ tau) ∗/ 175 f o r(i=0; i<3; i++){ 176 f o r(j=0; j<3; j++){ 177 I_by_omega[ i ] += I_TAR[ i ][ j] ∗omega_TAR_INT[ j ] ;//I ∗omega 178 } 179 I_by_omega[ i ] += M_TAR[ i ];//I ∗omega+M 180 } 181 182 cross_prod [ 0 ] = -omega_TAR_INT [ 1 ] ∗ I_by_omega [2]+omega_TAR_INT... [ 2 ] ∗ I_by_omega[1] + tau_TAR[0];//-omega cross(I ∗omega+M)+ ... tau 183 cross_prod [ 1 ] = -omega_TAR_INT [ 2 ] ∗ I_by_omega [0]+omega_TAR_INT... [ 0 ] ∗ I_by_omega[2] + tau_TAR[1]; 184 cross_prod [ 2 ] = -omega_TAR_INT [ 0 ] ∗ I_by_omega [1]+omega_TAR_INT... [ 1 ] ∗ I_by_omega[0] + tau_TAR[2]; 185 186 f o r(i=0; i<3; i++){ 187 f o r(j=0; j<3; j++){ 188 new_omega_dot_TAR_INT [ i ] += inv_I_TAR [ i ] [ j ] ∗ cross_prod[j ]; ... //omegadot=I^(-1)(-omega cross(I ∗omega+M)+ tau) 189 } 190 } 191 192 //New omega value using omegadot equation 193 f o r(i=0; i<3; i++){ 194 new_omega_TAR_INT[ i ] = omega_TAR_INT[ i ] + omega_dot_TAR_INT [ ... i ] ∗ ( dt ) ; 195 } 196 197 /∗ Construct qdot equation ∗/ 198 f o r(i=0; i<3; i++){ 199 array_with_zero [ i ] = omega_TAR_INT[ i ] ; 200 } 201 array_with_zero[3] = 0.0f; 202 quatMult_noNorm(int_q_dot ,q_TAR_INT, array_with_zero) ; 203 204 f o r(i=0; i<4; i++){ 205 new_q_dot_TAR_INT [ i ] = 0 . 5 f ∗int_q_dot[ i ]; 206 int_new_q_dot_TAR_INT [ i ] = ( dt ) ∗new_q_dot_TAR_INT [ i ] ; 207 } 208 209 f o r (i=0; i<3; i++){ 210 q_TAR_INT_conj [ i ] = -q_TAR_INT[ i ] ; 211 } 212 q_TAR_INT_conj [ 3 ] = q_TAR_INT [ 3 ] ; 213 quatMult_noNorm ( quat_term , q_TAR_INT_conj , int_new_q_dot_TAR_INT... ); 214 215 f o r (i=0; i<3; i++){ 216 quat_term3[ i]=quat_term[ i ]; 217 }

139 218 219 // Normalize quat_term3 220 temp = 0 ; 221 f o r (j=0; j<3; j++){ 222 temp += quat_term3[ j ] ∗ quat_term3[ j ]; 223 } 224 quat_term_vec_norm = sqrtf (temp) ; 225 226 f o r (k=0; k<3; k++){ 227 quat_exp_sin[k] = quat_term3[k] ∗ sin (quat_term_vec_norm)/... quat_term_vec_norm ; 228 quat_exponential_term[k] = exp(quat_term[3]) ∗quat_exp_sin[k... ]; 229 } 230 quat_exponential_term[3] = exp(quat_term[3]) ∗ cos (... quat_term_vec_norm) ; 231 quatMult_noNorm(new_q_TAR_INT,q_TAR_INT, quat_exponential_term )... ; 232 233 f o r(i=0; i<3; i++){ 234 omega_TAR_INT_array [ c ] [ i ] = new_omega_TAR_INT[ i ] ; 235 } 236 237 f o r(i=0; i<4; i++){ 238 q_TAR_INT_array [ c ] [ i ] = new_q_TAR_INT[ i ] ; 239 } 240 241 f o r(i=0; i<3; i++){ 242 omega_dot_TAR_INT_array [ c ] [ i ] = new_omega_dot_TAR_INT [ i ] ; 243 } 244 245 f o r(i=0; i<4; i++){ 246 q_dot_TAR_INT_array [ c ] [ i ] = new_q_dot_TAR_INT [ i ] ; 247 } 248 249 memcpy(&q_TAR_INT[ 0 ] , &new_q_TAR_INT[ 0 ] , sizeof(float) ∗4) ; 250 memcpy(&omega_TAR_INT [ 0 ] , &new_omega_TAR_INT [ 0 ] , sizeof(float) ... ∗3) ; 251 memcpy(&omega_dot_TAR_INT [ 0 ] , &new_omega_dot_TAR_INT [ 0 ] , ... s i z e o f(float) ∗3) ; 252 memcpy(&q_dot_TAR_INT [ 0 ] , &new_q_dot_TAR_INT [ 0 ] , sizeof(float) ... ∗4) ; 253 254 t = t + dt ; 255 c++;//counter for arrays 256 } 257 } 258 259 /∗∗∗∗∗∗∗ Back Propagate to TAR' s initial position ∗∗∗∗∗∗∗ / 260 void propagateToTarget(float ∗ c t r l S t a t e , float ∗ tgtState , float ... radial_profile[2000][3] , float velocity_profile[2000][3], float ... q_TAR_INT_array [ 2 0 0 0 ] [ 4 ] , float omega_TAR_INT_array[2000][3] , ... f l o a t q_dot_TAR_INT_array[2000][4] , float ... omega_dot_TAR_INT_array[2000][3]) {

140 261 262 // This should occur after every estimation stage. 263 // Initially, setup does not provide estimation knowledge of ... Target so we ' l l use true knowledge first 264 // Output: Profile for Chaser to follow(r_SVC_INT) 265 266 // Trim arrays down 267 f o r(i=0; i<1999; i++){ 268 i f ( ( q_TAR_INT_array [ i ] [ 0 ] ! = 0) | | (q_TAR_INT_array [ i ] [ 1 ] ! = 0) ... | | (q_TAR_INT_array [ i ] [ 2 ] ! = 0) | | (q_TAR_INT_array [ i ] [ 3 ] ! = 0) ) { 269 non_zero++; 270 } 271 } 272 i n t id = non_zero-1; 273 274 f l o a t dt = dt_setup; 275 276 // r_initial= Chaser ' s current position offset by the target ' s ... p o s i t i o n 277 f l o a t r_initial[3]; 278 f o r(i=0; i<3; i++){ 279 r_initial[i] = ctrlState[i]-tgtState[i]; 280 } 281 282 f l o a t q_TAR_INT [ 4 ] ; 283 memcpy(&q_TAR_INT[ 0 ] , &q_TAR_INT_array [ id ] [ 0 ] , sizeof(float) ∗4) ; 284 285 // rotation rate 286 f l o a t omega_TAR_INT [ 3 ] ; 287 288 // DCM transformation for desired offset from Target ' s CG 289 f l o a t dcm_init[3][3]; 290 dcm_from_quat(dcm_init , q_TAR_INT) ; 291 f l o a t r_SVC_INT [ 3 ] ; 292 f l o a t r_SVC_TAR [ 3 ] ; 293 f l o a t vec[3] = {0.4f, 0.0f, 0.0f};//r_standfof 294 f o r(i=0;i<3; i++){ 295 r_SVC_INT[ i ] = 0 . 0 f ; 296 f o r(j=0;j<3;j++){ 297 r_SVC_INT[ i ] += dcm_init [ i ] [ j ] ∗ vec [ j ] ; 298 } 299 } 300 vecRotbyQuat (q_TAR_INT,r_SVC_TAR,r_SVC_INT) ; 301 302 //quaternion from state vector is rotation from global frame to ... body frame 303 f l o a t q_UDP_TAR[ 4 ] = {0 , 0 , 0 , 1 } ;//quaternion from UDP frame ... to Target frame- observed in estimation 304 305 //r(i+1)= norm(r_SVC_TAR(:,i+1)); 306 f l o a t r_temp = 0; 307 f l o a t r0_temp = 0; 308 f l o a t r; 309 f o r (i=0; i<3; i++){

141 310 r_temp += r_SVC_INT[ i ] ∗r_SVC_INT[ i ] ; 311 r0_temp += r_initial[i] ∗ r_initial[i];// aka stop back ... propagation once you get to Chaser ' s current position 312 } 313 r = sqrtf(r_temp); 314 f l o a t r0; 315 r0 = sqrtf(r0_temp); 316 317 // This will be the Chaser ' s final move towards Target 318 f o r (i=0; i<3; i++){ 319 radial_profile [1999][ i ] = r_SVC_INT[ i ]; 320 } 321 322 // Weird attempt to get Sternberg ' s equation to work 323 f l o a t norm_rate = sqrtf(omega_TAR_INT_array[ id ][0] ∗ ... omega_TAR_INT_array[ id ][0] + omega_TAR_INT_array[ id ][1] ∗ ... omega_TAR_INT_array[ id ][1] + omega_TAR_INT_array[ id ][2] ∗ ... omega_TAR_INT_array[ id ][2]) ; 324 f l o a t rate = norm_rate ∗180.0f/3.14f; 325 x_factor = 0.1∗ r a t e / 5 ; 326 327 counter = 0 ; 328 while ((r < r0) && (counter < 2000)){ 329 330 //quatMult_noNorm(q_UDP_INT,q_UDP_TAR,q_TAR_INT);//returns ... q_UDP_INT 331 //quatMult_noNorm(q_UDP_INT,q_TAR_INT,q_UDP_TAR); 332 //q_SVC_INT= quatConj(q_UDP_INT);//math_quat.c 333 334 // Clear memory 335 memset(&dxdt ,0 , sizeof(float) ∗6) ; 336 memset(&drdot ,0 , sizeof(float) ∗3) ; 337 memset(&new_r_SVC_INT, 0 , sizeof(float) ∗3) ; 338 memset(&new_r_SVC_TAR, 0 , sizeof(float) ∗3) ; 339 memset(&new_rdot_SVC_TAR, 0 , sizeof(float) ∗3) ; 340 341 // Update Target ' s orientation information 342 f o r(i=0; i<3; i++){ 343 omega_TAR_INT[ i ] = omega_TAR_INT_array[ id - counter ][ i ]; 344 omega_dot_TAR_INT[ i ] = omega_dot_TAR_INT_array[ id - counter ][ i ... ]; 345 } 346 347 f o r(i=0;i<4; i++){ 348 q_TAR_INT[ i ] = q_TAR_INT_array [ id - counter ] [ i ] ; 349 new_q_TAR_INT[ i ] = q_TAR_INT_array [ id - counter - 1 ] [ i ] ; 350 q_dot_TAR_INT[ i ] = q_dot_TAR_INT_array[ id - counter ][ i ]; 351 } 352 353 // Now, set upA,B,C matrices 354 f l o a t w_skew[3][3] = { 355 {0 , -omega_TAR_INT [ 2 ] , omega_TAR_INT[ 1 ] } , 356 {omega_TAR_INT [ 2 ] , 0 , -omega_TAR_INT [ 0 ] } , 357 { -omega_TAR_INT [ 1 ] , omega_TAR_INT [ 0 ] , 0}

142 358 }; 359 f l o a t wdot_skew[3][3] = { 360 {0 , -omega_dot_TAR_INT [ 2 ] , omega_dot_TAR_INT [ 1 ] } , 361 {omega_dot_TAR_INT [ 2 ] , 0 , -omega_dot_TAR_INT [ 0 ] } , 362 { -omega_dot_TAR_INT [ 1 ] , omega_dot_TAR_INT [ 0 ] , 0} 363 }; 364 365 f o r (i=0; i<3; i++){ 366 f o r (j=0; j<3; j++){ 367 B[ i ] [ j ] = 2∗w_skew[i ][ j ]; 368 C[i][j] = (-wdot_skew[i][j] + w_skew[i][j] ∗ w_skew[i ][ j ])/... x_factor ; 369 } 370 } 371 f o r (k=0; k<3; k++){ 372 f o r (l=0; l<3; l++){ 373 A[ k ] [ l ]= 0 ; 374 } 375 f o r (m=3; m<6; m++){ 376 A[ k ] [m] = 1 ; 377 } 378 } 379 f o r (k=3; k<6; k++){ 380 f o r (l=0; l<3; l++){ 381 A[k][l]= C[k-3][l]; 382 } 383 f o r (m=3; m<6; m++){ 384 A[k][m] = B[k-3][m-3]; 385 } 386 } 387 388 f o r(i=0; i<3; i++){ 389 x [ i ] = r_SVC_TAR[ i ] ; 390 x [ i +3] = rdot_SVC_TAR [ i ] ; 391 } 392 393 //dxdt=A ∗x; 394 f o r(j=0; j<6; j++){ 395 f o r(k=0; k<6; k++){ 396 dxdt[j] += A[j][k] ∗ x [ k ] ; 397 } 398 } 399 400 f o r(i=0; i<3; i++){ 401 drdot[i] = dxdt[i+3]; 402 } 403 404 //new_r_SVC_TAR= r_SVC_TAR+ drdot ∗ dt 405 //rdot_SVC_TAR(:,i+1)=(r_SVC_TAR(:,i)- r_SVC_TAR(:,i+1))/ ... (dt); 406 i =0; 407 f o r (i=0; i<3; i++){ 408 new_r_SVC_TAR[ i ] = r_SVC_TAR[ i ] + drdot [ i ] ∗ ( dt ) ;

143 409 new_rdot_SVC_TAR [ i ] = (r_SVC_TAR[ i ] - new_r_SVC_TAR[ i ] ) /( dt )... ; 410 } 411 412 f o r (i=0; i<3; i++){ 413 new_q_TAR_INT_conj [ i ] = -new_q_TAR_INT[ i ] ; 414 } 415 new_q_TAR_INT_conj [ 3 ] = new_q_TAR_INT [ 3 ] ; 416 417 //r_SVC_INT(:,i+1)= trans_vec(conj_quat(q_TAR_INT(:,i+1)), ... r_SVC_TAR(:,i+1)); 418 vecRotbyQuat (new_q_TAR_INT_conj , new_r_SVC_INT,new_r_SVC_TAR) ; 419 vecRotbyQuat (new_q_TAR_INT_conj , new_rdot_SVC_INT , 420 new_rdot_SVC_TAR) ; 421 422 counter++; 423 // TODO: add tgtState back here if no radial shift is required 424 f o r(i=0; i<3; i++){ 425 radial_profile[1999-counter ][ i ] = new_r_SVC_INT[ i ]; 426 velocity_profile[1999-counter ][ i ] = new_rdot_SVC_INT[ i ]; 427 } 428 429 memcpy(&r_SVC_INT [ 0 ] , &new_r_SVC_INT [ 0 ] , sizeof(float) ∗3) ; 430 memcpy(&r_SVC_TAR[ 0 ] , &new_r_SVC_TAR[ 0 ] , sizeof(float) ∗3) ; 431 memcpy(&rdot_SVC_TAR [ 0 ] , &new_rdot_SVC_TAR [ 0 ] , sizeof(float) ... ∗3) ; 432 433 //r(i+1)= norm(r_SVC_TAR(:,i+1)); 434 f l o a t r_temp = 0; 435 f o r (i=0; i<3; i++){ 436 r_temp += new_r_SVC_TAR[ i ] ∗new_r_SVC_TAR[ i ] ; 437 } 438 r = sqrtf(r_temp); 439 } 440 441 442 /∗∗∗∗∗∗∗∗∗∗ Trajectory Shift ∗∗∗∗∗∗∗∗∗∗ / 443 // TODO: Add else statement for if shift isn ' t necessary but to ... add tgtState back in 444 // 1999-counter equals CHASER ' s first step. This needs to equal ... Chaser ' s current position. 445 i f(radial_profile[1999-counter][0] != ctrlState[0]-tgtState[0]){ ... // then find rotation matrix 446 // Make them unit vectors first 447 f l o a t rad_profile_mag = sqrtf(radial_profile[1999-counter][0] ∗ 448 radial_profile[1999-counter][0] + radial_profile[1999-... counter][1] ∗ 449 radial_profile[1999-counter][1]+radial_profile[1999-counter... ] [ 2 ] ∗ 450 radial_profile[1999-counter][2]) ; 451 f l o a t unit_rad_profile[3] = {radial_profile[1999-counter][0]/ 452 rad_profile_mag , radial_profile[1999-counter ][1]/ ... rad_profile_mag , 453 radial_profile[1999-counter ][2]/rad_profile_mag};

144 454 f l o a t ctrlState_mag = sqrtf((ctrlState[0]) ∗(ctrlState[0]) + 455 (ctrlState [1]) ∗(ctrlState[1]) + (ctrlState[2]) ∗( c t r l S t a t e ... [ 2 ] ) ) ; 456 f l o a t unit_ctrlState[3] = {(ctrlState [0])/ctrlState_mag , 457 (ctrlState [1])/ctrlState_mag ,( ctrlState [2])/ctrlState_mag}; 458 459 // dot product 460 dotproduct=0; 461 f o r(i=0; i<3; i++){ 462 dotproduct += unit_rad_profile[ i ] ∗ (unit_ctrlState[i]); 463 } 464 // cross product magnitude 465 f l o a t s1 = unit_rad_profile[1] ∗ (unit_ctrlState[2]) - ... unit_rad_profile [2] ∗ (unit_ctrlState[1]) ; 466 f l o a t s2 = unit_rad_profile[2] ∗ (unit_ctrlState[0]) - ... unit_rad_profile [0] ∗ (unit_ctrlState[2]) ; 467 f l o a t s3 = unit_rad_profile[0] ∗ (unit_ctrlState[1]) - ... unit_rad_profile [1] ∗ (unit_ctrlState[0]) ; 468 crossproduct = sqrtf(s1 ∗ s1 + s2 ∗ s2 + s3 ∗ s3 ) ; 469 470 // constructG matrix 471 G[0][0] = dotproduct; 472 G[0][1] = -crossproduct; 473 G[0][2] = 0.0f; 474 G[1][0] = crossproduct; 475 G[1][1] = dotproduct; 476 G[1][2] = 0.0f; 477 G[2][0] = 0.0f; 478 G[2][1] = 0.0f; 479 G[2][2] = 1.0f; 480 481 // ConstructF, Finv 482 f l o a t midterm[3] = {unit_ctrlState[0]-dotproduct ∗... unit_rad_profile[0] , 483 unit_ctrlState [1] -dotproduct ∗ unit_rad_profile[1] , 484 unit_ctrlState [2] -dotproduct ∗ unit_rad_profile [2]}; 485 f l o a t midterm_mag = sqrtf(midterm[0] ∗ midterm[0] + 486 midterm [ 1 ] ∗ midterm[1] + midterm[2] ∗ midterm[2]) ; 487 f l o a t F[3][3]; 488 f l o a t Finv[3][3] = {{unit_rad_profile[0], midterm[0]/ ... midterm_mag, s1}, 489 {unit_rad_profile [1] , midterm[1]/midterm_mag, s2}, 490 {unit_rad_profile [2] , midterm[2]/midterm_mag, s3}}; 491 matrixInverse(F, Finv); 492 493 // constructU 494 f l o a t U[3][3]; 495 f l o a t int_prod[3][3]; 496 f o r(i=0; i<3; i++){ 497 f o r(j=0; j<3; j++){ 498 int_prod[i][j] = 0.0f; 499 f o r(k=0; k<3; k++){ 500 int_prod[i][j] += G[i][k] ∗F [ k ] [ j ] ; 501 }

145 502 } 503 } 504 f o r(i=0; i<3; i++){ 505 f o r(j=0; j<3; j++){ 506 U[i][j] = 0.0f; 507 f o r(k=0; k<3; k++){ 508 U[i][j] += Finv[i][k] ∗ int_prod[k][ j ]; 509 } 510 } 511 } 512 513 514 // create temporary array to hold current radial profile 515 f o r(i=0; i<2000; i++){ 516 f o r(j=0; j<3; j++){ 517 temp_radial_profile[i ][j] = radial_profile[i ][j]; 518 } 519 } 520 521 // re-write radial profile with the rotation in place 522 f o r(i=0; i

146 556 minv[0][1] = (m[0][2] ∗ m[2][1] - m[0][1] ∗ m[ 2 ] [ 2 ] ) ∗ invdet ; 557 minv[0][2] = (m[0][1] ∗ m[1][2] - m[0][2] ∗ m[ 1 ] [ 1 ] ) ∗ invdet ; 558 minv[1][0] = (m[1][2] ∗ m[2][0] - m[1][0] ∗ m[ 2 ] [ 2 ] ) ∗ invdet ; 559 minv[1][1] = (m[0][0] ∗ m[2][2] - m[0][2] ∗ m[ 2 ] [ 0 ] ) ∗ invdet ; 560 minv[1][2] = (m[1][0] ∗ m[0][2] - m[0][0] ∗ m[ 1 ] [ 2 ] ) ∗ invdet ; 561 minv[2][0] = (m[1][0] ∗ m[2][1] - m[2][0] ∗ m[ 1 ] [ 1 ] ) ∗ invdet ; 562 minv[2][1] = (m[2][0] ∗ m[0][1] - m[0][0] ∗ m[ 2 ] [ 1 ] ) ∗ invdet ; 563 minv[2][2] = (m[0][0] ∗ m[1][1] - m[1][0] ∗ m[ 0 ] [ 1 ] ) ∗ invdet ; 564 565 } 566 567 void dcm_from_quat(float dcm[3][3] , float ∗ quat ) { 568 // Find the direction cosine matrix froma quaternion. 569 f l o a t q1 = quat[0]; 570 f l o a t q2 = quat[1]; 571 f l o a t q3 = quat[2]; 572 f l o a t q0 = quat[3];// scalar value 573 574 dcm[0][0] = q0∗q0+q1∗q1 - q2∗q2 - q3∗q3 ; 575 dcm[0][1] = 2∗( q1∗q2+q0∗q3 ) ; 576 dcm[0][2] = 2∗( q1∗q3 - q0∗q2 ) ; 577 dcm[1][0] = 2∗( q1∗q2 - q0∗q3 ) ; 578 dcm[1][1] = (q0∗q0 - q1∗q1+q2∗q2 - q3∗q3 ) ; 579 dcm[1][2] = 2∗( q2∗q3+q0∗q1 ) ; 580 dcm[2][0] = 2∗( q1∗q3+q0∗q2 ) ; 581 dcm[2][1] = 2∗( q2∗q3 - q0∗q1 ) ; 582 dcm[2][2] = (q0∗q0 - q1∗q1 - q2∗q2+q3∗q3 ) ; 583 584 }

147 148 Appendix B

Adaptive Control for Uncertainty

B.1 Thruster Characterization Plots

] ] -2 -2 Raw IMU data for Sphere logical ID 1 Raw IMU data for Sphere logical ID 2 0.05 0 1 0.05 0 1

0 0

-0.05 6 7 -0.05 6 7

14 16 18 20 22 24 14 16 18 20 22 24

X-Accelerometers [m s [m X-Accelerometers s [m X-Accelerometers

] ]

-2 -2 0.05 2 3 0.05 2 3

0 0

-0.05 8 9 -0.05 8 9

14 16 18 20 22 24 14 16 18 20 22 24

Y-Accelerometers [m s [m Y-Accelerometers s [m Y-Accelerometers

] ]

-2 -2 0.05 4 5 0.05 4 5

0 0

-0.05 10 11 -0.05 10 11 Z-Accelerometers [m s [m Z-Accelerometers Z-Accelerometers [m s [m Z-Accelerometers 14 16 18 20 22 24 14 16 18 20 22 24 Test time, s Test time, s

(a) SPH1 (Blue) 50 ms (b) SPH2 (Orange) 50 ms

] ] -2 -2 Raw IMU data for Sphere logical ID 1 Raw IMU data for Sphere logical ID 2 0.05 0 1 0.05 0 1

0 0

-0.05 6 7 -0.05 6 7

26 28 30 32 34 36 26 28 30 32 34 36

X-Accelerometers [m s [m X-Accelerometers s [m X-Accelerometers

] ]

-2 -2 0.05 2 3 0.05 2 3

0 0

-0.05 8 9 -0.05 8 9

26 28 30 32 34 36 26 28 30 32 34 36

Y-Accelerometers [m s [m Y-Accelerometers s [m Y-Accelerometers

] ]

-2 -2 0.05 4 5 0.05 4 5

0 0

-0.05 10 11 -0.05 10 11 Z-Accelerometers [m s [m Z-Accelerometers Z-Accelerometers [m s [m Z-Accelerometers 26 28 30 32 34 36 26 28 30 32 34 36 Test time, s Test time, s

(c) SPH1 (Blue) 100 ms (d) SPH1 (Orange) 100 ms Figure B-1: Thruster Characterization: 50 ms and 100 ms Impulses

149 B.2 Thruster Characterization Functions

Listing B.1: pulse_extraction.m

1 function pulses = pulse_extraction(sphnum) 2 % Specifically designed for T18 of TS97 3 % Run this file first. After running this, run process_pulses_sph.m 4 5 load('saved_imu_1.mat'); 6 load('saved_imu_2.mat'); 7 8 user_input = 1; 9 10 if sphnum == 1 11 time = imu_sph_1.gyro{2}.Time; 12 time_ind = find(time≥37.25&time≤50.7); 13 sdata(:,2) = time(time_ind); 14 time_x = imu_sph_1.gyro{1}.Time; 15 sph1_gyro_x = interp1(time_x,imu_sph_1.gyro{1}.Data,time); 16 sdata(:,3) = smooth(sph1_gyro_x(time_ind),7); 17 sph1_gyro_y = imu_sph_1.gyro{2}.Data; 18 sdata(:,4) = smooth(sph1_gyro_y(time_ind),7); 19 time_z = imu_sph_1.gyro{3}.Time; 20 sph1_gyro_z = interp1(time_z,imu_sph_1.gyro{3}.Data,time); 21 sdata(:,5) = smooth(sph1_gyro_z(time_ind),7); 22 time_x_a = imu_sph_1.accel{1}.Time; 23 sph1_accel_x = interp1(time_x_a,imu_sph_1.accel{1}.Data,time); 24 sdata(:,6) = smooth(sph1_accel_x(time_ind),7); 25 time_y_a = imu_sph_1.accel{2}.Time; 26 sph1_accel_y = interp1(time_y_a,imu_sph_1.accel{2}.Data,time); 27 sdata(:,7) = smooth(sph1_accel_y(time_ind),7); 28 time_z_a = imu_sph_1.accel{3}.Time; 29 sph1_accel_z = interp1(time_z_a,imu_sph_1.accel{3}.Data,time); 30 sdata(:,8) = smooth(sph1_accel_z(time_ind),7); 31 elseif sphnum == 2 32 time = imu_sph_2.gyro{2}.Time; 33 time_ind = find(time≥37.25&time≤50.7); 34 sdata(:,2) = time(time_ind); 35 time_x = imu_sph_2.gyro{1}.Time; 36 sph2_gyro_x = interp1(time_x,imu_sph_2.gyro{1}.Data,time); 37 sdata(:,3) = smooth(sph2_gyro_x(time_ind),7); 38 sph2_gyro_y = imu_sph_2.gyro{2}.Data; 39 sdata(:,4) = smooth(sph2_gyro_y(time_ind),7); 40 time_z = imu_sph_2.gyro{3}.Time; 41 sph2_gyro_z = interp1(time_z,imu_sph_2.gyro{3}.Data,time); 42 sdata(:,5) = smooth(sph2_gyro_z(time_ind),7); 43 time_x_a = imu_sph_2.accel{1}.Time; 44 sph2_accel_x = interp1(time_x_a,imu_sph_2.accel{1}.Data,time); 45 sdata(:,6) = smooth(sph2_accel_x(time_ind),7); 46 time_y_a = imu_sph_2.accel{2}.Time; 47 sph2_accel_y = interp1(time_y_a,imu_sph_2.accel{2}.Data,time); 48 sdata(:,7) = smooth(sph2_accel_y(time_ind),7);

150 49 time_z_a = imu_sph_2.accel{3}.Time; 50 sph2_accel_z = interp1(time_z_a,imu_sph_2.accel{3}.Data,time); 51 sdata(:,8) = smooth(sph2_accel_z(time_ind),7); 52 end 53 54 load('2018_01_17_13_18_53_P526_T18_Rcv'); 55 56 raw_data = data{1,sphnum}.DebugUnsignedVal;% thruster data 57 thr_data_on = []; 58 thr_data_off = []; 59 pulses = struct(); 60 % Sort thruster data into on and off 61 for c = 1:length(raw_data) 62 if 40932 ̸= raw_data(1,c) 63 neg_thr = dec2bin(raw_data(14,c),6); 64 thr_data_on(13,end+1) = raw_data(1,c)/10; 65 thr_data_off(13,end+1) = raw_data(1,c)/10; 66 for thr = 1:6 67 if strcmp(neg_thr(end+1-thr),'0') 68 thr_data_on(thr,end) = ... (raw_data(2*thr,c))/1000+raw_data(1,c)/10; 69 thr_data_off(thr,end) = ... (raw_data(2*thr+1,c))/1000+raw_data(1,c)/10; 70 thr_data_on(thr+6,end) = raw_data(1,c)/10; 71 thr_data_off(thr+6,end) = raw_data(1,c)/10; 72 else 73 thr_data_on(thr,end) = raw_data(1,c)/10; 74 thr_data_off(thr,end) = raw_data(1,c)/10; 75 thr_data_on(thr+6,end) = ... (raw_data(2*thr,c))/1000+raw_data(1,c)/10; 76 thr_data_off(thr+6,end) = ... (raw_data(2*thr+1,c))/1000+raw_data(1,c)/10; 77 end 78 end 79 end 80 end 81 82

83 84 for t = 75:2:97%Hard-coded for longest duration of thrust pulses ... in T18 of TS97 85 x = [-inf*ones(1,3) ones(1,3)*inf]; 86 thrusters = zeros(12,1); 87 base_data = []; 88 for thr = 1:12 89 if thr_data_on(thr,t)̸=thr_data_off(thr,t) 90 thrusters(thr) = 1; 91 % Modify this according to typical pulse length 92 x(1) = max(x(1),thr_data_on(thr,t) + 0);%Pre-pulse start 93 x(2) = max(x(2),thr_data_on(thr,t) + 0.2);%Pre-pulse end 94 x(3) = max(x(3),thr_data_on(thr,t) + 0.2);%During ... pulse start 95 x(4) = min(x(4),thr_data_off(thr,t) + 0.1);%During ... pulse end

151 96 x(5) = min(x(5),thr_data_off(thr,t)+ 0.1); ... %Post-pulse start 97 x(6) = min(x(6),thr_data_off(thr,t) + 0.3); ... %Post-pulse end 98 end 99 end 100 101 if sum(x̸=[-inf*ones(1,3) ones(1,3)*inf])==6 102 pulse_time = (sdata(:,2)≥x(1))&(sdata(:,2)≤x(6)); 103 pulse_data = sdata(pulse_time,:); 104 if ¬isempty(pulse_data) 105 pre_pulse_ind = ... find(pulse_data(:,2)≥x(1)&pulse_data(:,2)≤x(2)); 106 during_pulse_ind = ... find(pulse_data(:,2)≥x(3)&pulse_data(:,2)≤x(4)); 107 post_pulse_ind = ... find(pulse_data(:,2)≥x(5)&pulse_data(:,2)≤x(6)); 108 if ¬isempty(pre_pulse_ind) && ¬... isempty(during_pulse_ind) && ¬isempty(post_pulse_ind) 109 110 base_data(:,1) = pulse_data(:,1); 111 base_data(:,2) = pulse_data(:,2); 112 113 % Find line to describe base data 114 %Gyro data 115 for i = 3:5 116 p = polyfit(pulse_data(pre_pulse_ind,2),... 117 pulse_data(pre_pulse_ind,i),1); 118 base_data(:,i) = p(1)*pulse_data(:,2) + p(2); 119 end 120 %Accel data 121 for i = 6:8 122 p = polyfit([pulse_data(pre_pulse_ind,2);... 123 pulse_data(post_pulse_ind,2)],... 124 [pulse_data(pre_pulse_ind,i);... 125 pulse_data(post_pulse_ind,i)],1); 126 base_data(:,i) = p(1)*pulse_data(:,2) + p(2); 127 end 128 129 if user_input%only plot clean accel data 130 old_pulse_data_omega = pulse_data(:,3:5); 131 132 figure 133 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 134 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 135 during_pulse_ind;post_pulse_ind],6),... 136 'Color',[0 0.5 0]) 137 hold on 138 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 139 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 140 during_pulse_ind;post_pulse_ind],7),... 141 'Color',[0.5 0 0]) 142 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 143 post_pulse_ind],2),pulse_data([pre_pulse_ind;...

152 144 during_pulse_ind;post_pulse_ind],8),... 145 'Color',[0 0 0.5]) 146 title('Cleaned Accelerometer Data') 147 xlabel('Time(s)') 148 ylabel('Measured Acceleration(m/s^2)') 149 legend({'a_x','a_y','a_z'},... 150 'Location','EastOutside') 151 [p1,z] = ginput(1); 152 fake_time = [p1 p1+.16]; 153 fake_z = [z z]; 154 plot(fake_time,fake_z,'-*k'); 155 [p2,y] = ginput(1); 156 else 157 figure 158 subplot(2,2,1) 159 plot(pulse_data(:,2),pulse_data(:,3),... 160 'Color',[0 1 0]) 161 hold on 162 plot(base_data(:,2),base_data(:,3),... 163 'Color',[0 0.5 0]) 164 plot(pulse_data(:,2),pulse_data(:,4),... 165 'Color',[1 0 0]) 166 plot(base_data(:,2),base_data(:,4),... 167 'Color',[0.5 0 0]) 168 plot(pulse_data(:,2),pulse_data(:,5),... 169 'Color',[0 0 1]) 170 plot(base_data(:,2),base_data(:,5),... 171 'Color',[0 0 0.5]) 172 title('Raw Gyro Data and Baseline Estimate') 173 xlabel('Time(s)') 174 ylabel('Measured Angular Velocity(rad/s)') 175 legend({'\omega_x','\omega_x base','\omega_y',... 176 '\omega_y base','\omega_z','\omega_z ... base'},... 177 'Location','EastOutside') 178 179 subplot(2,2,2) 180 plot(pulse_data(:,2),pulse_data(:,6),... 181 'Color',[0 1 0]) 182 hold on 183 plot(base_data(:,2),base_data(:,6),... 184 'Color',[0 0.5 0]) 185 plot(pulse_data(:,2),pulse_data(:,7),... 186 'Color',[1 0 0]) 187 plot(base_data(:,2),base_data(:,7),... 188 'Color',[0.5 0 0]) 189 plot(pulse_data(:,2),pulse_data(:,8),... 190 'Color',[0 0 1]) 191 plot(base_data(:,2),base_data(:,8),... 192 'Color',[0 0 0.5]) 193 title('Raw Accelerometer Data and Baseline ... Estimate') 194 xlabel('Time(s)') 195 ylabel('Measured Acceleration(m/s^2)')

153 196 legend({'a_x','a_x base','a_y','a_y base',... 197 'a_z','a_z base'},'Location','EastOutside') 198 199 %extract the raw angular rate data(assuming ... no bias) 200 raw_omega = pulse_data(during_pulse_ind,3:5); 201 202 203 pulse_data(:,3:8) = pulse_data(:,3:8) - ... base_data(:,3:8); 204 205 subplot(2,2,3) 206 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 207 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 208 during_pulse_ind;post_pulse_ind],3),... 209 'Color',[0 0.5 0]) 210 hold on 211 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 212 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 213 during_pulse_ind;post_pulse_ind],4),... 214 'Color',[0.5 0 0]) 215 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 216 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 217 during_pulse_ind;post_pulse_ind],5),... 218 'Color',[0 0 0.5]) 219 title('Cleaned Gyro Data') 220 xlabel('Time(s)') 221 ylabel('Measured Angular Velocity(rad/s)') 222 legend({'\omega_x','\omega_y','\omega_z'},... 223 'Location','EastOutside') 224 subplot(2,2,4) 225 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 226 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 227 during_pulse_ind;post_pulse_ind],6),... 228 'Color',[0 0.5 0]) 229 hold on 230 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 231 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 232 during_pulse_ind;post_pulse_ind],7),... 233 'Color',[0.5 0 0]) 234 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 235 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 236 during_pulse_ind;post_pulse_ind],8),... 237 'Color',[0 0 0.5]) 238 title('Cleaned Accelerometer Data') 239 xlabel('Time(s)') 240 ylabel('Measured Acceleration(m/s^2)') 241 legend({'a_x','a_y','a_z'},... 242 'Location','EastOutside') 243 set(gcf,'Position',[100, 100, 1200, 700]) 244 %valid= questdlg('Was this pulse accurately ... extracted?'); 245 end 246 if user_input

154 247 during_pulse_ind_g = ... find(pulse_data(:,2)≥p1&pulse_data(:,2)≤p2); 248 pre_pulse_ind_g = ... find(pulse_data(:,2)≥x(1)&pulse_data(:,2)≤p1); 249 post_pulse_ind_g = ... find(pulse_data(:,2)≥p2&pulse_data(:,2)≤x(6)); 250 251 raw_omega_g = ... old_pulse_data_omega(during_pulse_ind_g,:); 252 end 253 254 if user_input 255 pulses(end+1).thruster = thrusters; 256 % accel= average of accel data"during pulse ... period" 257 pulses(end).accel = ... mean(pulse_data(during_pulse_ind_g,6:8)); 258 % alpha=(final gyro data- initial gyro ... data)/(tf- 259 % ti) for"during pulse period" 260 pulses(end).alpha = ... (pulse_data(during_pulse_ind_g(end),3:5)... 261 -pulse_data(during_pulse_ind_g(1),3:5))/... 262 (pulse_data(during_pulse_ind_g(end),2)-... 263 pulse_data(during_pulse_ind_g(1),2)); 264 %delta_omega= avg of gryo data before pulse ... - avg of 265 %gyro data after pulse 266 pulses(end).delta_omega = ... mean(pulse_data(post_pulse_ind_g,3:5))-... 267 mean(pulse_data(pre_pulse_ind_g,3:5)); 268 pulses(end).omega = mean(raw_omega_g); 269 else 270 pulses(end+1).thruster = thrusters; 271 pulses(end).accel = ... mean(pulse_data(during_pulse_ind,6:8)); 272 pulses(end).alpha = ... (pulse_data(during_pulse_ind(end),3:5)... 273 -pulse_data(during_pulse_ind(1),3:5))/... 274 (pulse_data(during_pulse_ind(end),2)-... 275 pulse_data(during_pulse_ind(1),2)); 276 pulses(end).delta_omega = ... mean(pulse_data(post_pulse_ind,3:5))-... 277 mean(pulse_data(pre_pulse_ind,3:5)); 278 pulses(end).omega = mean(raw_omega); 279 end 280 end 281 end 282 end 283 end 284 285 pulses(1) = []; 286 if sphnum == 1 287 filename ='T18';

155 288 else 289 filename ='T18_sph2'; 290 end 291 292 save(['pulses_' filename],'pulses','filename')

Listing B.2: process_pulses_sph.m

1 function results = process_pulses_sph() 2 % Run this after running pulse_extraction.m 3 % After this, run plot_pulses.m 4 5 [filename, folder] = uigetfile('*.mat','Pick pulse data file'); 6 load([folder filename]) 7 8 %% Computations 9 % SPHERES properties 10 mass = 4.43;%[kg] 11 % accelerometer locations 12 rgc_xaccel = [0.0519, 0.0217, 0.0327]'; 13 rgc_yaccel = [-0.0266, 0.0335, 0.0330]'; 14 rgc_zaccel = [0.0328, -0.0437, 0.0335]'; 15 16 % Thruster locations 17 Rgc =[-0.0516 , 0.0 , 0.0965; 18 -0.0516 , 0.0 , -0.0965; 19 0.0965 , -0.0516 , 0.0; 20 -0.0965 , -0.0516 , 0.0; 21 0.0 , 0.0965 , -0.0516; 22 0.0 , -0.0965 , -0.0516; 23 0.0516 , 0.0 , 0.0965; 24 0.0516 , 0.0 , -0.0965; 25 0.0965 , 0.0516 , 0.0; 26 -0.0965 , 0.0516 , 0.0; 27 0.0 , 0.0965 , 0.0516; 28 0.0 , -0.0965 , 0.0516]; 29 % Force directions 30 Force =[1,0,0; 31 1,0,0; 32 0,1,0; 33 0,1,0; 34 0,0,1; 35 0,0,1; 36 -1,0,0; 37 -1,0,0; 38 0,-1,0; 39 0,-1,0; 40 0,0,-1; 41 0,0,-1]; 42 R_thr = Rgc; 43 Torque = cross(R_thr,Force);% torque directions 44 Minv = [Force';Torque'];%Scale by the estimated thrust available 45

156 46 a_meas = zeros(length(pulses),3); 47 alpha_meas = zeros(length(pulses),3); 48 omega_meas = zeros(length(pulses),3); 49 A_thrust_x = zeros(length(pulses),4); 50 A_thrust_y = zeros(length(pulses),4); 51 A_thrust_z = zeros(length(pulses),4); 52 Ax = zeros(length(pulses),4); 53 Ay = zeros(length(pulses),4); 54 Az = zeros(length(pulses),4); 55 bx = zeros(length(pulses),1); 56 by = zeros(length(pulses),1); 57 bz = zeros(length(pulses),1); 58 for p = 1:length(pulses) 59 a_meas(p,:) = pulses(p).accel; 60 if sum(pulses(p).thruster)>0 61 % This extracts which force direction the specific pulse ... was in. 62 A_thrust = 0.94^(sum(pulses(p).thruster)-1)*... 63 (pulses(p).thruster*ones(1,3))'.*Minv(1:3,:); 64 else 65 A_thrust = zeros(3,12); 66 end 67 alpha_meas(p,:) = pulses(p).alpha; ... %pulses(p).delta_omega/0.36;% 68 omega_meas(p,:) = pulses(p).delta_omega/2; 69 alpha_cross = skewSym(pulses(p).alpha); ... %skewSym(pulses(p).delta_omega/0.36);% 70 omega_cross = skewSym(pulses(p).delta_omega/2); 71 A_cross = alpha_cross + omega_cross*omega_cross; 72 prod_x = A_cross(1,:)*rgc_xaccel; 73 prod_y = A_cross(2,:)*rgc_yaccel; 74 prod_z = A_cross(3,:)*rgc_zaccel; 75 76 A_thrust_x(p,:) = A_thrust(1,[1,2,7,8]); 77 A_thrust_y(p,:) = A_thrust(2,[3,4,9,10]); 78 A_thrust_z(p,:) = A_thrust(3,[5,6,11,12]); 79 80 Ax(p,:) = A_thrust_x(p,:); 81 Ay(p,:) = A_thrust_y(p,:); 82 Az(p,:) = A_thrust_z(p,:); 83 bx(p,1) = a_meas(p,1) - prod_x; 84 by(p,1) = a_meas(p,2) - prod_y; 85 bz(p,1) = a_meas(p,3) - prod_z; 86 end 87 88 %% Find the solution 89 %For thex-axis accelerometer 90 sol_xaccel = Ax\bx; 91 thrust_xaccel = sol_xaccel*mass; 92 93 %For they-axis accelerometer 94 sol_yaccel = Ay\by; 95 thrust_yaccel = sol_yaccel*mass; 96

157 97 %For thez-axis accelerometer 98 sol_zaccel = Az\bz; 99 thrust_zaccel = sol_zaccel*mass; 100 101 %% Compute the thruster force from individual axes estimation 102 thrust = [thrust_xaccel(1:2); thrust_yaccel(1:2);... 103 thrust_zaccel(1:2); thrust_xaccel(3:4);... 104 thrust_yaccel(3:4); thrust_zaccel(3:4)]; 105 106 %% Create results structure 107 results.Ax = Ax; 108 results.Ay = Ay; 109 results.Az = Az; 110 results.bx = bx; 111 results.by = by; 112 results.bz = bz; 113 results.a_meas = a_meas; 114 results.alpha_meas = alpha_meas; 115 results.omega_meas = omega_meas; 116 results.thrust = thrust; 117 118 %% Save results 119 save(['results_' filename],'results')

Listing B.3: plot_pulses.m

1 function plot_pulses() 2 % Run this after running process_pulses_sph.m 3 % If you want to modifya few pulses, run revise_pulses.m 4 load('results_T18.mat') 5 results_sph1 = results; 6 load('results_T18_sph2.mat') 7 results_sph2 = results; 8 9 %Plot thrust 10 thrust_sph1 = (results_sph1.thrust); 11 thrust_sph2 = (results_sph2.thrust); 12 num = 0:1:11; 13 14 figure 15 plot(num,thrust_sph1,'*b'); hold on; 16 plot(num,thrust_sph2,'or'); 17 yL = ylim; 18 xL = xlim; 19 line([0 0], yL,'Color','black');%x-axis 20 line(xL,[0 0],'Color','k'); 21 xlabel('Thruster Number'); 22 ylabel('Thrust[N]'); 23 title('Thruster Force') 24 legend('Blue','Orange','Location','Southeast'); 25 xticks([0,1,2,3,4,5,6,7,8,9,10,11]); grid on; 26 27 end

158 Listing B.4: revise_pulses.m

1 function revise_pulses(sphnum) 2 % Allows user input to re-do the pulse extraction for selected ... pulses. 3 4 user_input = 1; 5 6 if sphnum == 1 7 load('saved_imu_1.mat'); 8 load('pulses_T18.mat'); 9 time = imu_sph_1.gyro{2}.Time; 10 time_ind = find(time≥37.25&time≤50.7); 11 sdata(:,2) = time(time_ind); 12 time_x = imu_sph_1.gyro{1}.Time; 13 sph1_gyro_x = interp1(time_x,imu_sph_1.gyro{1}.Data,time); 14 sdata(:,3) = smooth(sph1_gyro_x(time_ind),7); 15 sph1_gyro_y = imu_sph_1.gyro{2}.Data; 16 sdata(:,4) = smooth(sph1_gyro_y(time_ind),7); 17 time_z = imu_sph_1.gyro{3}.Time; 18 sph1_gyro_z = interp1(time_z,imu_sph_1.gyro{3}.Data,time); 19 sdata(:,5) = smooth(sph1_gyro_z(time_ind),7); 20 time_x_a = imu_sph_1.accel{1}.Time; 21 sph1_accel_x = interp1(time_x_a,imu_sph_1.accel{1}.Data,time); 22 sdata(:,6) = smooth(sph1_accel_x(time_ind),7); 23 time_y_a = imu_sph_1.accel{2}.Time; 24 sph1_accel_y = interp1(time_y_a,imu_sph_1.accel{2}.Data,time); 25 sdata(:,7) = smooth(sph1_accel_y(time_ind),7); 26 time_z_a = imu_sph_1.accel{3}.Time; 27 sph1_accel_z = interp1(time_z_a,imu_sph_1.accel{3}.Data,time); 28 sdata(:,8) = smooth(sph1_accel_z(time_ind),7); 29 else 30 load('saved_imu_2.mat'); 31 load('pulses_T18_sph2.mat'); 32 time = imu_sph_2.gyro{2}.Time; 33 time_ind = find(time≥37.25&time≤50.7); 34 sdata(:,2) = time(time_ind); 35 time_x = imu_sph_2.gyro{1}.Time; 36 sph2_gyro_x = interp1(time_x,imu_sph_2.gyro{1}.Data,time); 37 sdata(:,3) = smooth(sph2_gyro_x(time_ind),7); 38 sph2_gyro_y = imu_sph_2.gyro{2}.Data; 39 sdata(:,4) = smooth(sph2_gyro_y(time_ind),7); 40 time_z = imu_sph_2.gyro{3}.Time; 41 sph2_gyro_z = interp1(time_z,imu_sph_2.gyro{3}.Data,time); 42 sdata(:,5) = smooth(sph2_gyro_z(time_ind),7); 43 time_x_a = imu_sph_2.accel{1}.Time; 44 sph2_accel_x = interp1(time_x_a,imu_sph_2.accel{1}.Data,time); 45 sdata(:,6) = smooth(sph2_accel_x(time_ind),7); 46 time_y_a = imu_sph_2.accel{2}.Time; 47 sph2_accel_y = interp1(time_y_a,imu_sph_2.accel{2}.Data,time); 48 sdata(:,7) = smooth(sph2_accel_y(time_ind),7);

159 49 time_z_a = imu_sph_2.accel{3}.Time; 50 sph2_accel_z = interp1(time_z_a,imu_sph_2.accel{3}.Data,time); 51 sdata(:,8) = smooth(sph2_accel_z(time_ind),7); 52 end 53 54 load('2018_01_17_13_18_53_P526_T18_Rcv'); 55 56 raw_data = data{1,sphnum}.DebugUnsignedVal;% This is thruster data! 57 thr_data_on = []; 58 thr_data_off = []; 59 counter = 1; 60 61 % Sort thruster data into on and off 62 for c = 1:length(raw_data) 63 if 40932 ̸= raw_data(1,c) 64 neg_thr = dec2bin(raw_data(14,c),6); 65 thr_data_on(13,end+1) = raw_data(1,c)/10; 66 thr_data_off(13,end+1) = raw_data(1,c)/10; 67 for thr = 1:6 68 if strcmp(neg_thr(end+1-thr),'0') 69 thr_data_on(thr,end) = ... (raw_data(2*thr,c))/1000+raw_data(1,c)/10; 70 thr_data_off(thr,end) = ... (raw_data(2*thr+1,c))/1000+raw_data(1,c)/10; 71 thr_data_on(thr+6,end) = raw_data(1,c)/10; 72 thr_data_off(thr+6,end) = raw_data(1,c)/10; 73 else 74 thr_data_on(thr,end) = raw_data(1,c)/10; 75 thr_data_off(thr,end) = raw_data(1,c)/10; 76 thr_data_on(thr+6,end) = ... (raw_data(2*thr,c))/1000+raw_data(1,c)/10; 77 thr_data_off(thr+6,end) = ... (raw_data(2*thr+1,c))/1000+raw_data(1,c)/10; 78 end 79 end 80 end 81 end 82 83 % Ask user which thrusters they want to revise 84 prompt ='Select thrusters to revise (1-12 scale) ina vector:'; 85 thr_to_revise = input(prompt); 86 87 for t = 75:2:97 88 x = [-inf*ones(1,3) ones(1,3)*inf]; 89 thrusters = zeros(12,1); 90 base_data = []; 91 for thr = thr_to_revise 92 if thr_data_on(thr,t)̸=thr_data_off(thr,t) 93 thrusters(thr) = 1; 94 x(1) = max(x(1),thr_data_on(thr,t) + 0);%Pre-pulse start 95 x(2) = max(x(2),thr_data_on(thr,t) + 0.2);%Pre-pulse end 96 x(3) = max(x(3),thr_data_on(thr,t) + 0.2);%During ... pulse start 97 x(4) = min(x(4),thr_data_off(thr,t) + 0.1);%During ...

160 pulse end 98 x(5) = min(x(5),thr_data_off(thr,t)+ 0.1); ... %Post-pulse start 99 x(6) = min(x(6),thr_data_off(thr,t) + 0.3); ... %Post-pulse end 100 end 101 end 102 103 if sum(x̸=[-inf*ones(1,3) ones(1,3)*inf])==6 104 pulse_time = (sdata(:,2)≥x(1))&(sdata(:,2)≤x(6)); 105 pulse_data = sdata(pulse_time,:); 106 if ¬isempty(pulse_data) 107 pre_pulse_ind = ... find(pulse_data(:,2)≥x(1)&pulse_data(:,2)≤x(2)); 108 during_pulse_ind = ... find(pulse_data(:,2)≥x(3)&pulse_data(:,2)≤x(4)); 109 post_pulse_ind = ... find(pulse_data(:,2)≥x(5)&pulse_data(:,2)≤x(6)); 110 if ¬isempty(pre_pulse_ind) && ¬... isempty(during_pulse_ind) && ¬isempty(post_pulse_ind) 111 112 base_data(:,1) = pulse_data(:,1); 113 base_data(:,2) = pulse_data(:,2); 114 115 % Find line to describe base data 116 %Gyro data 117 for i = 3:5 118 p = polyfit(pulse_data(pre_pulse_ind,2),... 119 pulse_data(pre_pulse_ind,i),1); 120 base_data(:,i) = p(1)*pulse_data(:,2) + p(2); 121 end 122 %Accel data 123 for i = 6:8 124 p = polyfit([pulse_data(pre_pulse_ind,2);... 125 pulse_data(post_pulse_ind,2)],... 126 [pulse_data(pre_pulse_ind,i);... 127 pulse_data(post_pulse_ind,i)],1); 128 base_data(:,i) = p(1)*pulse_data(:,2) + p(2); 129 end 130 131 if user_input%only plot clean accel data 132 old_pulse_data_omega = pulse_data(:,3:5); 133 %pulse_data(:,3:8)= pulse_data(:,3:8)- ... base_data(:,3:8); 134 figure 135 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 136 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 137 during_pulse_ind;post_pulse_ind],6),... 138 'Color',[0 0.5 0]) 139 hold on 140 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 141 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 142 during_pulse_ind;post_pulse_ind],7),... 143 'Color',[0.5 0 0])

161 144 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 145 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 146 during_pulse_ind;post_pulse_ind],8),... 147 'Color',[0 0 0.5]) 148 title('Cleaned Accelerometer Data') 149 xlabel('Time(s)') 150 ylabel('Measured Acceleration(m/s^2)') 151 legend({'a_x','a_y','a_z'},'Location','EastOutside') 152 [p1,z] = ginput(1); 153 fake_time = [p1 p1+.16]; 154 fake_z = [z z]; 155 plot(fake_time,fake_z,'-*k'); 156 [p2,y] = ginput(1); 157 else 158 figure 159 subplot(2,2,1) 160 plot(pulse_data(:,2),pulse_data(:,3),'Color',[0 ... 1 0]) 161 hold on 162 plot(base_data(:,2),base_data(:,3),'Color',[0 ... 0.5 0]) 163 plot(pulse_data(:,2),pulse_data(:,4),'Color',[1 ... 0 0]) 164 plot(base_data(:,2),base_data(:,4),'Color',[0.5 ... 0 0]) 165 plot(pulse_data(:,2),pulse_data(:,5),'Color',[0 ... 0 1]) 166 plot(base_data(:,2),base_data(:,5),'Color',[0 ... 0 0.5]) 167 title('Raw Gyro Data and Baseline Estimate') 168 xlabel('Time(s)') 169 ylabel('Measured Angular Velocity(rad/s)') 170 legend({'\omega_x','\omega_x base','\omega_y',... 171 '\omega_y base','\omega_z','\omega_z ... base'},... 172 'Location','EastOutside') 173 174 subplot(2,2,2) 175 plot(pulse_data(:,2),pulse_data(:,6),'Color',[0 ... 1 0]) 176 hold on 177 plot(base_data(:,2),base_data(:,6),'Color',[0 ... 0.5 0]) 178 plot(pulse_data(:,2),pulse_data(:,7),'Color',[1 ... 0 0]) 179 plot(base_data(:,2),base_data(:,7),'Color',[0.5 ... 0 0]) 180 plot(pulse_data(:,2),pulse_data(:,8),'Color',[0 ... 0 1]) 181 plot(base_data(:,2),base_data(:,8),'Color',[0 ... 0 0.5]) 182 title('Raw Accelerometer Data and Baseline ... Estimate') 183 xlabel('Time(s)')

162 184 ylabel('Measured Acceleration(m/s^2)') 185 legend({'a_x','a_x base','a_y','a_y base',... 186 'a_z','a_z base'},'Location','EastOutside') 187 188 %extract the raw angular rate data(assuming ... no bias) 189 raw_omega = pulse_data(during_pulse_ind,3:5); 190 191 pulse_data(:,3:8) = pulse_data(:,3:8) - ... base_data(:,3:8); 192 193 subplot(2,2,3) 194 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 195 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 196 during_pulse_ind;post_pulse_ind],3),... 197 'Color',[0 0.5 0]) 198 hold on 199 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 200 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 201 during_pulse_ind;post_pulse_ind],4),... 202 'Color',[0.5 0 0]) 203 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 204 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 205 during_pulse_ind;post_pulse_ind],5),... 206 'Color',[0 0 0.5]) 207 title('Cleaned Gyro Data') 208 xlabel('Time(s)') 209 ylabel('Measured Angular Velocity(rad/s)') 210 legend({'\omega_x','\omega_y','\omega_z'},... 211 'Location','EastOutside') 212 subplot(2,2,4) 213 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 214 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 215 during_pulse_ind;post_pulse_ind],6),... 216 'Color',[0 0.5 0]) 217 hold on 218 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 219 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 220 during_pulse_ind;post_pulse_ind],7),... 221 'Color',[0.5 0 0]) 222 plot(pulse_data([pre_pulse_ind;during_pulse_ind;... 223 post_pulse_ind],2),pulse_data([pre_pulse_ind;... 224 during_pulse_ind;post_pulse_ind],8),... 225 'Color',[0 0 0.5]) 226 title('Cleaned Accelerometer Data') 227 xlabel('Time(s)') 228 ylabel('Measured Acceleration(m/s^2)') 229 legend({'a_x','a_y','a_z'},... 230 'Location','EastOutside') 231 set(gcf,'Position',[100, 100, 1200, 700]) 232 %valid= questdlg('Was this pulse accurately ... extracted?'); 233 end 234 if user_input

163 235 during_pulse_ind_g = ... find(pulse_data(:,2)≥p1&pulse_data(:,2)≤p2); 236 pre_pulse_ind_g = ... find(pulse_data(:,2)≥x(1)&pulse_data(:,2)≤p1); 237 post_pulse_ind_g = ... find(pulse_data(:,2)≥p2&pulse_data(:,2)≤x(6)); 238 239 raw_omega_g = ... old_pulse_data_omega(during_pulse_ind_g,:); 240 end 241 242 if user_input%strcmp(valid,'Yes') 243 pulses(thr_to_revise(counter)).thruster = ... thrusters; 244 pulses(thr_to_revise(counter)).accel = ... mean(pulse_data(during_pulse_ind_g,6:8)); 245 pulses(thr_to_revise(counter)).alpha = ... (pulse_data(during_pulse_ind_g(end),3:5)... 246 -pulse_data(during_pulse_ind_g(1),3:5))/... 247 (pulse_data(during_pulse_ind_g(end),2)-... 248 pulse_data(during_pulse_ind_g(1),2)); 249 pulses(thr_to_revise(counter)).delta_omega = ... 250 mean(pulse_data(post_pulse_ind_g,3:5))- ... 251 mean(pulse_data(pre_pulse_ind_g,3:5)); 252 pulses(thr_to_revise(counter)).omega = ... mean(raw_omega_g); 253 counter = counter+1; 254 else 255 pulses(thr_to_revise(counter)).thruster = ... thrusters; 256 pulses(thr_to_revise(counter)).accel = ... mean(pulse_data(during_pulse_ind,6:8)); 257 pulses(thr_to_revise(counter)).alpha = ... (pulse_data(during_pulse_ind(end),3:5)... 258 -pulse_data(during_pulse_ind(1),3:5))/... 259 (pulse_data(during_pulse_ind(end),2)-... 260 pulse_data(during_pulse_ind(1),2)); 261 pulses(thr_to_revise(counter)).delta_omega = ... 262 mean(pulse_data(post_pulse_ind,3:5))-... 263 mean(pulse_data(pre_pulse_ind,3:5)); 264 pulses(thr_to_revise(counter)).omega = ... mean(raw_omega); 265 counter = counter+1; 266 end 267 end 268 end 269 end 270 end 271 272 % Re-save pulses file 273 if sphnum == 1 274 filename ='T18'; 275 else 276 filename ='T18_sph2';

164 277 end 278 save(['pulses_' filename],'pulses','filename')

B.3 Adaptive PID SMC Controller

Listing B.5: ctrl_pid_smc.c

1 /* 2 Copyright(c) 2013, Massachusetts Institute of Technology Space ... Systems Laboratory 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or ... without modification, are permitted provided that the ... following conditions are met: 6 Redistributions of source code must retain the above copyright ... notice, this list of conditions and the following disclaimer. 7 Redistributions in binary form must reproduce the above copyright ... notice, this list of conditions and the following disclaimer ... in the documentation and/or other materials provided with the ... distribution. 8 Neither the name of the Massachusetts Institute of Technology, ... the MIT Space Systems Laboratory, nor the names of its ... contributors may be used to endorse or promote products ... derived from this software without specific prior written ... permission. 9 10 THIS SOFTWAREIS PROVIDEDBY THE COPYRIGHT HOLDERS AND ... CONTRIBUTORS"ASIS" AND ANY EXPRESSOR IMPLIED WARRANTIES, ... INCLUDING, BUT NOT LIMITEDTO, THE IMPLIED WARRANTIESOF ... MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE ... DISCLAIMED.INNO EVENT SHALL THE COPYRIGHT HOLDEROR ... CONTRIBUTORSBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ... SPECIAL, EXEMPLARY,OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT ... NOT LIMITEDTO, PROCUREMENTOF SUBSTITUTE GOODSOR SERVICES; ... LOSSOF USE, DATA,OR PROFITS;OR BUSINESS INTERRUPTION) ... HOWEVER CAUSED ANDON ANY THEORYOF LIABILITY, WHETHERIN ... CONTRACT, STRICT LIABILITY,OR TORT(INCLUDING NEGLIGENCEOR ... OTHERWISE) ARISINGIN ANY WAY OUTOF THE USEOF THIS SOFTWARE, ... EVENIF ADVISEDOF THE POSSIBILITYOF SUCH DAMAGE. 11 */ 12 13 /* 14 * ctrl_pid_smc.c 15 * 16 * This file containsa library of standard"PID"-type position ... controllers. 17 * 18 * MIT Space Systems Laboratory 19 * SPHERES Guest Scientist Program v1.0

165 20 * http://ssl.mit.edu/spheres/ 21 * 22 * Copyright 2018 Massachusetts Institute of Technology 23 * 24 ********************************************************** 25 * Sliding Mode Controller- PID * 26 * By: Hailee Hettrick * 27 ********************************************************** 28 * Last modified: 10/14/2018 * 29 * * 30 ********************************************************** 31 */ 32 33 #include 34 #include"ctrl_pid_smc.h" 35 #include"spheres_constants.h" 36 #include"ctrl_position.h" 37 #include"spheres_physical_parameters.h" 38 #include"control.h" 39 40 #ifdef SPH_MATLAB_SIM 41 #include"mex.h" 42 #define DEBUG(arg) mexPrintf arg 43 #else 44 #define DEBUG(arg) 45 #endif 46 47 // Constants 48 float lambda = 0.085f; 49 float lambda_att = 0.1f; 50 float gamma1 = 60.0f; 51 float gamma2 = 80.0f; 52 float gamma3 = 4.0f; 53 float gamma4 = 2.0f; 54 float Kp = 1000.0f; 55 float Kp_att = 50.0f; 56 float P = 10.0f; 57 float P_att = 10.0f; 58 int i, j; 59 int n = 2; 60 61 // zero initialization 62 float u_hat[2] = {0.0f, 0.0f}; 63 float u_pid[2] = {0.0f, 0.0f}; 64 float xr_ddot[2] = {0.0f,0.0f}; 65 float Y[4] = {0.0f, 0.0f, 0.0f, 0.0f}; 66 float Y_att[3] = {0.0f, 0.0f, 0.0f}; 67 float theta_tilde[3] ={0.0f, 0.0f, 0.0f}; 68 float theta[3] ={0.0f, 0.0f, 0.0f}; 69 float u_hat_att[3] = {0.0f, 0.0f,0.0f}; 70 float u_pid_att[3] = {0.0f, 0.0f,0.0f}; 71 float u_pd_att[3] = {0.0f, 0.0f, 0.0f}; 72 73 // saturation

166 74 float p = 0.001f;// defines the boundary layer//this helps ... with chattering but the corresponding translation parameters ... don't work with it 75 float dist = 1.0f; 76 float k = 2.0f; 77 float delta[3] = {0.0f, 0.0f, 0.0f}; 78 79 void sat(float, float, float); 80 81 //x,y translation 82 void ctrl_PID_SMC_position(float s[], float s_dot[], float ... s_int[], float old_s[], float delta_t, float Ki_hat_dot[], ... float old_Ki_hat_dot[], float Kd_hat_dot[], float ... old_Kd_hat_dot[], float a_hat_dot[], float old_a_hat_dot[], ... float *ctrlStateError, float *prev_ctrlStateError, float ... *ctrlControl, float *ctrlState, float Ki_hat[], float ... Kd_hat[], float a_hat[]){//add more inputs 83 84 // compute s_int 85 for(i=0; i

167 118 a_hat_dot[i] = a_hat_dot[i] - P*Y[j]*s[0]; 119 // fory 120 a_hat_dot[i+2] = a_hat_dot[i+2] - P*Y[j+2]*s[1]; 121 } 122 } 123 124 // integrate 125 for(i=0; i

168 160 theta_tilde[0] = atan2( ... 2*(ctrlStateError[QUAT_4]*ctrlStateError[QUAT_1] + ... ctrlStateError[QUAT_2]*ctrlStateError[QUAT_3]), ... 1-2*(ctrlStateError[QUAT_1]*ctrlStateError[QUAT_1] + ... ctrlStateError[QUAT_2]*ctrlStateError[QUAT_2]) ); 161 theta_tilde[1] = asin( ... 2*(ctrlStateError[QUAT_4]*ctrlStateError[QUAT_2] - ... ctrlStateError[QUAT_3]*ctrlStateError[QUAT_1]) ); 162 theta_tilde[2] = atan2( ... 2*(ctrlStateError[QUAT_4]*ctrlStateError[QUAT_3] + ... ctrlStateError[QUAT_1]*ctrlStateError[QUAT_2]), ... 1-2*(ctrlStateError[QUAT_2]*ctrlStateError[QUAT_2] + ... ctrlStateError[QUAT_3]*ctrlStateError[QUAT_3]) ); 163 164 theta[0] = atan2( 2*(ctrlState[QUAT_4]*ctrlState[QUAT_1] + ... ctrlState[QUAT_2]*ctrlState[QUAT_3]), ... 1-2*(ctrlState[QUAT_1]*ctrlState[QUAT_1] + ... ctrlState[QUAT_2]*ctrlState[QUAT_2]) ); 165 theta[1] = asin( 2*(ctrlState[QUAT_4]*ctrlState[QUAT_2] - ... ctrlState[QUAT_3]*ctrlState[QUAT_1]) ); 166 theta[2] = atan2( 2*(ctrlState[QUAT_4]*ctrlState[QUAT_3] + ... ctrlState[QUAT_1]*ctrlState[QUAT_2]), ... 1-2*(ctrlState[QUAT_2]*ctrlState[QUAT_2] + ... ctrlState[QUAT_3]*ctrlState[QUAT_3]) ); 167 168 169 // compute s_int_att 170 for(i=0; i<3; i++){ 171 s_int_att[i] = s_int_att[i] + delta_t*(old_s_att[i] + ... s_att[i])/2; 172 } 173 174 // compute s_att 175 for(i=0; i<3; i++){ 176 s_att[i] = -(ctrlStateError[i+RATE_X] + ... lambda_att*theta_tilde[i]); 177 } 178 179 // compute s_dot_att 180 for(i=0; i<3; i++){ 181 s_dot_att[i] = -((ctrlStateError[i+RATE_X] - ... prev_ctrlStateError[i+RATE_X])/(delta_t) + ... lambda_att*ctrlStateError[i+RATE_X]); 182 } 183 184 // construct Y_att= theta_ddot_desired- lambda *theta_tilde 185 // theta_ddot_desired=0 186 for(i=0; i<3; i++){ 187 Y_att[i] = lambda_att*theta_tilde[i]; 188 } 189 190 // adaptation laws 191 for(i=0; i<3; i++){ 192 Ki_hat_dot_att[i] = gamma3*s_att[i]*s_int_att[i];

169 193 Kd_hat_dot_att[i] = gamma4*s_att[i]*s_dot_att[i]; 194 } 195 196 a_hat_dot_att[0] = -P_att * Y_att[0] * s_att[0]; 197 a_hat_dot_att[1] = -P_att * Y_att[1] * s_att[0]; 198 a_hat_dot_att[2] = -P_att * Y_att[2] * s_att[0]; 199 a_hat_dot_att[3] = -P_att * Y_att[0] * s_att[1]; 200 a_hat_dot_att[4] = -P_att * Y_att[1] * s_att[1]; 201 a_hat_dot_att[5] = -P_att * Y_att[2] * s_att[1]; 202 a_hat_dot_att[6] = -P_att * Y_att[0] * s_att[2]; 203 a_hat_dot_att[7] = -P_att * Y_att[1] * s_att[2]; 204 a_hat_dot_att[8] = -P_att * Y_att[2] * s_att[2]; 205 206 // integrate 207 for(i=0; i<3; i++){ 208 Ki_hat_att[i] = Ki_hat_att[i] + ... delta_t*(old_Ki_hat_dot_att[i] + Ki_hat_dot_att[i])/2; 209 Kd_hat_att[i] = Kd_hat_att[i] + ... delta_t*(old_Kd_hat_dot_att[i] + Kd_hat_dot_att[i])/2; 210 a_hat_att[i] += delta_t*(old_a_hat_dot_att[i] + ... a_hat_dot_att[i])/2; 211 } 212 213 // u_hat= Y_att *a_hat_att 214 u_hat_att[0] = Y_att[0]*a_hat_att[0] + Y_att[0]*a_hat_att[1] ... + Y_att[0]*a_hat_att[2]; 215 u_hat_att[1] = Y_att[1]*a_hat_att[3] + Y_att[1]*a_hat_att[4] ... + Y_att[1]*a_hat_att[5]; 216 u_hat_att[2] = Y_att[2]*a_hat_att[6] + Y_att[2]*a_hat_att[7] ... + Y_att[2]*a_hat_att[8]; 217 218 // construct u_pid 219 for(i=0; i<3; i++){ 220 u_pid_att[i] = Kp_att*(s_att[i])+ ... Kd_hat_att[i]*(s_dot_att[i])+ ... Ki_hat_att[i]*(s_int_att[i]); 221 } 222 223 // updateu= u_hat- u_pid 224 ctrlControl[TORQUE_X] = 0; 225 ctrlControl[TORQUE_Y] = 0; 226 ctrlControl[TORQUE_Z] = 0; 227 ctrlControl[TORQUE_X] = u_hat_att[0] - u_pid_att[0]; 228 ctrlControl[TORQUE_Y] = u_hat_att[1] - u_pid_att[1]; 229 ctrlControl[TORQUE_Z] = u_hat_att[2] - u_pid_att[2]; 230 } 231 232 void sat(float n, float lower, float upper) { 233 234 if(n > upper){ n = upper; } 235 if( n < lower) { n = lower; } 236 }

170 Appendix C

Docked Dynamics Functions

C.1 Contact Dynamics of Docking Event

Listing C.1: FindImpulsiveFT.m

1 % Inertial frame's origin is defined at the point where the ... satellites dock 2 % Body-fixed frame of each sat has positivex through docking port 3 4 syms m rho x y z vx vy vz theta3 theta3d theta3dd dt real 5 syms theta1d theta2d real 6 7 %%% Chaser setup 8 % Inputs 9 MassChaser_kg = m; 10 PosDPtoChaserCMInInertial_m = [x;y;z]; 11 AngVelChaserInCHA_rps = [theta1d; theta2d; theta3d]; 12 AngChaserCMInInertial = [0; 0; theta3 + pi]; 13 QuatInertialToCHA = EulerAnglesZYXToQuat(AngChaserCMInInertial); 14 QuatCHAToInertial = quatconj(QuatInertialToCHA); 15 VelChaserInCHA_mps = cross(AngVelChaserInCHA_rps, ... 16 QuatRotate(QuatInertialToCHA, PosDPtoChaserCMInInertial_m')'); 17 % Computations 18 % simplification fora sphere 19 MOIChaser_kgm2 = (2/5) * MassChaser_kg * rho^2 * eye(3); 20 AngMomChaserInCHA_kgm2ps = MOIChaser_kgm2 * AngVelChaserInCHA_rps; 21 22 %%% Target setup 23 % Inputs 24 MassTarget_kg = m; 25 PosDPtoTargetCMInInertial_m = [-x; -y; z]; 26 VelTargetInitInTAR_mps = [0; 0; 0]; 27 AngVelTargetInTAR_rps = AngVelChaserInCHA_rps; 28 AngTargetCMInInertial = [0; 0; theta3]; 29 QuatInertialToTAR = EulerAnglesZYXToQuat(AngTargetCMInInertial); 30 QuatTARToInertial = quatconj(QuatInertialToTAR); 31 % Computations

171 32 % simplification fora sphere 33 MOITarget_kgm2 = (2/5) * MassTarget_kg * rho^2 * eye(3); 34 PosTargetToChaserInInertial_m = PosDPtoChaserCMInInertial_m - ... PosDPtoTargetCMInInertial_m; 35 VelTargetToChaserInInertial_mps = QuatRotate(QuatCHAToInertial, ... VelChaserInCHA_mps')' ... 36 - QuatRotate(QuatTARToInertial,VelTargetInitInTAR_mps')'; 37 AngMomTargetInTAR_kgm2ps = MOITarget_kgm2 * AngVelTargetInTAR_rps; 38 39 % Aggregated system 40 PosDPtoCMCInInertial_m = (MassChaser_kg * ... PosDPtoChaserCMInInertial_m + ... 41 MassTarget_kg * PosDPtoTargetCMInInertial_m) / (MassChaser_kg ... + MassTarget_kg); 42 RSkewSymMatrixChaser_m = [0, -PosDPtoChaserCMInInertial_m(3), ... PosDPtoChaserCMInInertial_m(2); ... PosDPtoChaserCMInInertial_m(3), 0, ... -PosDPtoChaserCMInInertial_m(1); ... 43 -PosDPtoChaserCMInInertial_m(2), ... PosDPtoChaserCMInInertial_m(1), 0]; 44 RSkewSymMatrixTarget_m = [0, -PosDPtoTargetCMInInertial_m(3), ... PosDPtoTargetCMInInertial_m(2); ... PosDPtoTargetCMInInertial_m(3), 0, ... -PosDPtoTargetCMInInertial_m(1); ... 45 -PosDPtoTargetCMInInertial_m(2), ... PosDPtoTargetCMInInertial_m(1), 0]; 46 MOICMC_kgm2 = (MOIChaser_kgm2 - MassChaser_kg * ... RSkewSymMatrixChaser_m*RSkewSymMatrixChaser_m) + ... 47 (MOITarget_kgm2 - MassTarget_kg * ... RSkewSymMatrixTarget_m*RSkewSymMatrixTarget_m); 48 49 PosCMCtoTargetCMInInertial_m = -PosDPtoCMCInInertial_m + ... PosDPtoTargetCMInInertial_m; 50 51 % Constants 52 MassRatio = MassChaser_kg / MassTarget_kg; 53 54 % Relationships 55 VelocityCMCInInertial_mps = (MassChaser_kg * ... QuatRotate(QuatCHAToInertial, VelChaserInCHA_mps')' + ... 56 MassTarget_kg * QuatRotate(QuatTARToInertial, ... VelTargetInitInTAR_mps')') / ... 57 (MassChaser_kg + MassTarget_kg); 58 %VelTarget_mps= VelTargetInitial_mps- VelocityCMC_mps; 59 60 %%% After dock 61 AngVelCMCInInertial_rps = (MOICMC_kgm2) \ ... (QuatRotate(QuatTARToInertial, AngMomTargetInTAR_kgm2ps')' ... 62 + QuatRotate(QuatCHAToInertial, AngMomChaserInCHA_kgm2ps')' + ... 63 cross(MassChaser_kg * (1 + MassRatio)^(-1) * ... PosTargetToChaserInInertial_m, ... VelTargetToChaserInInertial_mps)); 64 VelPostDockTargetInInertial_mps = VelocityCMCInInertial_mps + ... 65 cross(AngVelCMCInInertial_rps, PosCMCtoTargetCMInInertial_m);

172 66 67 % want to minimize this impulsive force if Target is fragile 68 ForceImpulsiveInInertial_N = simplify(MassTarget_kg * ... (VelPostDockTargetInInertial_mps - ... 69 QuatRotate(QuatTARToInertial, VelTargetInitInTAR_mps')') / dt); 70 TorqueImpulsiveInInertial_Nm =simplify( MOITarget_kgm2 * ... (AngVelCMCInInertial_rps - ... 71 QuatRotate(QuatTARToInertial, AngVelTargetInTAR_rps')') / dt ... - ... 72 cross(PosDPtoTargetCMInInertial_m, ... ForceImpulsiveInInertial_N) );

Listing C.2: SolveImpulsiveForcesAndTorques.m

1 function [ForceImpulsiveInInertial_N,... 2 TorqueImpulsiveInInertial_Nm] = ... SolveImpulsiveForcesAndTorques(Chaser, Target, dt) 3 4 %%% Chaser setup 5 PosDPtoChaserCMInInertial_m = [Chaser.x2_0; Chaser.y2_0; ... Chaser.z2_0]; 6 AngVelChaserInCHA_rps = [Target.roll1d_0; Target.pitch1d_0; ... Target.yaw1d_0]; 7 QuatInertialToCHA = EulerAnglesZYXToQuat(Chaser.EulerAngles_rad); 8 QuatCHAToInertial = quatconj(QuatInertialToCHA); 9 VelChaserInCHA_mps = cross(AngVelChaserInCHA_rps, ... 10 QuatRotate(QuatInertialToCHA, PosDPtoChaserCMInInertial_m')'); 11 AngMomChaserInCHA_kgm2ps = Chaser.MOI_kgm2 * AngVelChaserInCHA_rps; 12 13 %%% Target setup 14 PosDPtoTargetCMInInertial_m = [Target.x1_0; Target.y1_0; ... Target.z1_0]; 15 VelTargetInitInTAR_mps = [Target.x1d_0; Target.y1d_0; Target.z1d_0]; 16 AngVelTargetInTAR_rps = [Target.roll1d_0; Target.pitch1d_0; ... Target.yaw1d_0]; 17 QuatInertialToTAR = EulerAnglesZYXToQuat(Target.EulerAngles_rad); 18 QuatTARToInertial = quatconj(QuatInertialToTAR); 19 % Computations 20 PosTargetToChaserInInertial_m = PosDPtoChaserCMInInertial_m - ... PosDPtoTargetCMInInertial_m; 21 VelTargetToChaserInInertial_mps = QuatRotate(QuatCHAToInertial, ... VelChaserInCHA_mps')' ... 22 - QuatRotate(QuatTARToInertial,VelTargetInitInTAR_mps')'; 23 AngMomTargetInTAR_kgm2ps = Target.MOI_kgm2 * AngVelTargetInTAR_rps; 24 25 % Aggregated system 26 PosDPtoCMCInInertial_m = (Chaser.mass_kg * ... PosDPtoChaserCMInInertial_m + ... 27 Target.mass_kg * PosDPtoTargetCMInInertial_m) / ... (Chaser.mass_kg + Target.mass_kg); 28 RSkewSymMatrixChaser_m = [0, -PosDPtoChaserCMInInertial_m(3), ... PosDPtoChaserCMInInertial_m(2); ... PosDPtoChaserCMInInertial_m(3), 0, ...

173 -PosDPtoChaserCMInInertial_m(1); ... 29 -PosDPtoChaserCMInInertial_m(2), ... PosDPtoChaserCMInInertial_m(1), 0]; 30 RSkewSymMatrixTarget_m = [0, -PosDPtoTargetCMInInertial_m(3), ... PosDPtoTargetCMInInertial_m(2); ... PosDPtoTargetCMInInertial_m(3), 0, ... -PosDPtoTargetCMInInertial_m(1); ... 31 -PosDPtoTargetCMInInertial_m(2), ... PosDPtoTargetCMInInertial_m(1), 0]; 32 MOICMC_kgm2 = (Chaser.MOI_kgm2 - Chaser.mass_kg * ... RSkewSymMatrixChaser_m*RSkewSymMatrixChaser_m) + ... 33 (Target.MOI_kgm2 - Target.mass_kg * ... RSkewSymMatrixTarget_m*RSkewSymMatrixTarget_m); 34 35 PosCMCtoTargetCMInInertial_m = -PosDPtoCMCInInertial_m + ... PosDPtoTargetCMInInertial_m; 36 37 % Constants 38 MassRatio = Chaser.mass_kg / Target.mass_kg; 39 40 % Relationships 41 VelocityCMCInInertial_mps = (Chaser.mass_kg * ... QuatRotate(QuatCHAToInertial, VelChaserInCHA_mps')' + ... 42 Target.mass_kg * QuatRotate(QuatTARToInertial, ... VelTargetInitInTAR_mps')') / ... 43 (Chaser.mass_kg + Target.mass_kg); 44 45 %%% Post dock 46 AngVelCMCInInertial_rps = (MOICMC_kgm2) \ ... (QuatRotate(QuatTARToInertial, AngMomTargetInTAR_kgm2ps')' ... 47 + QuatRotate(QuatCHAToInertial, AngMomChaserInCHA_kgm2ps')' + ... 48 cross(Chaser.mass_kg * (1 + MassRatio)^(-1) * ... PosTargetToChaserInInertial_m, ... VelTargetToChaserInInertial_mps)); 49 VelPostDockTargetInInertial_mps = VelocityCMCInInertial_mps + ... 50 cross(AngVelCMCInInertial_rps, PosCMCtoTargetCMInInertial_m); 51 52 % Impulsive Force and Torque 53 ForceImpulsiveInInertial_N = (Target.mass_kg * ... (VelPostDockTargetInInertial_mps - ... 54 QuatRotate(QuatTARToInertial, VelTargetInitInTAR_mps')') / dt); 55 TorqueImpulsiveInInertial_Nm = ( Target.MOI_kgm2 * ... (AngVelCMCInInertial_rps - ... 56 QuatRotate(QuatTARToInertial, AngVelTargetInTAR_rps')') / dt ... - ... 57 cross(PosDPtoTargetCMInInertial_m, ... ForceImpulsiveInInertial_N) );

C.2 Setting up Target and Chaser

174 Listing C.3: SetupTargetParams.m

1 function Target = SetupTargetParams(mass, CM2DPDistance, ... CMToEdgeY_m, CMToEdgeZ_m, TargetShapeType, AngVelVec_rad) 2 3 % Coordinates 4 i = [1 0 0]; 5 j = [0 1 0]; 6 k = [0 0 1]; 7 8 % Target mass 9 Target.mass_kg = mass; 10 % Distance from Target'sCM to the docking port interface 11 Target.CM2DPinX_m = CM2DPDistance; 12 13 % Distances fromCM to edges 14 Target.CMToEdgeZ_m = CMToEdgeZ_m; 15 Target.CMToEdgeY_m = CMToEdgeY_m; 16 Target.CMToEdgeX_m = Target.CM2DPinX_m; 17 18 % Set up inertia matrix based on shape type 19 if strcmp(TargetShapeType,'cylinder') 20 Target.MOI_kgm2 = [1/2*Target.mass_kg*Target.CMToEdgeY_m^2, ... 0, 0;... 21 0, 1/12*Target.mass_kg*(3*Target.CMToEdgeY_m^2 + ... Target.CMToEdgeX_m^2), 0;... 22 0, 0, 1/12*Target.mass_kg*(3*Target.CMToEdgeY_m^2 + ... Target.CMToEdgeX_m^2)]; 23 elseif strcmp(TargetShapeType,'sphere') 24 Target.MOI_kgm2 = ... (2/5)*Target.mass_kg*Target.CMToEdgeX_m^2*eye(3); 25 elseif strcmp(TargetShapeType,'rect prism') 26 Target.MOI_kgm2 = (1/12)*Target.mass_kg*... 27 [((2*Target.CMToEdgeY_m)^2+(2*Target.CMToEdgeZ_m)^2), 0, ... 0;... 28 0, ((2*Target.CMToEdgeZ_m)^2+(2*Target.CMToEdgeX_m)^2), 0;... 29 0, 0, ((2*Target.CMToEdgeY_m)^2+(2*Target.CMToEdgeX_m)^2)]; 30 end 31 32 % Simplified notation for following calcultions 33 Ixx = Target.MOI_kgm2(1,1); Iyy = Target.MOI_kgm2(2,2); Izz = ... Target.MOI_kgm2(3,3); 34 35 % Initial Conditions 36 % Initial angles should always be equal to0 since the assumption ... is that 37 % the global frame= the body frame at the start of this phase; ... so they are 38 % not included as an option for ICs 39 Target.roll1d_0 = AngVelVec_rad(1);%wx 40 Target.pitch1d_0 = AngVelVec_rad(2);%wy 41 Target.yaw1d_0 = AngVelVec_rad(3);%wz 42 43 % Initial angular accelerations

175 44 Target.roll1dd_0 = (Iyy-Izz)*Target.pitch1d_0*Target.yaw1d_0/Ixx; 45 Target.pitch1dd_0 = (Izz-Ixx)*Target.roll1d_0*Target.yaw1d_0/Iyy; 46 Target.yaw1dd_0 = (Ixx-Iyy)*Target.pitch1d_0*Target.roll1d_0/Izz; 47 48 % Angular velocity construction in Target 49 Target.BodyToInertialRot = FindRotMat(0, 0, 0); 50 omega_123 = [Target.roll1d_0; Target.pitch1d_0; Target.yaw1d_0]; 51 Target.omega_xyz = Target.BodyToInertialRot*omega_123; 52 53 % Notation in inertial frame for determining ICs 54 %r1_xyz= [(-Target.CM2DPinX_m);0;0]; 55 r1_xyz = [0;0;0]; 56 v1_xyz = cross(Target.omega_xyz, r1_xyz); 57 58 Target.x1_0 = dot(r1_xyz,i); 59 Target.x1d_0 = dot(v1_xyz,i);% Change to0 for no translation 60 Target.y1_0 = dot(r1_xyz,j); 61 Target.y1d_0 = dot(v1_xyz,j);% Change to0 for no translation 62 Target.z1_0 = dot(r1_xyz,k); 63 Target.z1d_0 = dot(v1_xyz,k);% Change to0 for no translation 64 65 Target.shape = TargetShapeType; 66 67 end

Listing C.4: SetupChaserParams.m

1 function Chaser = SetupChaserParams(mass, CM2DPDistance, ... CMToEdgeY_m, CMToEdgeZ_m, ChaserShapeType, Target) 2 3 % Coordinate frame 4 i = [1 0 0]; 5 j = [0 1 0]; 6 k = [0 0 1]; 7 8 % Chaser mass 9 Chaser.mass_kg = mass; 10 % Distance from Chaser'sCM to docking port interface 11 Chaser.CM2DPinX_m = CM2DPDistance; 12 13 % Distances fromCM to edges 14 Chaser.CMToEdgeZ_m = CMToEdgeZ_m; 15 Chaser.CMToEdgeY_m = CMToEdgeY_m; 16 Chaser.CMToEdgeX_m = Chaser.CM2DPinX_m; 17 18 % Set up inertia matrix 19 if strcmp(ChaserShapeType,'cylinder') 20 Chaser.MOI_kgm2 = [1/2*Chaser.mass_kg*Chaser.CMToEdgeY_m^2, ... 0, 0;... 21 0, 1/12*Chaser.mass_kg*(3*Chaser.CMToEdgeY_m^2 + ... Chaser.CMToEdgeX_m^2), 0;... 22 0, 0, 1/12*Chaser.mass_kg*(3*Chaser.CMToEdgeY_m^2 + ... Chaser.CMToEdgeX_m^2)];

176 23 elseif strcmp(ChaserShapeType,'sphere') 24 Chaser.MOI_kgm2 = ... (2/5)*Chaser.mass_kg*Chaser.CMToEdgeX_m^2*eye(3); 25 elseif strcmp(ChaserShapeType,'rect prism') 26 Chaser.MOI_kgm2 = (1/12)*Chaser.mass_kg*... 27 [((2*Chaser.CMToEdgeY_m)^2+(2*Chaser.CMToEdgeZ_m)^2), 0, ... 0;... 28 0, ((2*Chaser.CMToEdgeZ_m)^2+(2*Chaser.CMToEdgeX_m)^2), 0;... 29 0, 0, ((2*Chaser.CMToEdgeY_m)^2+(2*Chaser.CMToEdgeX_m)^2)]; 30 end 31 32 % Set up initial conditions 33 R = (Target.CM2DPinX_m+Chaser.CM2DPinX_m); 34 r2_xyz = (Target.BodyToInertialRot*[R;0;0]); 35 v2_xyz = cross(Target.omega_xyz, r2_xyz); 36 37 Chaser.x2_0 = dot(r2_xyz,i) + Target.x1_0; 38 Chaser.x2d_0 = dot(v2_xyz,i) + Target.x1d_0; 39 Chaser.y2_0 = dot(r2_xyz,j) + Target.y1_0; 40 Chaser.y2d_0 = dot(v2_xyz,j)+ Target.y1d_0; 41 Chaser.z2_0 = dot(r2_xyz,k) + Target.z1_0; 42 Chaser.z2d_0 = dot(v2_xyz,k) + Target.z1d_0; 43 Chaser.shape = ChaserShapeType; 44 45 end

C.3 Discrete Solver

Listing C.5: AggregatedDynamicsDiscreteSolver.m

1 function [out,tspan] = ... AggregatedDynamicsDiscreteSolver(Target,Chaser,tspan,term_type) 2 3 n = length(tspan); 4 % initial conditions+ setup 5 qw = zeros(2,1); qw(1) = 1; 6 qx = zeros(2,1); qy = zeros(2,1); qz= zeros(2,1); 7 qwdot = zeros(2,1); qxdot = zeros(2,1); 8 qydot = zeros(2,1); qzdot = zeros(2,1); 9 yaw1 = zeros(2,1); yaw1d = zeros(2,1); 10 yaw1d(1) = Target.yaw1d_0; yaw1dd = zeros(2,1); yaw1dd(1) = ... Target.yaw1dd_0; 11 pitch1 = zeros(2,1); pitch1d = zeros(2,1); 12 pitch1d(1) = Target.pitch1d_0; pitch1dd = zeros(2,1); pitch1dd(1) ... = Target.pitch1dd_0; 13 roll1 = zeros(2,1); roll1d = zeros(2,1); 14 roll1d(1) = Target.roll1d_0; roll1dd = zeros(2,1); roll1dd(1) = ... Target.roll1dd_0; 15 x1 = zeros(2,1); x1(1) = Target.x1_0; x1d = zeros(2,1); 16 x1d(1) = Target.x1d_0; x1dd = zeros(2,1); x1dd(1) = 0;

177 17 y1 = zeros(2,1); y1(1) = Target.y1_0; y1d = zeros(2,1); 18 y1d(1) = Target.y1d_0; y1dd = zeros(2,1); y1dd(1) = 0; 19 z1 = zeros(2,1); z1(1) = Target.z1_0; z1d = zeros(2,1); 20 z1d(1) = Target.z1d_0; z1dd = zeros(2,1); z1dd(1) = 0; 21 x2 = zeros(2,1); x2(1) = Chaser.x2_0; x2d = zeros(2,1); 22 x2d(1) = Chaser.x2d_0; x2dd = zeros(2,1); x2dd(1) = 0; 23 y2 = zeros(2,1); y2(1) = Chaser.y2_0; y2d = zeros(2,1); 24 y2d(1) = Chaser.y2d_0; y2dd = zeros(2,1); y2dd(1) = 0; 25 z2 = zeros(2,1); z2(1) = Chaser.z2_0; z2d = zeros(2,1); 26 z2d(1) = Chaser.z2d_0; z2dd = zeros(2,1); z2dd(1) = 0; 27 BodyToInertialRot = zeros(3,3,n); BodyToInertialRot(:,:,1) = ... FindRotMat(0, 0, 0); 28 CurrentB2IRot = BodyToInertialRot; 29 CentAccInBody_mpsps = zeros(3,2); 30 AngAccInBody_mpsps = zeros(3,2); 31 Mx = zeros(2,1); Fz = zeros(2,1); Fth = zeros(2,1); 32 if isfield(Chaser,'roll1dd_user') 33 roll1dd_user = Chaser.roll1dd_user; 34 pitch1dd_user = Chaser.pitch1dd_user; 35 yaw1dd_user = Chaser.yaw1dd_user; 36 end 37 38 t_wait = 1; 39 i = 1; 40 tol = 0.001; 41 h = tspan(2)-tspan(1);%assumes linspace 42 R = (Target.CM2DPinX_m + Chaser.CM2DPinX_m); 43 Ixx = Target.MOI_kgm2(1,1); Iyy = Target.MOI_kgm2(2,2); Izz = ... Target.MOI_kgm2(3,3); 44 rollstopped = 0; 45 RInBody = R*[1;0;0]; 46 47 while(abs(yaw1d(i)) ≥ tol || abs(pitch1d(i)) ≥ tol || ... abs(roll1d(i)) ≥ tol) 48 49 % Determine double dot terms 50 ifi ̸=1 51 roll1dd(i) = (Iyy-Izz)*pitch1d(i)*yaw1d(i)/Ixx; 52 pitch1dd(i) = (Izz-Ixx)*roll1d(i)*yaw1d(i)/Iyy; 53 yaw1dd(i) = (Ixx-Iyy)*pitch1d(i)*roll1d(i)/Izz; 54 end 55 xdd_trans = 0; ydd_trans = 0; zdd_trans = 0; 56 if tspan(i) ≥ t_wait% start the process of stopping the Target 57 %If nutating, we want to stop roll1d first before ... stopping yaw1d, 58 %pitch1d 59 if strcmp(term_type,'user_defined') 60 roll1dd(i) = roll1dd_user(i) + roll1dd(i); 61 pitch1dd(i) = pitch1dd_user(i) + pitch1dd(i); 62 yaw1dd(i) = yaw1dd_user(i) + yaw1dd(i); 63 else 64 if (Ixx == Iyy) && (Iyy == Izz) 65 % Target isa sphere; no nutation 66 if strcmp(term_type,'NegQuadratic')

178 67 yaw1dd_slowdown = ... NegativeQuadraticTerm(Target,... 68 Target.yaw1d_0, t_wait, tspan(i)); 69 roll1dd_slowdown = ... NegativeQuadraticTerm(Target,... 70 Target.roll1d_0, t_wait, tspan(i)); 71 pitch1dd_slowdown = ... NegativeQuadraticTerm(Target,... 72 Target.pitch1d_0, t_wait, tspan(i)); 73 elseif strcmp(term_type,'PosLinear') 74 yaw1dd_slowdown = PositiveLinearTerm(Target,... 75 Target.yaw1d_0, t_wait, tspan(i)); 76 roll1dd_slowdown = PositiveLinearTerm(Target,... 77 Target.roll1d_0, t_wait, tspan(i)); 78 pitch1dd_slowdown = PositiveLinearTerm(Target,... 79 Target.pitch1d_0, t_wait, tspan(i)); 80 elseif strcmp(term_type,'NegLinear') 81 yaw1dd_slowdown = NegativeLinearTerm(Target,... 82 Target.yaw1d_0, t_wait, tspan(i)); 83 roll1dd_slowdown = NegativeLinearTerm(Target,... 84 Target.roll1d_0, t_wait, tspan(i)); 85 pitch1dd_slowdown = NegativeLinearTerm(Target,... 86 Target.pitch1d_0, t_wait, tspan(i)); 87 elseif strcmp(term_type,'Constant') 88 yaw1dd_slowdown = ConstantAccTerm(Target,... 89 Target.yaw1d_0); 90 roll1dd_slowdown = ConstantAccTerm(Target,... 91 Target.roll1d_0); 92 pitch1dd_slowdown = ConstantAccTerm(Target,... 93 Target.pitch1d_0); 94 end 95 roll1dd(i) = roll1dd_slowdown + roll1dd(i); 96 pitch1dd(i) = pitch1dd_slowdown + pitch1dd(i); 97 yaw1dd(i) = yaw1dd_slowdown + yaw1dd(i); 98 else 99 %Target may be nutating 100 if abs(roll1d(i)) > tol/10 101 if strcmp(term_type,'NegQuadratic') 102 roll1dd_slowdown = ... NegativeQuadraticTerm(Target,... 103 Target.roll1d_0, t_wait, tspan(i)); 104 elseif strcmp(term_type,'PosLinear') 105 roll1dd_slowdown = ... PositiveLinearTerm(Target,... 106 Target.roll1d_0, t_wait, tspan(i)); 107 elseif strcmp(term_type,'NegLinear') 108 roll1dd_slowdown = ... NegativeLinearTerm(Target,... 109 Target.roll1d_0, t_wait, tspan(i)); 110 elseif strcmp(term_type,'Constant') 111 roll1dd_slowdown = ConstantAccTerm(Target,... 112 Target.roll1d_0); 113 end 114 roll1dd(i) = roll1dd_slowdown + roll1dd(i);

179 115 end 116 if abs(roll1d(i)) ≤ tol/10 117 % slow down ang vel in other axes now 118 if rollstopped == 0 119 % save off these ang vels 120 Target.yaw1d_0 = yaw1d(i); 121 Target.pitch1d_0 = pitch1d(i); 122 end 123 if abs(pitch1d(i)) > tol 124 if strcmp(term_type,'NegQuadratic') 125 pitch1dd_slowdown = ... NegativeQuadraticTerm(Target,... 126 Target.pitch1d_0, t_wait, tspan(i)); 127 elseif strcmp(term_type,'PosLinear') 128 pitch1dd_slowdown = ... PositiveLinearTerm(Target,... 129 Target.pitch1d_0, t_wait, tspan(i)); 130 elseif strcmp(term_type,'NegLinear') 131 pitch1dd_slowdown = ... NegativeLinearTerm(Target,... 132 Target.pitch1d_0, t_wait, tspan(i)); 133 elseif strcmp(term_type,'Constant') 134 pitch1dd_slowdown = ... ConstantAccTerm(Target,... 135 Target.pitch1d_0); 136 end 137 pitch1dd(i) = pitch1dd_slowdown + ... pitch1dd(i); 138 end 139 if abs(yaw1d(i)) > tol 140 if strcmp(term_type,'NegQuadratic') 141 yaw1dd_slowdown = ... NegativeQuadraticTerm(Target,... 142 Target.yaw1d_0, t_wait, tspan(i)); 143 elseif strcmp(term_type,'PosLinear') 144 yaw1dd_slowdown = ... PositiveLinearTerm(Target,... 145 Target.yaw1d_0, t_wait, tspan(i)); 146 elseif strcmp(term_type,'NegLinear') 147 yaw1dd_slowdown = ... NegativeLinearTerm(Target,... 148 Target.yaw1d_0, t_wait, tspan(i)); 149 elseif strcmp(term_type,'Constant') 150 yaw1dd_slowdown = ... ConstantAccTerm(Target,... 151 Target.yaw1d_0); 152 end 153 yaw1dd(i) = yaw1dd_slowdown + yaw1dd(i); 154 end 155 rollstopped = 1; 156 end 157 end 158 end 159

180 160 % Always occur post t_wait 161 if abs(y1d(i)) > tol 162 ydd_trans = ConstantAccTerm(Target, Target.y1d_0); 163 end 164 if abs(x1d(i)) > tol 165 xdd_trans = ConstantAccTerm(Target, Target.x1d_0); 166 end 167 if abs(z1d(i)) > tol 168 zdd_trans = ConstantAccTerm(Target, Target.z1d_0); 169 end 170 end 171 172 % Quaternion to DCM 173 ifi ̸=1 174 BodyToInertialRot(:,:,i) = quat2dcm([qw(i), qx(i), qy(i), ... qz(i)]); 175 BodyToInertialRot(:,:,i) = BodyToInertialRot(:,:,i)'; 176 CurrentB2IRot(:,:,i) = BodyToInertialRot(:,:,i); 177 end 178 omega_123 = [roll1d(i); pitch1d(i); yaw1d(i)]; 179 alpha_123 = [roll1dd(i); pitch1dd(i); yaw1dd(i)]; 180 181 % Necessary for maintaining synchronous motion 182 CentAccInBody_mpsps(:,i) = cross(omega_123, cross(omega_123, ... RInBody)); 183 AngAccInBody_mpsps(:,i) = cross(alpha_123, RInBody); 184 185 CentAccInInertial_mpsps = ... CurrentB2IRot(:,:,i)*CentAccInBody_mpsps(:,i); 186 AngAccInInertial_mpsps = ... CurrentB2IRot(:,:,i)*AngAccInBody_mpsps(:,i); 187 TotalAccInInertial_mpsps = CentAccInInertial_mpsps + ... AngAccInInertial_mpsps; 188 189 x2dd(i) = TotalAccInInertial_mpsps(1) + xdd_trans; 190 y2dd(i) = TotalAccInInertial_mpsps(2) + ydd_trans; 191 z2dd(i) = TotalAccInInertial_mpsps(3) + zdd_trans; 192 193 x1dd(i) = xdd_trans; 194 y1dd(i) = ydd_trans; 195 z1dd(i) = zdd_trans; 196 197 qwdot(i) = -1/2 * (roll1d(i).*qx(i) + pitch1d(i).*qy(i) + ... yaw1d(i).*qz(i)); 198 qxdot(i) = 1/2 * (roll1d(i).*qw(i) + pitch1d(i).*qz(i) - ... yaw1d(i).*qy(i)); 199 qydot(i) = 1/2 * (pitch1d(i).*qw(i) + yaw1d(i).*qx(i) - ... roll1d(i).*qz(i)); 200 qzdot(i) = 1/2 * (yaw1d(i).*qw(i) + roll1d(i).*qy(i) - ... pitch1d(i).*qx(i)); 201 202 % results from TARGET AMB(wrt aggregated system) 203 Hdot = Target.MOICombowrtTargetCM_kgm2*alpha_123 + ... 204 cross(omega_123, Target.MOICombowrtTargetCM_kgm2*omega_123);

181 205 Mx(i) = Hdot(1); 206 Fz(i) = -Hdot(2)/R; 207 Fth(i) = Hdot(3)/R; 208 209 % Update timer 210 i = i+1; 211 if i>n 212 break; 213 end 214 215 % update velocity terms 216 x1d(i) = x1d(i-1) + x1dd(i-1)*h; y1d(i) = y1d(i-1) + y1dd(i-1)*h; 217 z1d(i) = z1d(i-1) + z1dd(i-1)*h; 218 nextstep = CurrentB2IRot(:,:,i-1)*cross(omega_123, RInBody); 219 x2d(i) = x1d(i) + nextstep(1); y2d(i) = y1d(i) + nextstep(2); 220 z2d(i) = z1d(i) + nextstep(3); 221 222 % Update position terms 223 x1(i) = x1(i-1) + x1d(i)*h; y1(i) = y1(i-1) + y1d(i)*h; 224 z1(i) = z1(i-1) + z1d(i)*h; 225 nextstep = CurrentB2IRot(:,:,i-1)*RInBody; 226 x2(i) = x1(i) + nextstep(1); y2(i) = y1(i) + nextstep(2); 227 z2(i) = z1(i) + nextstep(3); 228 229 % update angular velocity 230 yaw1d(i) = yaw1d(i-1) + yaw1dd(i-1)*h; 231 pitch1d(i) = pitch1d(i-1) + pitch1dd(i-1)*h; 232 roll1d(i) = roll1d(i-1) + roll1dd(i-1)*h; 233 234 %update angles, delta angle 235 yaw1(i) = yaw1(i-1) + yaw1d(i)*h; 236 pitch1(i) = pitch1(i-1) + pitch1d(i)*h; 237 roll1(i) = roll1(i-1) + roll1d(i)*h; 238 239 %update quaternion 240 qw(i) = qw(i-1) + qwdot(i-1)*h; qx(i) = qx(i-1) + qxdot(i-1)*h; 241 qy(i) = qy(i-1) + qydot(i-1)*h; qz(i) = qz(i-1) + qzdot(i-1)*h; 242 243 end 244 ifi ≤n 245 tspan = tspan(1:i); 246 end 247 248 % Pack output 249 out.roll1 = roll1; out.pitch1 = pitch1; out.yaw1 = yaw1; 250 out.roll1d = roll1d; out.pitch1d = pitch1d; out.yaw1d = ... yaw1d; 251 out.roll1dd = roll1dd; out.pitch1dd = pitch1dd; out.yaw1dd = ... yaw1dd; 252 out.x1 = x1; out.y1 = y1; out.z1 = z1; 253 out.x2 = x2; out.y2 = y2; out.z2 = z2; 254 out.x1d = x1d; out.y1d = y1d; out.z1d = z1d; 255 out.x2d = x2d; out.y2d = y2d; out.z2d = z2d; 256 out.x1dd = x1dd; out.y1dd = y1dd; out.z1dd = z1dd;

182 257 out.x2dd = x2dd; out.y2dd = y2dd; out.z2dd = z2dd; 258 out.CurrentB2IRot = CurrentB2IRot; 259 out.qw = qw; out.qx = qx; out.qy = qy; out.qz= qz; 260 261 %% Calculate loads/moments 262 TotalForceInBody_N = Chaser.mass_kg*(CentAccInBody_mpsps + ... 263 AngAccInBody_mpsps); 264 out.ShearLoadY_N = TotalForceInBody_N(2,:) - Fth'; 265 out.ShearLoadZ_N = TotalForceInBody_N(3,:) - Fz'; 266 267 out.Torsion_Nm = Chaser.MOI_kgm2(1,1)*roll1dd - ... 268 (Chaser.MOI_kgm2(2,2)-Chaser.MOI_kgm2(3,3)).*... 269 pitch1d(1:length(roll1dd)).*yaw1d(1:length(roll1dd)) - Mx; 270 out.BendingMomY_Nm = Chaser.MOI_kgm2(2,2)*pitch1dd - ... 271 (Chaser.MOI_kgm2(3,3)-Chaser.MOI_kgm2(1,1)).*... 272 roll1d(1:length(pitch1dd)).*yaw1d(1:length(pitch1dd)); 273 out.BendingMomZ_Nm = Chaser.MOI_kgm2(3,3)*yaw1dd - ... 274 (Chaser.MOI_kgm2(1,1)-Chaser.MOI_kgm2(2,2)).*... 275 pitch1d(1:length(yaw1dd)).*roll1d(1:length(yaw1dd)); 276 277 p = length(out.ShearLoadY_N); 278 out.int.ShearLoadY_N = cumtrapz(tspan(1:p), abs(out.ShearLoadY_N)); 279 out.int.ShearLoadZ_N = cumtrapz(tspan(1:p), abs(out.ShearLoadZ_N)); 280 out.int.Torsion_Nm = cumtrapz(tspan(1:p), abs(out.Torsion_Nm)); 281 out.int.BendingMomY_Nm = cumtrapz(tspan(1:p), ... abs(out.BendingMomY_Nm)); 282 out.int.BendingMomZ_Nm = cumtrapz(tspan(1:p), ... abs(out.BendingMomZ_Nm)); 283 out.int.TotalLM = out.int.ShearLoadY_N(end) + ... out.int.ShearLoadZ_N(end) + ... 284 out.int.Torsion_Nm(end) + out.int.BendingMomY_Nm(end)... 285 + out.int.BendingMomZ_Nm(end); 286 287 %% Calculate deltaV 288 n = length(yaw1dd); 289 t = tspan(1:n); 290 291 out.DeltaVRoll_mps = cumtrapz(t, roll1dd); 292 out.DeltaVPitch_mps = cumtrapz(t, pitch1dd); 293 out.DeltaVYaw_mps = cumtrapz(t, yaw1dd); 294 out.TotalDeltaV_mps = out.DeltaVRoll_mps(end) + ... 295 out.DeltaVPitch_mps(end) + out.DeltaVYaw_mps(end); 296 297 end 298 299 function current_acc = ConstantAccTerm(p,init_vel) 300 current_acc = (0 - init_vel) / p.deltaT; 301 end 302 303 function current_acc = ... NegativeLinearTerm(p,init_vel,t_wait,current_time) 304 a = init_vel/(p.deltaT)^2; 305 current_acc = -2*a*(current_time-t_wait); 306 end

183 307 308 function current_acc = ... PositiveLinearTerm(p,init_vel,t_wait,current_time) 309 a = init_vel/(p.deltaT)^2; 310 current_acc = 2*a*(current_time-(p.deltaT+t_wait)); 311 end 312 313 function current_acc = ... NegativeQuadraticTerm(p,init_vel,t_wait,current_time) 314 a = init_vel/(p.deltaT)^3; 315 current_acc = -3*a*(current_time-t_wait)^2; 316 end

C.4 Direct Optimization Using GPOPS

Listing C.6: detumble_gpops.m

1 %---Detumbling Target---% 2 clear all; close all; clc 3 4 %--- Provide Auxiliary Data for Problem ---% 5 6 TargetShapeType ='cylinder';%options:'sphere','rect prism', ... 'cylinder' 7 ChaserShapeType = TargetShapeType; 8 9 %Target= SetupTargetParams(mass, CM2DPDistance, CMToEdgeY_m, ... CMToEdgeZ_m, TargetShapeType, AngVelVec_rad) 10 Target = SetupTargetParams(5, 0.10, 0.35, 0.35, TargetShapeType, ... deg2rad([1 2 3])); 11 % Forcing Target to have no translation 12 Target.x1d_0 = 0; 13 Target.y1d_0 = 0; 14 Target.z1d_0 = 0; 15 Chaser = SetupChaserParams(5, 0.10, 0.35, 0.35, ChaserShapeType, ... Target); 16 17 disp_vec = [-Target.CM2DPinX_m; 0; 0];%from CMC to new point 18 Target.MOICombowrtTargetCM_kgm2 = Target.MOI_kgm2 + ... Chaser.MOI_kgm2 + ... 19 (Target.mass_kg+Chaser.mass_kg)*(dot(disp_vec,disp_vec)*eye(3) ... - disp_vec*disp_vec'); 20 21 auxdata.I_C = Chaser.MOI_kgm2; 22 auxdata.mass_C = Chaser.mass_kg; 23 auxdata.I_T = Target.MOI_kgm2; 24 auxdata.mass_T = Target.mass_kg; 25 auxdata.I_CMCwrtTAR = Target.MOICombowrtTargetCM_kgm2; 26 auxdata.R = (Target.CM2DPinX_m + Chaser.CM2DPinX_m); 27 RInBody = auxdata.R*[1;0;0];

184 28 29 30 %--- Provide All Bounds for Problem ---% 31 t0min = 0; t0max = 0; 32 tfmin = 0; tfmax = 250; 33 % Orientation 34 quat0 = [1 0 0 0]; 35 quatfmin = [-1 -1 -1 -1]; quatfmax = [1 1 1 1]; 36 quatmin = quatfmin; quatmax = quatfmax; 37 % Angular velocity 38 omega0 = [Target.roll1d_0, Target.pitch1d_0, Target.yaw1d_0]; 39 omegaf=[0 0 0]; 40 omegamin = deg2rad([-5 -5 -5]); omegamax = deg2rad([5 5 5]); 41 r0 = [Chaser.x2_0, Chaser.y2_0, Chaser.z2_0]; 42 rfmin = [Target.x1_0, Target.y1_0, Target.z1_0] - auxdata.R; 43 rfmax = [Target.x1_0, Target.y1_0, Target.z1_0] + auxdata.R; 44 rdot0= [Chaser.x2d_0, Chaser.y2d_0, Chaser.z2d_0]; 45 rdotfmin = 0.1*[-1 -1 -1]; rdotfmax = 0.1*[1 1 1]; 46 rmin = rfmin; rmax = rfmax; 47 rdotmin = 0.5*[-1 -1 -1]; rdotmax = 0.5*[1 1 1]; 48 % control is angular acceleration 49 umin = -0.007*ones(1,3); umax = -umin; 50 51 %--- Setup for Problem Bounds ---% 52 bounds.phase.initialtime.lower = t0min; 53 bounds.phase.initialtime.upper = t0max; 54 bounds.phase.finaltime.lower = tfmin; 55 bounds.phase.finaltime.upper = tfmax; 56 bounds.phase.initialstate.lower = [quat0, omega0, r0, rdot0]; 57 bounds.phase.initialstate.upper = [quat0, omega0, r0, rdot0]; 58 bounds.phase.state.lower = [quatmin, omegamin, rmin, rdotmin]; 59 bounds.phase.state.upper = [quatmax, omegamax, rmax, rdotmax]; 60 bounds.phase.finalstate.lower = [quatfmin, omegaf, rfmin, rdotfmin]; 61 bounds.phase.finalstate.upper = [quatfmax, omegaf, rfmax, rdotfmax]; 62 bounds.phase.control.lower = [umin]; 63 bounds.phase.control.upper = [umax]; 64 bounds.phase.integral.lower = 0; 65 bounds.phase.integral.upper = [50]; 66 % Path constraint for Chaser to stay docked to Target 67 bounds.phase.path.lower= sqrt(Chaser.x2_0^2 + Chaser.y2_0^2 + ... Chaser.z2_0^2)-0.001/10; 68 bounds.phase.path.upper= sqrt(Chaser.x2_0^2 + Chaser.y2_0^2 + ... Chaser.z2_0^2)+0.001/10; 69 70 %--- Provide Guess of Solution ---% 71 tGuess = [t0min; 50]; 72 quatGuess = [quat0; quatfmax]; 73 omegaGuess = [omega0; omegaf]; 74 rGuess = [r0; rfmax]; 75 rdotGuess = [rdot0; rdotmax]; 76 uGuess = [umin; umin]; 77 guess.phase.state = [quatGuess, omegaGuess, rGuess, rdotGuess]; 78 guess.phase.control = [uGuess]; 79 guess.phase.time = [tGuess];

185 80 guess.phase.integral = 0.01; 81 82 %---Provide Mesh Refinement Method and Initial Mesh ---% 83 mesh.method ='hp-PattersonRao'; 84 % desired mesh error tolerance for optimal solution 85 mesh.tolerance = 1e-5; 86 mesh.maxiterations = 20; 87 mesh.colpointsmin = 4; 88 mesh.colpointsmax = 10; 89 mesh.phase.colpoints = 4; 90 91 %--- Assemble Information into Problem Structure ---% 92 setup.mesh= mesh; 93 setup.name ='Detumble'; 94 setup.functions.endpoint = @detumbleEndpoint; 95 setup.functions.continuous = @detumbleContinuous; 96 setup.displaylevel = 2; 97 setup.auxdata = auxdata; 98 setup.bounds = bounds; 99 setup.guess = guess; 100 setup.nlp.solver ='ipopt'; 101 setup.derivatives.supplier ='sparseCD'; 102 setup.derivatives.derivativelevel ='second'; 103 setup.method ='RPM-Differentiation'; 104 setup.scales.method ='automatic-bounds'; 105 setup.nlp.ipoptoptions.maxiterations = 2000; 106 setup.nlp.ipoptoptions.tolerance = 10e-7; 107 108 %--- Solve Problem Using GPOPS2 ---% 109 output = gpops2(setup);

Listing C.7: detumbleContinuous.m

1 function phaseout = detumbleContinuous(input) 2 % Update dynamics and objective function 3 4 %% Dynamics- make actual equations of motion 5 % states order:[quat, omegadot, rmin, rdot]; 6 qw = input.phase.state(:,1); 7 qx = input.phase.state(:,2); 8 qy = input.phase.state(:,3); 9 qz= input.phase.state(:,4); 10 rolldot = input.phase.state(:,5); 11 pitchdot = input.phase.state(:,6); 12 yawdot = input.phase.state(:,7); 13 x = input.phase.state(:,8); 14 y = input.phase.state(:,9); 15 z = input.phase.state(:,10); 16 xdot = input.phase.state(:,11); 17 ydot = input.phase.state(:,12); 18 zdot = input.phase.state(:,13); 19 u1 = input.phase.control(:,1);%rollddot 20 u2 = input.phase.control(:,2);%pitchddot

186 21 u3 = input.phase.control(:,3);%yawddot 22 23 % dynamics 24 qwdot = -1/2 * (rolldot.*qx + pitchdot.*qy + yawdot.*qz); 25 qxdot = 1/2 * (rolldot.*qw + pitchdot.*qz - yawdot.*qy); 26 qydot = 1/2 * (pitchdot.*qw + yawdot.*qx - rolldot.*qz); 27 qzdot = 1/2 * (yawdot.*qw + rolldot.*qy - pitchdot.*qx); 28 quatdot = [qwdot, qxdot, qydot, qzdot]; 29 30 rollddot = u1; 31 pitchddot = u2; 32 yawddot = u3; 33 angacc = [rollddot, pitchddot, yawddot]; 34 35 dx = xdot; 36 dy = ydot; 37 dz = zdot; 38 dtrans = [dx, dy, dz]; 39 40 % Need to solve for accelerations 41 RInBody = input.auxdata.R*[1;0;0]; 42 omega = [rolldot'; pitchdot'; yawdot']; 43 alpha = [rollddot'; pitchddot'; yawddot']; 44 [¬, c] = size(omega); 45 for i=1:c 46 CentAccInBody_mpsps(:,i) = cross(omega(:,i), ... cross(omega(:,i), RInBody)); 47 AngAccInBody_mpsps(:,i) = cross(alpha(:,i), RInBody); 48 dcm = quat2dcm([qw(i) qx(i) qy(i) qz(i)]); 49 CentAccInInertial_mpsps = dcm*CentAccInBody_mpsps(:,i); 50 AngAccInInertial_mpsps = dcm*AngAccInBody_mpsps(:,i); 51 TotalAccInInertial_mpsps(:,i) = CentAccInInertial_mpsps + ... AngAccInInertial_mpsps; 52 end 53 54 xddot = TotalAccInInertial_mpsps(1,:)'; 55 yddot = TotalAccInInertial_mpsps(2,:)'; 56 zddot = TotalAccInInertial_mpsps(3,:)'; 57 ddtrans = [xddot, yddot, zddot]; 58 59 phaseout.dynamics = [quatdot, angacc, dtrans, ddtrans]; 60 61 % Path constraint 62 phaseout.path= sqrt(x.^2 + y.^2 + z.^2); 63 %% Find integrand 64 t = input.phase.time; 65 n = length(t); 66 67 for i=1:n 68 normU(i) = norm([u1(i), u2(i), u3(i)]); 69 end 70 71 %% Find Hdot 72 R = input.auxdata.R;

187 73 for i=1:n 74 omega_123 = [rolldot(i); pitchdot(i); yawdot(i)]; 75 alpha_123 = [rollddot(i); pitchddot(i); yawddot(i)]; 76 int_product = input.auxdata.I_CMCwrtTAR*omega_123; 77 Hdot = input.auxdata.I_CMCwrtTAR*alpha_123 + cross(omega_123, ... int_product); 78 Mx(i) = Hdot(1); 79 Fz(i) = -Hdot(2)/R; 80 Fth(i) = Hdot(3)/R; 81 end 82 83 %% Find Loads- dims are wrong 84 TotalForceInBody_N = input.auxdata.mass_C*(CentAccInBody_mpsps + ... AngAccInBody_mpsps); 85 ShearLoadY_N = TotalForceInBody_N(2,:)' - Fth'; 86 ShearLoadZ_N = TotalForceInBody_N(3,:)' - Fz'; 87 88 %% Find Moments 89 I_C = input.auxdata.I_C; 90 Torsion = I_C(1,1)*rolldot - (I_C(2,2) - ... I_C(3,3))*pitchdot.*yawdot - Mx'; 91 BendingMomY_Nm = I_C(2,2)*pitchddot - ... (I_C(3,3)-I_C(1,1))*rolldot.*yawdot; 92 BendingMomZ_Nm = I_C(3,3)*yawddot - ... (I_C(1,1)-I_C(2,2))*pitchdot.*rolldot; 93 94 % Integrand 95 phaseout.integrand = normU' + (ShearLoadY_N) + ... 96 (ShearLoadZ_N) + (Torsion) + (BendingMomY_Nm) + (BendingMomZ_Nm); 97 98 end

Listing C.8: detumbleEndpoint.m

1 function output = detumbleEndpoint(input) 2 3 % Inputs 4 % input.phase(phasenumber).initialstate-- row 5 % input.phase(phasenumber).finalstate-- row 6 % input.phase(phasenumber).initialtime-- scalar 7 % input.phase(phasenumber).finaltime-- scalar 8 % input.phase(phasenumber).integral-- row 9 % input.parameter-- row 10 % input.auxdata= auxiliary information 11 12 % Output 13 % output.objective-- scalar 14 % output.eventgroup(eventnumber).event-- row 15 16 output.objective = input.phase.integral; 17 18 end

188 Bibliography

[1] A. Vogeley and R. Brissenden, “Survey of rendezvous progress,” in Guidance and Control Conference, p. 353, 1964. [2] J. Mayer and R. Parten, “Development of the gemini operational rendezvous plan.,” Journal of spacecraft and rockets, vol. 5, no. 9, pp. 1023–1028, 1968. [3] G. Lunney, “Summary of gemini rendezvous experience,” in Simulation and Sup- port Conference, p. 272, 1967. [4] D. Zimpfer, P. Kachmar, and S. Tuohy, “Autonomous rendezvous, capture and in-space assembly: past, present and future,” in 1st Space exploration conference: continuing the voyage of discovery, p. 2523, 2005. [5] K. A. Young and J. D. Alexander, “Apollo lunar rendezvous,” Journal of Space- craft and Rockets, vol. 7, p. 1083, 1970. [6] J. L. Goodman, “History of space shuttle rendezvous and proximity operations,” Journal of Spacecraft and Rockets, vol. 43, no. 5, pp. 944–959, 2006. [7] B. LOGAN, JR, “Shuttle payload deployment and retrieval system,” in Guidance and Control Conference, p. 1580, 1982. [8] “View of the hst berthed to the shuttle atlantis : Nasa : Free download, borrow, and streaming.” https://archive.org/details/s125e007257, May 2009. [9] T. E. Rumford, “Demonstration of autonomous rendezvous technology (dart) project summary,” in Space Systems Technology and Operations, vol. 5088, pp. 10–20, International Society for Optics and Photonics, 2003. [10] G. S. Center, “On-orbit satellite servicing study project report,” tech. rep., Tech- nical report, 2010. [11] T. M. Davis and D. Melanson, “Xss-10 microsatellite flight demonstration pro- gram results,” in Spacecraft platforms and infrastructure, vol. 5419, pp. 16–26, International Society for Optics and Photonics, 2004. [12] A. Ogilvie, J. Allport, M. Hannah, and J. Lymer, “Autonomous satellite servicing using the orbital express demonstration manipulator system,” in Proc. of the 9th International Symposium on Artificial Intelligence, Robotics and Automation in Space (i-SAIRAS’08), pp. 25–29, 2008.

189 [13] “Orbital express astro.” http://www.astronautix.com/o/ orbitalexpressastro.html.

[14] D. J. Kessler, N. L. Johnson, J. Liou, and M. Matney, “The kessler syndrome: implications to future space operations,” Advances in the Astronautical Sciences, vol. 137, no. 8, p. 2010, 2010.

[15] J.-C. Liou and N. L. Johnson, “Risks in space from orbiting debris,” 2006.

[16] C. Bonnal, J.-M. Ruault, and M.-C. Desjean, “Active debris removal: Recent progress and current trends,” Acta Astronautica, vol. 85, pp. 51–60, 2013.

[17] M. Shan, J. Guo, and E. Gill, “Review and comparison of active space debris capturing and removal methods,” Progress in Aerospace Sciences, vol. 80, pp. 18– 32, 2016.

[18] J. P. Gardner, J. C. Mather, M. Clampin, R. Doyon, M. A. Greenhouse, H. B. Hammel, J. B. Hutchings, P. Jakobsen, S. J. Lilly, K. S. Long, et al., “The james webb space telescope,” Space Science Reviews, vol. 123, no. 4, pp. 485–606, 2006.

[19] R. Rembala and C. Ower, “Robotic assembly and maintenance of future space stations based on the iss mission operations experience,” Acta Astronautica, vol. 65, no. 7-8, pp. 912–920, 2009.

[20] “Image of international space station.” https://spaceflight.nasa.gov/ gallery/images/station/assembly/hires/s88e5157.jpg.

[21] “Image of international space station.” https://spaceflight.nasa.gov/ gallery/images/station/assembly/hires/s133e010447.jpg.

[22] S. Mohan, Reconfiguration methods for on-orbit servicing, assembly, and opera- tions with application to space telescopes. PhD thesis, Massachusetts Institute of Technology, 2007.

[23] C. M. Jewison, Reconfigurable thruster selection algorithms for aggregative space- craft systems. PhD thesis, Massachusetts Institute of Technology, 2014.

[24] W. J. Larson and J. R. Wertz, “Space mission analysis and design,” tech. rep., Torrance, CA (United States); Microcosm, Inc., 1992.

[25] R. Garner, “Hubble servicing missions overview.” https://www.nasa.gov/ mission_pages/hubble/servicing/index.html, 2018.

[26] D. King, “Space servicing: past, present and future,” in Proceedings of the 6th International Symposium on Artificial Intelligence and Robotics & Automation in Space: i-SAIRAS, pp. 18–22, 2001.

[27] C. S. Agency, “About canadarm2.” http://www.asc-csa.gc.ca/eng/iss/ canadarm2/about.asp, 2018.

190 [28] C. Jewison, B. McCarthy, D. Sternberg, D. Strawser, and C. Fang, “Resource Aggregated Reconfigurable Control and Risk-Allocative Path Planning for On- orbit Assembly and Servicing of Satellites,” tech. rep., AIAA SciTech 2014, 2013.

[29] A. Saenz-Otero, Design Principles for the Development of Space Technology Mat- uration Laboratories Aboard the International Space Station. PhD thesis, Mas- sachusetts Institute of Technology, Cambridge, MA, 2005.

[30] J. James, C. Jewison, D. Sternberg, W. Sanchez, D. Roascio, and A. Saenz-Otero, “Recent SPHERES Docking and Reconfiguration Experiments on the ISS.” 2016.

[31] L. J. DiGirolamo, K. A. Hacker, A. H. Hoskins, and D. B. Spencer, “A hybrid motion planning algorithm for safe and efficient, close proximity, autonomous spacecraft missions,” in AIAA/AAS astrodynamics specialist conference, p. 4130, 2014.

[32] M. C. Jackson, “A six degree of freedom, plume-fuel optimal trajectory planner for spacecraft proximity operations using an a* node search,” Master’s thesis, Massachusetts Institute of Technology, 1994.

[33] A. Miele, M. Weeks, and M. Ciarcia, “Optimal trajectories for spacecraft ren- dezvous,” Journal of optimization theory and applications, vol. 132, no. 3, pp. 353–376, 2007.

[34] D.-R. Lee and H. Pernicka, “Integrated system for autonomous proximity oper- ations and docking,” International Journal of Aeronautical and Space Sciences, vol. 12, no. 1, pp. 43–56, 2011.

[35] J. Virgili-Llop, C. Zagaris, R. Zappulla, A. Bradstreet, and M. Romano, “A convex-programming-based guidance algorithm to capture a tumbling object on orbit using a spacecraft equipped with a robotic manipulator,” The International Journal of Robotics Research, vol. 38, no. 1, pp. 40–72, 2019.

[36] J. D. Munoz, Rapid path-planning algorithms for autonomous proximity opera- tions of satellites. PhD thesis, University of Florida, 2011.

[37] R. Zappulla, J. Virgili-Llop, and M. Romano, “Near-optimal real-time spacecraft guidance and control using harmonic potential functions and a modified rrt,” in 27th AAS/AIAA Space Flight Mechanics Meeting, San Antonio, TX, 2017.

[38] D. C. Sternberg et al., Optimal docking to tumbling objects with uncertain prop- erties. PhD thesis, Massachusetts Institute of Technology, 2017.

[39] J.-J. E. Slotine and W. Li, Applied Nonlinear Control. Prentice-Hall Upper Saddle River, NJ, 1 ed., 1991.

[40] K. D. Young, V. I. Utkin, and U. Ozguner, “A control engineer’s guide to sliding mode control,” in Proceedings. 1996 IEEE International Workshop on Variable Structure Systems.-VSS’96-, pp. 1–14, IEEE, 1996.

191 [41] Y. M. Sam, J. H. Osman, and M. R. A. Ghani, “A class of proportional-integral sliding mode control with application to active suspension system,” Systems & control letters, vol. 51, no. 3-4, pp. 217–223, 2004.

[42] I. Eker, “Sliding mode control with pid sliding surface and experimental applica- tion to an electromechanical plant,” ISA transactions, vol. 45, no. 1, pp. 109–118, 2006.

[43] L. Zhao and Y. Jia, “Finite-time attitude tracking control for a rigid spacecraft using time-varying terminal sliding mode techniques,” International Journal of Control, vol. 88, no. 6, pp. 1150–1162, 2015.

[44] I. D. Landau, R. Lozano, M. M’Saad, and A. Karimi, Adaptive control: algo- rithms, analysis and applications. Springer Science & Business Media, 2011.

[45] G. Kreisselmeier and B. Anderson, “Robust model reference adaptive control,” IEEE Transactions on Automatic Control, vol. 31, no. 2, pp. 127–133, 1986.

[46] S. Nicosia and P. Tomei, “Model reference adaptive control algorithms for indus- trial robots,” Automatica, vol. 20, no. 5, pp. 635–644, 1984.

[47] R. Kumar, S. Das, P. Syam, and A. K. Chattopadhyay, “Review on model ref- erence adaptive system for sensorless vector control of induction motor drives,” IET Electric Power Applications, vol. 9, no. 7, pp. 496–511, 2015.

[48] A. Shekhar and A. Sharma, “Review of model reference adaptive control,” in 2018 International Conference on Information, Communication, Engineering and Technology (ICICET), pp. 1–5, IEEE, 2018.

[49] A. T. Espinoza and W. Sanchez, “On-board parameter learning using a model reference adaptive position and attitude controller,” in 2017 IEEE Aerospace Conference, pp. 1–8, IEEE, 2017.

[50] A. P. Nair, N. Selvaganesan, and V. Lalithambika, “Lyapunov based pd/pid in model reference adaptive control for satellite launch vehicle systems,” Aerospace Science and Technology, vol. 51, pp. 70–77, 2016.

[51] K. J. Åström, “Theory and applications of adaptive controlâĂŤa survey,” Auto- matica, vol. 19, no. 5, pp. 471–486, 1983.

[52] K. J. Åström and B. Wittenmark, Adaptive control. Courier Corporation, 2013.

[53] D. Clarke and P. Gawthrop, “Self-tuning control,” in Proceedings of the Institu- tion of Electrical Engineers, vol. 126, pp. 633–640, IET, 1979.

[54] J.-J. Slotine and J. Coetsee, “Adaptive sliding controller synthesis for non-linear systems,” International Journal of Control, vol. 43, no. 6, pp. 1631–1651, 1986.

192 [55] J.-J. Slotine and S. S. Sastry, “Tracking control of non-linear systems using sliding surfaces, with application to robot manipulators,” International journal of control, vol. 38, no. 2, pp. 465–492, 1983.

[56] F. Plestan, Y. Shtessel, V. Bregeault, and A. Poznyak, “New methodologies for adaptive sliding mode control,” International journal of control, vol. 83, no. 9, pp. 1907–1919, 2010.

[57] G. Godard and K. D. Kumar, “Fault tolerant reconfigurable satellite formations using adaptive variable structure techniques,” Journal of guidance, control, and dynamics, vol. 33, no. 3, pp. 969–984, 2010.

[58] J. Li, Y. Pan, and K. D. Kumar, “Formation flying control of small satellites,” in AIAA Guidance, Navigation, and Control Conference, p. 8296, 2010.

[59] Q. Hu and B. Xiao, “Fault-tolerant sliding mode attitude control for flexible spacecraft under loss of actuator effectiveness,” Nonlinear Dynamics, vol. 64, no. 1-2, pp. 13–23, 2011.

[60] S. Kawamoto, Y. Ohkawa, H. Okamoto, K. Iki, and T. Okumura, “Current status of research and development on active debris removal at ,” in 7th European Conference on Space Debris, 2017.

[61] T.-C. Nguyen-Huynh and I. Sharf, “Adaptive reactionless motion for space ma- nipulator when capturing an unknown tumbling target,” in 2011 IEEE Interna- tional Conference on Robotics and Automation, pp. 4202–4207, IEEE, 2011.

[62] Y.-w. Zhang, L.-p. Yang, Y.-w. Zhu, H. Huang, and W.-w. Cai, “Nonlinear 6- dof control of spacecraft docking with inter-satellite electromagnetic force,” Acta Astronautica, vol. 77, pp. 97–108, 2012.

[63] J. G. Katz, “Estimation and control of flexible space structures for autonomous on-orbit assembly,” Master’s thesis, Massachusetts Institute of Technology, 2009.

[64] F. Aghili, “Time-optimal detumbling control of spacecraft,” Journal of guidance, control, and dynamics, vol. 32, no. 5, pp. 1671–1675, 2009.

[65] G. Avanzini and F. Giulietti, “Magnetic detumbling of a rigid spacecraft,” Jour- nal of guidance, control, and dynamics, vol. 35, no. 4, pp. 1326–1334, 2012.

[66] V. Coverstone-Carroll, “Detumbling and reorienting underactuated rigid space- craft,” Journal of Guidance, Control, and Dynamics, vol. 19, no. 3, pp. 708–710, 1996.

[67] C. Grubin, “Docking dynamics for rigid-body spacecraft,” AIAA Journal, vol. 2, no. 1, pp. 5–12, 1964.

193 [68] M. A. Patterson and A. V. Rao, “Gpops-ii: A matlab software for solving multiple-phase optimal control problems using hp-adaptive gaussian quadrature collocation methods and sparse nonlinear programming,” ACM Transactions on Mathematical Software (TOMS), vol. 41, no. 1, p. 1, 2014.

[69] A. Waechter, C. Laird, F. Margot, and Y. Kawajir, “Introduction to ipopt: A tutorial for downloading, installing, and using ipopt,” Revision, 2009.

194