public static void Launch(
            string vessel_name,
            CommonData common_data,
            Connection connection,
            Service space_center,
            Vessel vessel,
            double apoapsis)
        {
            KrpcAutoPilot.Control control = new KrpcAutoPilot.Control(vessel_name, common_data, connection, space_center, vessel);
            control.UpdateData();

            control.Engage();

            vessel.Control.RCS = false;

            while (true)
            {
                if (!control.UpdateData())
                {
                    break;
                }
                if (control.LaunchIntoApoapsis(apoapsis, 0d))
                {
                    break;
                }
                if (control.Execute() == KrpcAutoPilot.Control.Status.FAIL)
                {
                    break;
                }
                Thread.Sleep(100);
            }

            control.LaunchIntoPeriapsisInit();

            while (true)
            {
                if (!control.UpdateData())
                {
                    break;
                }
                if (control.LaunchIntoPeriapsis(apoapsis))
                {
                    break;
                }
                if (control.Execute() == KrpcAutoPilot.Control.Status.FAIL)
                {
                    break;
                }
                Thread.Sleep(100);
            }

            control.DisEngage();
            control.Dispose();
        }
        public static void LaunchAndDocking(
            string vessel_name,
            CommonData common_data,
            Connection connection,
            Service space_center,
            Vessel vessel,
            double apoapsis,
            string target_vessel_name,
            string target_port_tag,
            string control_node_tag,
            ref bool force_docking)
        {
            KrpcAutoPilot.Control control = new KrpcAutoPilot.Control(vessel_name, common_data, connection, space_center, vessel);
            control.UpdateData();

            control.Engage();

            vessel.Control.RCS = false;

            while (!force_docking)
            {
                if (!control.UpdateData())
                {
                    break;
                }
                if (control.LaunchIntoApoapsis(apoapsis, 0d))
                {
                    break;
                }
                if (control.Execute() == KrpcAutoPilot.Control.Status.FAIL)
                {
                    break;
                }
                Thread.Sleep(100);
            }

            vessel.Control.RCS = true;
            control.LaunchIntoPeriapsisInit();

            SwitchRcsEngines(vessel, true);
            bool fairing_separated = false;

            while (!force_docking)
            {
                if (!control.UpdateData())
                {
                    break;
                }
                if (control.LaunchIntoPeriapsis(apoapsis))
                {
                    break;
                }
                if (control.Execute() == KrpcAutoPilot.Control.Status.FAIL)
                {
                    break;
                }
                if (!fairing_separated &&
                    (!common_data.Body.HasAtmosphere ||
                     control.State.Vessel.Altitude > common_data.Body.AtmosphereDepth))
                {
                    fairing_separated = true;
                    try
                    {
                        vessel.Control.ActivateNextStage();
                    }
                    catch (Exception)
                    {
                        break;
                    }
                }
                Thread.Sleep(100);
            }

            control.ApproachInit(
                ship_name: target_vessel_name,
                dock_tag: target_port_tag,
                control_node_tag: control_node_tag);

            bool shroud_opened = false;

            while (true)
            {
                if (!control.UpdateData())
                {
                    break;
                }
                double distance;
                if (control.Approach(out distance) == KrpcAutoPilot.Control.Status.FINISHED)
                {
                    break;
                }
                if (!shroud_opened && distance < 20d)
                {
                    shroud_opened = true;
                    vessel.Control.ToggleActionGroup(2);
                }
                if (control.Execute() == KrpcAutoPilot.Control.Status.FAIL)
                {
                    break;
                }
                Thread.Sleep(100);
            }

            control.DisEngage();
            control.Dispose();
        }