Repository: OpenMDAO/dymos (language: python)

Issue:
Unify setting values across transcriptions
### Proposed feature.

Currently each of the different transcriptions require distinct methods of setting state values. 
For Gauss-Lobatto and Radau-ps, we use `set_val('phase.states:{}', val)`. 
For explicit shooting, this causes an error since `'states.{}'` does not exist. We must instead do `set_val('phase.initial_states:{}', val)`.
For Birkhoff, we need to set `'states:{}'`, `'initial_states:{}'`, and `'final_states:{}'`.

This makes it cumbersome to move between transcriptions. Additionally, in the birkhoff transcription, if the initial and final state values are not set they default to 1. In that case, if `fix_initial` or `fix_final` is used, the collocation constraint will drive the initial and/or final value to 1, likely leading to invalid trajectories. This can be confusing, so to simplify the process we should have a single method to set the initial guess for the states.

The proposed change is to use `phase.set_state_val()` with the signature `set_state_val(self, name, vals=None, time_vals=None, units=None, interpolation_kind='linear')`

This method will automatically set the appropriate values required for the transcription.

To keep the API consistent, we should also introduce the methods `set_control_val`, `set_polynomial_control_val`, `set_parameter_val`, and `set_time_val` to `Phase`. With the signatures

`set_time_val(self, initial=None, duration=None, units=None)`
`set_control_val(self, name, vals=None, time_vals=None, units=None, interpolation_kind='linear')`
`set_polynomial_control_val(self, name, vals=None, time_vals=None, units=None, interpolation_kind='linear')`
`set_parameter_val(self, name, val=None, units=None)`

### Example

_No response_


Discussion / hints:

Fix patch:
diff --git a/docs/dymos_book/api/phase_api.ipynb b/docs/dymos_book/api/phase_api.ipynb
index 01ca8d272..ab5d38a5d 100644
--- a/docs/dymos_book/api/phase_api.ipynb
+++ b/docs/dymos_book/api/phase_api.ipynb
@@ -170,6 +170,14 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_time_val\n",
+    "\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Phase.set_time_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
+    "\n",
     "## add_state\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Phase.add_state\n",
@@ -182,6 +190,12 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_state_val\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Phase.set_state_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
     "## add_control\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Phase.add_control\n",
@@ -194,6 +208,12 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_control_val\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Phase.set_control_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
     "## add_polynomial_control\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Phase.add_polynomial_control\n",
@@ -206,6 +226,12 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_polynomial_control_val\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Phase.set_polynomial_control_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
     "## add_parameter\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Phase.add_parameter\n",
@@ -218,6 +244,12 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_parameter_val\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Phase.set_parameter_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
     "## add_timeseries\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Phase.add_timeseries\n",
@@ -266,6 +298,13 @@
     "        :noindex:\n",
     "```"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
@@ -293,7 +332,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/api/trajectory_api.ipynb b/docs/dymos_book/api/trajectory_api.ipynb
index e31190dca..fdaff59b9 100644
--- a/docs/dymos_book/api/trajectory_api.ipynb
+++ b/docs/dymos_book/api/trajectory_api.ipynb
@@ -66,6 +66,12 @@
     "        :noindex:\n",
     "```\n",
     "\n",
+    "## set_parameter_val\n",
+    "```{eval-rst}\n",
+    "    .. automethod:: dymos.Trajectory.set_parameter_val\n",
+    "        :noindex:\n",
+    "```\n",
+    "\n",
     "## add_phase\n",
     "```{eval-rst}\n",
     "    .. automethod:: dymos.Trajectory.add_phase\n",
@@ -111,7 +117,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/balanced_field/balanced_field.ipynb b/docs/dymos_book/examples/balanced_field/balanced_field.ipynb
index 48fd00ad4..8372bd8f9 100644
--- a/docs/dymos_book/examples/balanced_field/balanced_field.ipynb
+++ b/docs/dymos_book/examples/balanced_field/balanced_field.ipynb
@@ -423,19 +423,19 @@
    ]
   },
   {
-    "cell_type": "code",
-    "execution_count": null,
-    "metadata": {
-     "tags": [
-      "active-ipynb",
-      "remove-input",
-      "remove-output"
-     ]
-    },
-    "outputs": [],
-    "source": [
-     "%matplotlib inline"
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": [
+     "active-ipynb",
+     "remove-input",
+     "remove-output"
     ]
+   },
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
   },
   {
    "cell_type": "code",
@@ -661,7 +661,6 @@
    "cell_type": "code",
    "execution_count": null,
    "metadata": {
-    "scrolled": true,
     "tags": [
      "output_scroll"
     ]
@@ -670,37 +669,32 @@
    "source": [
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.br_to_v1.t_initial', 0)\n",
-    "p.set_val('traj.br_to_v1.t_duration', 35)\n",
-    "p.set_val('traj.br_to_v1.states:r', br_to_v1.interp('r', [0, 2500.0]))\n",
-    "p.set_val('traj.br_to_v1.states:v', br_to_v1.interp('v', [0, 100.0]))\n",
-    "p.set_val('traj.br_to_v1.parameters:alpha', 0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.v1_to_vr.t_initial', 35)\n",
-    "p.set_val('traj.v1_to_vr.t_duration', 35)\n",
-    "p.set_val('traj.v1_to_vr.states:r', v1_to_vr.interp('r', [2500, 300.0]))\n",
-    "p.set_val('traj.v1_to_vr.states:v', v1_to_vr.interp('v', [100, 110.0]))\n",
-    "p.set_val('traj.v1_to_vr.parameters:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.rto.t_initial', 35)\n",
-    "p.set_val('traj.rto.t_duration', 35)\n",
-    "p.set_val('traj.rto.states:r', rto.interp('r', [2500, 5000.0]))\n",
-    "p.set_val('traj.rto.states:v', rto.interp('v', [110, 0]))\n",
-    "p.set_val('traj.rto.parameters:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.rotate.t_initial', 70)\n",
-    "p.set_val('traj.rotate.t_duration', 5)\n",
-    "p.set_val('traj.rotate.states:r', rotate.interp('r', [1750, 1800.0]))\n",
-    "p.set_val('traj.rotate.states:v', rotate.interp('v', [80, 85.0]))\n",
-    "p.set_val('traj.rotate.polynomial_controls:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.climb.t_initial', 75)\n",
-    "p.set_val('traj.climb.t_duration', 15)\n",
-    "p.set_val('traj.climb.states:r', climb.interp('r', [5000, 5500.0]), units='ft')\n",
-    "p.set_val('traj.climb.states:v', climb.interp('v', [160, 170.0]), units='kn')\n",
-    "p.set_val('traj.climb.states:h', climb.interp('h', [0, 35.0]), units='ft')\n",
-    "p.set_val('traj.climb.states:gam', climb.interp('gam', [0, 5.0]), units='deg')\n",
-    "p.set_val('traj.climb.controls:alpha', 5.0, units='deg')\n",
+    "br_to_v1.set_time_val(initial=0.0, duration=35.0)\n",
+    "br_to_v1.set_state_val('r', [0, 2500.0])\n",
+    "br_to_v1.set_state_val('v', [0.0001, 100.0])\n",
+    "br_to_v1.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "v1_to_vr.set_time_val(initial=35.0, duration=35.0)\n",
+    "v1_to_vr.set_state_val('r', [2500, 300.0])\n",
+    "v1_to_vr.set_state_val('v', [100, 110.0])\n",
+    "v1_to_vr.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "rto.set_time_val(initial=35.0, duration=1.0)\n",
+    "rto.set_state_val('r', [2500, 5000.0])\n",
+    "rto.set_state_val('v', [110, 0.0001])\n",
+    "rto.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "rotate.set_time_val(initial=35.0, duration=5.0)\n",
+    "rotate.set_state_val('r', [1750, 1800.0])\n",
+    "rotate.set_state_val('v', [80, 85.0])\n",
+    "rotate.set_polynomial_control_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "climb.set_time_val(initial=30.0, duration=20.0)\n",
+    "climb.set_state_val('r', [5000, 5500.0], units='ft')\n",
+    "climb.set_state_val('v', [160, 170.0], units='kn')\n",
+    "climb.set_state_val('h', [0.0, 35.0], units='ft')\n",
+    "climb.set_state_val('gam', [0.0, 5.0], units='deg')\n",
+    "climb.set_control_val('alpha', 5.0, units='deg')\n",
     "\n",
     "dm.run_problem(p, run_driver=True, simulate=True)"
    ]
@@ -818,7 +812,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/balanced_field/balanced_field_funccomp.ipynb b/docs/dymos_book/examples/balanced_field/balanced_field_funccomp.ipynb
index 3502f21eb..696233bc7 100644
--- a/docs/dymos_book/examples/balanced_field/balanced_field_funccomp.ipynb
+++ b/docs/dymos_book/examples/balanced_field/balanced_field_funccomp.ipynb
@@ -419,37 +419,32 @@
     "#\n",
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.br_to_v1.t_initial', 0)\n",
-    "p.set_val('traj.br_to_v1.t_duration', 35)\n",
-    "p.set_val('traj.br_to_v1.states:r', br_to_v1.interp('r', [0, 2500.0]))\n",
-    "p.set_val('traj.br_to_v1.states:v', br_to_v1.interp('v', [0, 100.0]))\n",
-    "p.set_val('traj.br_to_v1.parameters:alpha', 0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.v1_to_vr.t_initial', 35)\n",
-    "p.set_val('traj.v1_to_vr.t_duration', 35)\n",
-    "p.set_val('traj.v1_to_vr.states:r', v1_to_vr.interp('r', [2500, 300.0]))\n",
-    "p.set_val('traj.v1_to_vr.states:v', v1_to_vr.interp('v', [100, 110.0]))\n",
-    "p.set_val('traj.v1_to_vr.parameters:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.rto.t_initial', 35)\n",
-    "p.set_val('traj.rto.t_duration', 35)\n",
-    "p.set_val('traj.rto.states:r', rto.interp('r', [2500, 5000.0]))\n",
-    "p.set_val('traj.rto.states:v', rto.interp('v', [110, 0]))\n",
-    "p.set_val('traj.rto.parameters:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.rotate.t_initial', 70)\n",
-    "p.set_val('traj.rotate.t_duration', 5)\n",
-    "p.set_val('traj.rotate.states:r', rotate.interp('r', [1750, 1800.0]))\n",
-    "p.set_val('traj.rotate.states:v', rotate.interp('v', [80, 85.0]))\n",
-    "p.set_val('traj.rotate.polynomial_controls:alpha', 0.0, units='deg')\n",
-    "\n",
-    "p.set_val('traj.climb.t_initial', 75)\n",
-    "p.set_val('traj.climb.t_duration', 15)\n",
-    "p.set_val('traj.climb.states:r', climb.interp('r', [5000, 5500.0]), units='ft')\n",
-    "p.set_val('traj.climb.states:v', climb.interp('v', [160, 170.0]), units='kn')\n",
-    "p.set_val('traj.climb.states:h', climb.interp('h', [0, 35.0]), units='ft')\n",
-    "p.set_val('traj.climb.states:gam', climb.interp('gam', [0, 5.0]), units='deg')\n",
-    "p.set_val('traj.climb.controls:alpha', 5.0, units='deg')\n",
+    "br_to_v1.set_time_val(initial=0.0, duration=35.0)\n",
+    "br_to_v1.set_state_val('r', [0, 2500.0])\n",
+    "br_to_v1.set_state_val('v', [0.0001, 100.0])\n",
+    "br_to_v1.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "v1_to_vr.set_time_val(initial=35.0, duration=35.0)\n",
+    "v1_to_vr.set_state_val('r', [2500, 300.0])\n",
+    "v1_to_vr.set_state_val('v', [100, 110.0])\n",
+    "v1_to_vr.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "rto.set_time_val(initial=35.0, duration=1.0)\n",
+    "rto.set_state_val('r', [2500, 5000.0])\n",
+    "rto.set_state_val('v', [110, 0.0001])\n",
+    "rto.set_parameter_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "rotate.set_time_val(initial=35.0, duration=5.0)\n",
+    "rotate.set_state_val('r', [1750, 1800.0])\n",
+    "rotate.set_state_val('v', [80, 85.0])\n",
+    "rotate.set_polynomial_control_val('alpha', 0.0, units='deg')\n",
+    "\n",
+    "climb.set_time_val(initial=30.0, duration=20.0)\n",
+    "climb.set_state_val('r', [5000, 5500.0], units='ft')\n",
+    "climb.set_state_val('v', [160, 170.0], units='kn')\n",
+    "climb.set_state_val('h', [0.0, 35.0], units='ft')\n",
+    "climb.set_state_val('gam', [0.0, 5.0], units='deg')\n",
+    "climb.set_control_val('alpha', 5.0, units='deg')\n",
     "\n",
     "dm.run_problem(p, run_driver=True, simulate=True)\n",
     "\n",
@@ -555,7 +550,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/brachistochrone/brachistochrone.ipynb b/docs/dymos_book/examples/brachistochrone/brachistochrone.ipynb
index 5a2b9b87f..a26591b11 100644
--- a/docs/dymos_book/examples/brachistochrone/brachistochrone.ipynb
+++ b/docs/dymos_book/examples/brachistochrone/brachistochrone.ipynb
@@ -476,13 +476,11 @@
     "#\n",
     "# Set the initial values\n",
     "#\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 2.0\n",
-    "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 10]))\n",
-    "p.set_val('traj.phase0.states:y', phase.interp('y', ys=[10, 5]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 9.9]))\n",
-    "p.set_val('traj.phase0.controls:theta', phase.interp('theta', ys=[5, 100.5]))\n",
+    "phase.set_time_val(initial=0.0, duration=2.0)\n",
+    "phase.set_state_val('x', [0, 10])\n",
+    "phase.set_state_val('y', [10, 5])\n",
+    "phase.set_state_val('v', [0, 9.9])\n",
+    "phase.set_control_val('theta', [5, 100.5])\n",
     "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
@@ -623,15 +621,11 @@
     "#\n",
     "# Set the initial values\n",
     "#\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 2.0\n",
-    "\n",
-    "# Only the initial values of the states are design variables,\n",
-    "# so the phase interp method is not used on states.\n",
-    "p.set_val('traj.phase0.initial_states:x', 0.0)\n",
-    "p.set_val('traj.phase0.initial_states:y', 10.0)\n",
-    "p.set_val('traj.phase0.initial_states:v', 0.0)\n",
-    "p.set_val('traj.phase0.controls:theta', phase.interp('theta', ys=[5, 100.5]))\n",
+    "phase.set_time_val(initial=0.0, duration=2.0)\n",
+    "phase.set_state_val('x', [0, 10])\n",
+    "phase.set_state_val('y', [10, 5])\n",
+    "phase.set_state_val('v', [0, 9.9])\n",
+    "phase.set_control_val('theta', [5, 100.5])\n",
     "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
diff --git a/docs/dymos_book/examples/brachistochrone/brachistochrone_tandem_phases.ipynb b/docs/dymos_book/examples/brachistochrone/brachistochrone_tandem_phases.ipynb
index 2699fbb85..0ad7aecde 100644
--- a/docs/dymos_book/examples/brachistochrone/brachistochrone_tandem_phases.ipynb
+++ b/docs/dymos_book/examples/brachistochrone/brachistochrone_tandem_phases.ipynb
@@ -258,13 +258,11 @@
     "p.model.linear_solver = om.DirectSolver()\n",
     "p.setup()\n",
     "\n",
-    "p['phase0.t_initial'] = 0.0\n",
-    "p['phase0.t_duration'] = 2.0\n",
-    "\n",
-    "p.set_val('phase0.states:x', phase0.interp('x', ys=[0, 10]))\n",
-    "p.set_val('phase0.states:y', phase0.interp('y', ys=[10, 5]))\n",
-    "p.set_val('phase0.states:v', phase0.interp('v', ys=[0, 9.9]))\n",
-    "p.set_val('phase0.controls:theta', phase0.interp('theta', ys=[5, 100]))\n",
+    "phase0.set_time_val(initial=0.0, duration=2.0)\n",
+    "phase0.set_state_val('x', [0, 10])\n",
+    "phase0.set_state_val('y', [10, 5])\n",
+    "phase0.set_state_val('v', [0, 9.9])\n",
+    "phase0.set_control_val('theta', [5, 100.5])\n",
     "\n",
     "p['phase0.parameters:g'] = 9.80665\n",
     "\n",
@@ -372,7 +370,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_controls.ipynb b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_controls.ipynb
index e60502dcd..df7c1e2db 100644
--- a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_controls.ipynb
+++ b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_controls.ipynb
@@ -179,13 +179,13 @@
     "p.setup(check=True)\n",
     "\n",
     "# Now that the OpenMDAO problem is setup, we can set the values of the states and controls.\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')\n",
+    "phase.set_state_val('x', [0, 10])\n",
     "\n",
-    "p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')\n",
+    "phase.set_state_val('y', [10, 5])\n",
     "\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')\n",
+    "phase.set_state_val('v', [0, 5])\n",
     "\n",
-    "p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')\n",
+    "phase.set_control_val('theta', [90, 90.5], units='deg')\n",
     "\n",
     "# Run the driver to solve the problem\n",
     "p.run_driver()\n",
@@ -259,7 +259,7 @@
    }
   },
   "kernelspec": {
-   "display_name": "Python 3",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
    "name": "python3"
   },
@@ -273,7 +273,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.3"
+   "version": "3.11.0"
   },
   "orphan": true
  },
diff --git a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_init_duration_states.ipynb b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_init_duration_states.ipynb
index 161060fbf..62fc96589 100644
--- a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_init_duration_states.ipynb
+++ b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_init_duration_states.ipynb
@@ -164,18 +164,17 @@
     "# p.set_val('x0', 0.0, units='m')\n",
     "# Here we're intentially setting the intiial x value to something other than zero, just\n",
     "# to demonstrate that the optimizer brings it back in line with the value of x0 set above.\n",
-    "p.set_val('traj.phase0.states:x',\n",
-    "          phase.interp('x', [0, 10]),\n",
-    "          units='m')\n",
-    "p.set_val('traj.phase0.states:y',\n",
-    "          phase.interp('y', [10, 5]),\n",
-    "          units='m')\n",
-    "p.set_val('traj.phase0.states:v',\n",
-    "          phase.interp('v', [0, 5]),\n",
-    "          units='m/s')\n",
-    "p.set_val('traj.phase0.controls:theta',\n",
-    "          phase.interp('theta', [90, 90]),\n",
-    "          units='deg')\n",
+    "phase.set_state_val('x', [0, 10],\n",
+    "                    units='m')\n",
+    "\n",
+    "phase.set_state_val('y', [10, 5],\n",
+    "                    units='m')\n",
+    "\n",
+    "phase.set_state_val('v', [0, 9.9],\n",
+    "                    units='m/s')\n",
+    "\n",
+    "phase.set_control_val('theta', [5, 100.5],\n",
+    "                      units='deg')\n",
     "\n",
     "# Run the driver to solve the problem\n",
     "dm.run_problem(p, simulate=True)\n"
@@ -260,7 +259,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_states.ipynb b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_states.ipynb
index 9a8d1948a..576a86dbe 100644
--- a/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_states.ipynb
+++ b/docs/dymos_book/examples/brachistochrone/brachistochrone_upstream_states.ipynb
@@ -190,21 +190,18 @@
     "\n",
     "# Here we're intentially setting the intiial x value to something other than zero, just\n",
     "# to demonstrate that the optimizer brings it back in line with the value of x0 set above.\n",
-    "p.set_val('traj.phase0.states:x',\n",
-    "          phase.interp('x', [1, 10]),\n",
-    "          units='m')\n",
+    "phase.set_state_val('x', [1, 10],\n",
+    "                   units='m')\n",
     "\n",
-    "p.set_val('traj.phase0.states:y',\n",
-    "          phase.interp('y', [10, 5]),\n",
-    "          units='m')\n",
+    "phase.set_state_val('y', [10, 5],\n",
+    "                   units='m')\n",
     "\n",
-    "p.set_val('traj.phase0.states:v',\n",
-    "          phase.interp('v', [0, 5]),\n",
-    "          units='m/s')\n",
+    "phase.set_state_val('v', [0, 5],\n",
+    "                   units='m/s')\n",
     "\n",
-    "p.set_val('traj.phase0.controls:theta',\n",
-    "          phase.interp('theta', [90, 90]),\n",
-    "          units='deg')\n",
+    "phase.set_control_val('theta',\n",
+    "                      [90, 90],\n",
+    "                     units='deg')\n",
     "\n",
     "# Run the driver to solve the problem\n",
     "dm.run_problem(p, make_plots=True)\n",
@@ -275,7 +272,7 @@
    }
   },
   "kernelspec": {
-   "display_name": "Python 3",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
    "name": "python3"
   },
@@ -289,7 +286,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.3"
+   "version": "3.11.0"
   },
   "orphan": true
  },
diff --git a/docs/dymos_book/examples/bryson_denham/bryson_denham.ipynb b/docs/dymos_book/examples/bryson_denham/bryson_denham.ipynb
index 3f0a159de..02fe19939 100644
--- a/docs/dymos_book/examples/bryson_denham/bryson_denham.ipynb
+++ b/docs/dymos_book/examples/bryson_denham/bryson_denham.ipynb
@@ -220,19 +220,20 @@
    ]
   },
   {
-    "cell_type": "code",
-    "execution_count": null,
-    "metadata": {
-     "tags": [
-      "active-ipynb",
-      "remove-input",
-      "remove-output"
-     ]
-    },
-    "outputs": [],
-    "source": [
-     "%matplotlib inline"
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0f14deb3",
+   "metadata": {
+    "tags": [
+     "active-ipynb",
+     "remove-input",
+     "remove-output"
     ]
+   },
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
   },
   {
    "cell_type": "code",
@@ -423,13 +424,13 @@
     "#\n",
     "# Set the initial values\n",
     "#\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 1.0\n",
     "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 0]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', ys=[1, -1]))\n",
-    "p.set_val('traj.phase0.states:J', phase.interp('J', ys=[0, 1]))\n",
-    "p.set_val('traj.phase0.controls:u', np.sin(phase.interp('u', ys=[0, 0])))\n",
+    "phase.set_time_val(initial=0.0, duration=1.0)\n",
+    "\n",
+    "phase.set_state_val('x', [0, 0])\n",
+    "phase.set_state_val('v', [1, -1])\n",
+    "phase.set_state_val('J', [0, 1])\n",
+    "phase.set_control_val('u', [0, 0])\n",
     "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
@@ -718,7 +719,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/cannonball_implicit_duration/cannonball_implicit_duration.ipynb b/docs/dymos_book/examples/cannonball_implicit_duration/cannonball_implicit_duration.ipynb
index 16a8f5dc0..58683c036 100644
--- a/docs/dymos_book/examples/cannonball_implicit_duration/cannonball_implicit_duration.ipynb
+++ b/docs/dymos_book/examples/cannonball_implicit_duration/cannonball_implicit_duration.ipynb
@@ -370,13 +370,12 @@
     "\n",
     "guess = initial_guess(t_dur=30.0)\n",
     "\n",
-    "p.set_val('traj.phase.t_initial', 0.0)\n",
-    "p.set_val('traj.phase.t_duration', 30.0)\n",
+    "phase.set_time_val(initial=0.0, duration=30.0)\n",
     "\n",
-    "p.set_val('traj.phase.states:r', phase.interp('r', ys=guess['r'], xs=guess['t']))\n",
-    "p.set_val('traj.phase.states:h', phase.interp('h', ys=guess['h'], xs=guess['t']))\n",
-    "p.set_val('traj.phase.states:v', phase.interp('v', ys=guess['v'], xs=guess['t']))\n",
-    "p.set_val('traj.phase.states:gam', phase.interp('gam', ys=guess['gam'], xs=guess['t']), units='rad')\n",
+    "phase.set_state_val('r', vals=guess['r'], time_vals=guess['t'])\n",
+    "phase.set_state_val('h', vals=guess['h'], time_vals=guess['t'])\n",
+    "phase.set_state_val('v', vals=guess['v'], time_vals=guess['t'])\n",
+    "phase.set_state_val('gam', vals=guess['gam'], time_vals=guess['t'], units='rad')\n",
     "\n",
     "#####################################################\n",
     "# Run the optimization and final explicit simulation\n",
@@ -448,7 +447,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/cart_pole/cart_pole.ipynb b/docs/dymos_book/examples/cart_pole/cart_pole.ipynb
index 17d91e0f3..0862cbfb0 100644
--- a/docs/dymos_book/examples/cart_pole/cart_pole.ipynb
+++ b/docs/dymos_book/examples/cart_pole/cart_pole.ipynb
@@ -296,14 +296,14 @@
    "source": [
     "# --- set initial guess ---\n",
     "# The initial condition of cart-pole (i.e., state values at time 0) is set here because we set `fix_initial=True` when declaring the states.\n",
-    "p.set_val('traj.phase.t_initial', 0.0)  # set initial time to 0.\n",
-    "p.set_val(\"traj.phase.states:x\", phase.interp(xs=[0, 1, 2], ys=[0, 1, 1], nodes=\"state_input\"), units=\"m\")\n",
-    "p.set_val(\"traj.phase.states:x_dot\", phase.interp(xs=[0, 1, 2], ys=[0, 0.1, 0], nodes=\"state_input\"), units=\"m/s\")\n",
-    "p.set_val(\"traj.phase.states:theta\", phase.interp(xs=[0, 1, 2], ys=[0, np.pi/2, np.pi], nodes=\"state_input\"), units=\"rad\")\n",
-    "p.set_val(\"traj.phase.states:theta_dot\", phase.interp(xs=[0, 1, 2], ys=[0, 1, 0], nodes=\"state_input\"), units=\"rad/s\")\n",
-    "p.set_val(\"traj.phase.states:energy\", phase.interp(xs=[0, 1, 2], ys=[0, 30, 60], nodes=\"state_input\"))\n",
-    "p.set_val(\"traj.phase.controls:f\", phase.interp(xs=[0, 1, 2], ys=[3, -1, 0], nodes=\"control_input\"), units=\"N\")\n",
-    "    \n",
+    "phase.set_time_val(initial=0.0)  # set initial time to 0.\n",
+    "phase.set_state_val('x', vals=[0, 1, 1], time_vals=[0, 1, 2], units='m')\n",
+    "phase.set_state_val('x_dot', vals=[0, 0.1, 0], time_vals=[0, 1, 2], units='m/s')\n",
+    "phase.set_state_val('theta', vals=[0, np.pi/2, np.pi], time_vals=[0, 1, 2], units='rad')\n",
+    "phase.set_state_val('theta_dot', vals=[0, 1, 0], time_vals=[0, 1, 2], units='rad/s')\n",
+    "phase.set_state_val('energy', vals=[0, 30, 60], time_vals=[0, 1, 2])\n",
+    "phase.set_control_val('f', vals=[3, -1, 0], time_vals=[0, 1, 2], units='N')\n",
+    "\n",
     "# --- run optimization ---\n",
     "dm.run_problem(p, run_driver=True, simulate=True, simulate_kwargs={'method' : 'Radau', 'times_per_seg' : 10})\n",
     "# NOTE: with Simulate=True, dymos will call scipy.integrate.solve_ivp and simulate the trajectory using the optimized control inputs."
@@ -396,7 +396,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.5"
+   "version": "3.11.0"
   },
   "vscode": {
    "interpreter": {
diff --git a/docs/dymos_book/examples/commercial_aircraft/commercial_aircraft.ipynb b/docs/dymos_book/examples/commercial_aircraft/commercial_aircraft.ipynb
index 650a0f3ac..0b39db6b1 100644
--- a/docs/dymos_book/examples/commercial_aircraft/commercial_aircraft.ipynb
+++ b/docs/dymos_book/examples/commercial_aircraft/commercial_aircraft.ipynb
@@ -636,13 +636,11 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 3600.0\n",
-    "p['traj.phase0.states:range'] = phase.interp('range', ys=(0, 724.0))\n",
-    "p['traj.phase0.states:mass_fuel'] = phase.interp('mass_fuel', ys=(30000, 1e-3))\n",
-    "p['traj.phase0.states:alt'][:] = 10.0\n",
-    "\n",
-    "p['traj.phase0.controls:mach'][:] = 0.8\n",
+    "phase.set_time_val(initial=0.0, duration=3600)\n",
+    "phase.set_state_val('range', (0, 724.0))\n",
+    "phase.set_state_val('mass_fuel', (30000, 1e-3))\n",
+    "phase.set_state_val('alt', 10.0)\n",
+    "phase.set_control_val('mach', 0.8)\n",
     "\n",
     "p['assumptions.S'] = 427.8\n",
     "p['assumptions.mass_empty'] = 0.15E6\n",
@@ -736,7 +734,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/double_integrator/double_integrator.ipynb b/docs/dymos_book/examples/double_integrator/double_integrator.ipynb
index 41b70e78a..dcae666f2 100644
--- a/docs/dymos_book/examples/double_integrator/double_integrator.ipynb
+++ b/docs/dymos_book/examples/double_integrator/double_integrator.ipynb
@@ -204,12 +204,11 @@
     "#\n",
     "p.setup(check=True)\n",
     "\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 1.0\n",
+    "phase.set_time_val(initial=0.0, duration=1.0)\n",
     "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 0.25]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 0]))\n",
-    "p.set_val('traj.phase0.controls:u', phase.interp('u', ys=[1, -1]))\n",
+    "phase.set_state_val('x', [0, 0.25])\n",
+    "phase.set_state_val('v', [0, 0])\n",
+    "phase.set_control_val('u', [1, -1])\n",
     "\n",
     "#\n",
     "# Solve the problem.\n",
@@ -287,7 +286,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/finite_burn_orbit_raise/finite_burn_orbit_raise.ipynb b/docs/dymos_book/examples/finite_burn_orbit_raise/finite_burn_orbit_raise.ipynb
index debe4a1c1..4f52d3eeb 100644
--- a/docs/dymos_book/examples/finite_burn_orbit_raise/finite_burn_orbit_raise.ipynb
+++ b/docs/dymos_book/examples/finite_burn_orbit_raise/finite_burn_orbit_raise.ipynb
@@ -260,36 +260,30 @@
     "burn2 = p.model.traj.phases.burn2\n",
     "coast = p.model.traj.phases.coast\n",
     "\n",
-    "p.set_val('traj.burn1.t_initial', val=0.0)\n",
-    "p.set_val('traj.burn1.t_duration', val=2.25)\n",
-    "p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))\n",
-    "p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))\n",
-    "p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))\n",
-    "p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))\n",
-    "p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))\n",
-    "p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]))\n",
-    "p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))\n",
-    "\n",
-    "p.set_val('traj.coast.t_initial', val=2.25)\n",
-    "p.set_val('traj.coast.t_duration', val=3.0)\n",
-    "\n",
-    "p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))\n",
-    "p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))\n",
-    "p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))\n",
-    "p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))\n",
-    "p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))\n",
-    "\n",
-    "p.set_val('traj.burn2.t_initial', val=5.25)\n",
-    "p.set_val('traj.burn2.t_duration', val=1.75)\n",
-    "\n",
-    "p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1, 3.]))\n",
-    "p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [0, 4.0]))\n",
-    "p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [0, 0]))\n",
-    "p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3.)]))\n",
-    "p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))\n",
-    "p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))\n",
-    "\n",
-    "p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [0, 0]))\n",
+    "burn1.set_time_val(initial=0.0, duration=2.25)\n",
+    "burn1.set_state_val('r', [1, 1.5])\n",
+    "burn1.set_state_val('theta', [0, 1.7])\n",
+    "burn1.set_state_val('vr', [0, 0])\n",
+    "burn1.set_state_val('vt', [1, 1])\n",
+    "burn1.set_state_val('accel', [0.1, 0.0])\n",
+    "burn1.set_state_val('deltav', [0, 0.1])\n",
+    "burn1.set_control_val('u1', [-3.5, 13.0])\n",
+    "\n",
+    "coast.set_time_val(initial=2.25, duration=3.0)\n",
+    "coast.set_state_val('r', [1.3, 1.5])\n",
+    "coast.set_state_val('theta', [2.1767, 1.7])\n",
+    "coast.set_state_val('vr', [0.3285, 0])\n",
+    "coast.set_state_val('vt', [0.97, 1])\n",
+    "coast.set_state_val('accel', [0, 0])\n",
+    "\n",
+    "burn2.set_time_val(initial=5.25, duration=1.75)\n",
+    "burn2.set_state_val('r', [1, 3])\n",
+    "burn2.set_state_val('theta', [0, 4])\n",
+    "burn2.set_state_val('vr', [0, 0])\n",
+    "burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])\n",
+    "burn2.set_state_val('accel', [0.1, 0.0])\n",
+    "burn2.set_state_val('deltav', [0.1, 0.2])\n",
+    "burn2.set_control_val('u1', [0, 0])\n",
     "\n",
     "dm.run_problem(p, simulate=True)"
    ]
@@ -436,7 +430,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/hull/hull_problem.ipynb b/docs/dymos_book/examples/hull/hull_problem.ipynb
index ea84eff39..9dec62449 100644
--- a/docs/dymos_book/examples/hull/hull_problem.ipynb
+++ b/docs/dymos_book/examples/hull/hull_problem.ipynb
@@ -213,19 +213,20 @@
    ]
   },
   {
-    "cell_type": "code",
-    "execution_count": null,
-    "metadata": {
-     "tags": [
-      "active-ipynb",
-      "remove-input",
-      "remove-output"
-     ]
-    },
-    "outputs": [],
-    "source": [
-     "%matplotlib inline"
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fc8f4299",
+   "metadata": {
+    "tags": [
+     "active-ipynb",
+     "remove-input",
+     "remove-output"
     ]
+   },
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
   },
   {
    "cell_type": "code",
@@ -411,11 +412,11 @@
     "#\n",
     "# Set the initial values\n",
     "#\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', [1.5, 1]))\n",
-    "p.set_val('traj.phase0.states:xL', phase.interp('xL', [0, 1]))\n",
-    "p.set_val('traj.phase0.t_initial', 0)\n",
-    "p.set_val('traj.phase0.t_duration', 10)\n",
-    "p.set_val('traj.phase0.controls:u', phase.interp('u', [-7, -0.14]))\n",
+    "phase.set_state_val('x', [1.5, 1])\n",
+    "phase.set_state_val('xL', [0, 1])\n",
+    "phase.set_time_val(initial=0.0, duration=10.0)\n",
+    "phase.set_control_val('u', [-7, -0.14])\n",
+    "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
     "#\n",
diff --git a/docs/dymos_book/examples/hypersensitive/hypersensitive.ipynb b/docs/dymos_book/examples/hypersensitive/hypersensitive.ipynb
index 91d3e8870..8029582d5 100644
--- a/docs/dymos_book/examples/hypersensitive/hypersensitive.ipynb
+++ b/docs/dymos_book/examples/hypersensitive/hypersensitive.ipynb
@@ -246,11 +246,10 @@
     "\n",
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', [1.5, 1]))\n",
-    "p.set_val('traj.phase0.states:xL', phase.interp('xL', [0, 1]))\n",
-    "p.set_val('traj.phase0.t_initial', 0)\n",
-    "p.set_val('traj.phase0.t_duration', tf)\n",
-    "p.set_val('traj.phase0.controls:u', phase.interp('u', [-0.6, 2.4]))\n",
+    "phase.set_time_val(initial=0, duration=tf)\n",
+    "phase.set_state_val('x', [1.5, 1])\n",
+    "phase.set_state_val('xL', [0, 1])\n",
+    "phase.set_control_val('u', [-0.6, 2.4])\n",
     "\n",
     "#\n",
     "# Solve the problem.\n",
diff --git a/docs/dymos_book/examples/length_constrained_brachistochrone/length_constrained_brachistochrone.ipynb b/docs/dymos_book/examples/length_constrained_brachistochrone/length_constrained_brachistochrone.ipynb
index d767f963e..05a05236c 100644
--- a/docs/dymos_book/examples/length_constrained_brachistochrone/length_constrained_brachistochrone.ipynb
+++ b/docs/dymos_book/examples/length_constrained_brachistochrone/length_constrained_brachistochrone.ipynb
@@ -219,14 +219,12 @@
     "\n",
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.phase0.t_initial', 0.0)\n",
-    "p.set_val('traj.phase0.t_duration', 2.0)\n",
-    "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]))\n",
-    "p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', [0, 9.9]))\n",
-    "p.set_val('traj.phase0.controls:theta', phase.interp('theta', [5, 100]))\n",
-    "p.set_val('traj.phase0.parameters:g', 9.80665)\n",
+    "phase.set_time_val(initial=0.0, duration=2.0)\n",
+    "phase.set_state_val('x', [0, 10])\n",
+    "phase.set_state_val('y', [10, 5])\n",
+    "phase.set_state_val('v', [0, 9.9])\n",
+    "phase.set_control_val('theta', [5, 100])\n",
+    "phase.set_parameter_val('g', 9.80665)\n",
     "\n",
     "p.run_driver()\n",
     "\n",
@@ -274,7 +272,7 @@
    }
   },
   "kernelspec": {
-   "display_name": "Python 3",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
    "name": "python3"
   },
@@ -288,7 +286,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.3"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/min_time_climb/min_time_climb.ipynb b/docs/dymos_book/examples/min_time_climb/min_time_climb.ipynb
index 24e23ad18..5a68d9abf 100644
--- a/docs/dymos_book/examples/min_time_climb/min_time_climb.ipynb
+++ b/docs/dymos_book/examples/min_time_climb/min_time_climb.ipynb
@@ -274,15 +274,13 @@
     "#\n",
     "p.setup(check=True)\n",
     "\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 500\n",
-    "\n",
-    "p.set_val('traj.phase0.states:r', phase.interp('r', [0.0, 50000.0]))\n",
-    "p.set_val('traj.phase0.states:h', phase.interp('h', [100.0, 20000.0]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', [135.964, 283.159]))\n",
-    "p.set_val('traj.phase0.states:gam', phase.interp('gam', [0.0, 0.0]))\n",
-    "p.set_val('traj.phase0.states:m', phase.interp('m', [19030.468, 10000.]))\n",
-    "p.set_val('traj.phase0.controls:alpha', phase.interp('alpha', [0.0, 0.0]))\n",
+    "phase.set_time_val(initial=0.0, duration=350)\n",
+    "phase.set_state_val('r', [0.0, 50000.0])\n",
+    "phase.set_state_val('h', [100.0, 20000.0])\n",
+    "phase.set_state_val('v', [135.964, 283.159])\n",
+    "phase.set_state_val('gam', [0.0, 0.0])\n",
+    "phase.set_state_val('m', [19030.468, 10000.])\n",
+    "phase.set_control_val('alpha', [0.0, 0.0])\n",
     "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
@@ -363,7 +361,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/mountain_car/mountain_car.ipynb b/docs/dymos_book/examples/mountain_car/mountain_car.ipynb
index 21801be1e..1c35916c5 100644
--- a/docs/dymos_book/examples/mountain_car/mountain_car.ipynb
+++ b/docs/dymos_book/examples/mountain_car/mountain_car.ipynb
@@ -478,12 +478,11 @@
     "#\n",
     "# Set the initial values\n",
     "#\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 500.0\n",
+    "phase.set_time_val(initial=0.0, duration=500.0)\n",
     "\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', ys=[-0.5, 0.5]))\n",
-    "p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 0.07]))\n",
-    "p.set_val('traj.phase0.controls:u', np.sin(phase.interp('u', ys=[0, 1.0])))\n",
+    "phase.set_state_val('x', [-0.5, 0.5])\n",
+    "phase.set_state_val('v', [0, 0.07])\n",
+    "phase.set_control_val('u', [0, np.sin(1.0)])\n",
     "\n",
     "#\n",
     "# Solve for the optimal trajectory\n",
@@ -722,7 +721,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/multi_phase_cannonball/multi_phase_cannonball.ipynb b/docs/dymos_book/examples/multi_phase_cannonball/multi_phase_cannonball.ipynb
index f37970bce..ec7d16c28 100644
--- a/docs/dymos_book/examples/multi_phase_cannonball/multi_phase_cannonball.ipynb
+++ b/docs/dymos_book/examples/multi_phase_cannonball/multi_phase_cannonball.ipynb
@@ -412,23 +412,22 @@
     "p.set_val('radius', 0.05, units='m')\n",
     "p.set_val('dens', 7.87, units='g/cm**3')\n",
     "\n",
-    "p.set_val('traj.parameters:CD', 0.5)\n",
+    "traj.set_parameter_val('CD', 0.5)\n",
     "\n",
-    "p.set_val('traj.ascent.t_initial', 0.0)\n",
-    "p.set_val('traj.ascent.t_duration', 10.0)\n",
     "\n",
-    "p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))\n",
-    "p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))\n",
-    "p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))\n",
-    "p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')\n",
+    "ascent.set_time_val(initial=0.0, duration=10.0)\n",
     "\n",
-    "p.set_val('traj.descent.t_initial', 10.0)\n",
-    "p.set_val('traj.descent.t_duration', 10.0)\n",
+    "ascent.set_state_val('r', [0, 100])\n",
+    "ascent.set_state_val('h', [0, 100])\n",
+    "ascent.set_state_val('v', [200, 150])\n",
+    "ascent.set_state_val('gam', [25, 0], units='deg')\n",
     "\n",
-    "p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))\n",
-    "p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))\n",
-    "p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))\n",
-    "p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')\n",
+    "descent.set_time_val(initial=10.0, duration=10.0)\n",
+    "\n",
+    "descent.set_state_val('r', [100, 200])\n",
+    "descent.set_state_val('h', [100, 0])\n",
+    "descent.set_state_val('v', [150, 200])\n",
+    "descent.set_state_val('gam', [0, -45], units='deg')\n",
     "\n",
     "#####################################################\n",
     "# Run the optimization and final explicit simulation\n",
@@ -561,7 +560,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.11.4"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/multibranch_trajectory/multibranch_trajectory.ipynb b/docs/dymos_book/examples/multibranch_trajectory/multibranch_trajectory.ipynb
index b99fa0fe6..659c44719 100644
--- a/docs/dymos_book/examples/multibranch_trajectory/multibranch_trajectory.ipynb
+++ b/docs/dymos_book/examples/multibranch_trajectory/multibranch_trajectory.ipynb
@@ -431,17 +431,10 @@
     "\n",
     "prob.setup()\n",
     "\n",
-    "prob['traj.phase0.t_initial'] = 0\n",
-    "prob['traj.phase0.t_duration'] = 1.0*3600\n",
-    "\n",
-    "prob['traj.phase1.t_initial'] = 1.0*3600\n",
-    "prob['traj.phase1.t_duration'] = 1.0*3600\n",
-    "\n",
-    "prob['traj.phase1_bfail.t_initial'] = 1.0*3600\n",
-    "prob['traj.phase1_bfail.t_duration'] = 1.0*3600\n",
-    "\n",
-    "prob['traj.phase1_mfail.t_initial'] = 1.0*3600\n",
-    "prob['traj.phase1_mfail.t_duration'] = 1.0*3600\n",
+    "phase0.set_time_val(initial=0.0, duration=3600)\n",
+    "phase1.set_time_val(initial=3600.0, duration=3600.0)\n",
+    "phase1_bfail.set_time_val(initial=3600.0, duration=3600.0)\n",
+    "phase1_mfail.set_time_val(initial=3600.0, duration=3600.0)\n",
     "\n",
     "prob.set_solver_print(level=0)\n",
     "dm.run_problem(prob)\n",
@@ -544,7 +537,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/racecar/racecar.ipynb b/docs/dymos_book/examples/racecar/racecar.ipynb
index e7d0a31df..b0fa201ca 100644
--- a/docs/dymos_book/examples/racecar/racecar.ipynb
+++ b/docs/dymos_book/examples/racecar/racecar.ipynb
@@ -379,21 +379,21 @@
     "\n",
     "# States\n",
     "# Nonzero velocity to avoid division by zero errors\n",
-    "p.set_val('traj.phase0.states:V', phase.interp('V', [20, 20]), units='m/s')\n",
+    "phase.set_state_val('V', 20.0, units='m/s')\n",
     "# All other states start at 0\n",
-    "p.set_val('traj.phase0.states:lambda', phase.interp('lambda', [0.0, 0.0]), units='rad')\n",
-    "p.set_val('traj.phase0.states:omega', phase.interp('omega', [0.0, 0.0]), units='rad/s')\n",
-    "p.set_val('traj.phase0.states:alpha', phase.interp('alpha', [0.0, 0.0]), units='rad')\n",
-    "p.set_val('traj.phase0.states:ax', phase.interp('ax', [0.0, 0.0]), units='m/s**2')\n",
-    "p.set_val('traj.phase0.states:ay', phase.interp('ay', [0.0, 0.0]), units='m/s**2')\n",
-    "p.set_val('traj.phase0.states:n', phase.interp('n', [0.0, 0.0]), units='m')\n",
+    "phase.set_state_val('lambda', 0.0, units='rad')\n",
+    "phase.set_state_val('omega', 0.0, units='rad/s')\n",
+    "phase.set_state_val('alpha', 0.0, units='rad')\n",
+    "phase.set_state_val('ax', 0.0, units='m/s**2')\n",
+    "phase.set_state_val('ay', 0.0, units='m/s**2')\n",
+    "phase.set_state_val('n', 0.0, units='m')\n",
     "# initial guess for what the final time should be\n",
-    "p.set_val('traj.phase0.states:t', phase.interp('t', [0.0, 100.0]), units='s')\n",
+    "phase.set_state_val('t', [0.0, 100.0], units='s')\n",
     "\n",
     "# Controls\n",
     "# a small amount of thrust can speed up convergence\n",
-    "p.set_val('traj.phase0.controls:delta', phase.interp('delta', [0.0, 0.0]), units='rad')\n",
-    "p.set_val('traj.phase0.controls:thrust', phase.interp('thrust', [0.1, 0.1]), units=None)\n",
+    "phase.set_control_val('delta', 0.0, units='rad')\n",
+    "phase.set_control_val('thrust', 0.1, units=None)\n",
     "\n",
     "dm.run_problem(p, run_driver=True)\n",
     "print('Optimization finished')\n",
@@ -629,7 +629,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/reentry/reentry.ipynb b/docs/dymos_book/examples/reentry/reentry.ipynb
index 4ff901bf8..574e54d92 100644
--- a/docs/dymos_book/examples/reentry/reentry.ipynb
+++ b/docs/dymos_book/examples/reentry/reentry.ipynb
@@ -667,26 +667,17 @@
     "\n",
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.phase0.t_initial', 0, units='s')\n",
-    "p.set_val('traj.phase0.t_duration', 2000, units='s')\n",
-    "\n",
-    "p.set_val('traj.phase0.states:h',\n",
-    "          phase0.interp('h', [260000, 80000]), units='ft')\n",
-    "p.set_val('traj.phase0.states:gamma',\n",
-    "          phase0.interp('gamma', [-1, -5]), units='deg')\n",
-    "p.set_val('traj.phase0.states:phi',\n",
-    "          phase0.interp('phi', [0, 75]), units='deg')\n",
-    "p.set_val('traj.phase0.states:psi',\n",
-    "          phase0.interp('psi', [90, 10]), units='deg')\n",
-    "p.set_val('traj.phase0.states:theta',\n",
-    "          phase0.interp('theta', [0, 25]), units='deg')\n",
-    "p.set_val('traj.phase0.states:v',\n",
-    "          phase0.interp('v', [25600, 2500]), units='ft/s')\n",
-    "\n",
-    "p.set_val('traj.phase0.controls:alpha',\n",
-    "          phase0.interp('alpha', ys=[17.4, 17.4]), units='deg')\n",
-    "p.set_val('traj.phase0.controls:beta',\n",
-    "          phase0.interp('beta', ys=[-75, 0]), units='deg')\n",
+    "phase0.set_time_val(initial=0, duration=2000, units='s')\n",
+    "\n",
+    "phase0.set_state_val('h', [260000, 80000], units='ft')\n",
+    "phase0.set_state_val('gamma', [-1, -5], units='deg')\n",
+    "phase0.set_state_val('phi', [0, 75], units='deg')\n",
+    "phase0.set_state_val('psi', [90, 10], units='deg')\n",
+    "phase0.set_state_val('theta', [0, 25], units='deg')\n",
+    "phase0.set_state_val('v', [25600, 2500], units='ft/s')\n",
+    "\n",
+    "phase0.set_control_val('alpha', 17.4, units='deg')\n",
+    "phase0.set_control_val('beta', [-75, 0], units='deg')\n",
     "\n",
     "# Run the driver\n",
     "dm.run_problem(p, simulate=True)"
diff --git a/docs/dymos_book/examples/robertson_problem/robertson_problem.ipynb b/docs/dymos_book/examples/robertson_problem/robertson_problem.ipynb
index d416a0cf9..73a7e287c 100644
--- a/docs/dymos_book/examples/robertson_problem/robertson_problem.ipynb
+++ b/docs/dymos_book/examples/robertson_problem/robertson_problem.ipynb
@@ -240,7 +240,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -297,12 +296,11 @@
     "    #\n",
     "    # Set the initial values\n",
     "    #\n",
-    "    p['traj.phase0.t_initial'] = 0.0\n",
-    "    p['traj.phase0.t_duration'] = t_final\n",
     "\n",
-    "    p.set_val('traj.phase0.initial_states:x0', 1.0)\n",
-    "    p.set_val('traj.phase0.initial_states:y0', 0.0)\n",
-    "    p.set_val('traj.phase0.initial_states:z0', 0.0)\n",
+    "    phase.set_time_val(initial=0.0, duration=t_final)\n",
+    "    phase.set_state_val('x0', [1.0, 0.7])\n",
+    "    phase.set_state_val('y0', [0.0, 1e-5])\n",
+    "    phase.set_state_val('z0', [0.0, 0.3])\n",
     "\n",
     "    return p\n"
    ]
diff --git a/docs/dymos_book/examples/ssto_earth/ssto_earth.ipynb b/docs/dymos_book/examples/ssto_earth/ssto_earth.ipynb
index 9de6ed22a..3c7f98003 100644
--- a/docs/dymos_book/examples/ssto_earth/ssto_earth.ipynb
+++ b/docs/dymos_book/examples/ssto_earth/ssto_earth.ipynb
@@ -323,14 +323,13 @@
     "#\n",
     "p.setup(check=True)\n",
     "\n",
-    "p.set_val('traj.phase0.t_initial', 0.0)\n",
-    "p.set_val('traj.phase0.t_duration', 150.0)\n",
-    "p.set_val('traj.phase0.states:x', phase.interp('x', [0, 1.15E5]))\n",
-    "p.set_val('traj.phase0.states:y', phase.interp('y', [0, 1.85E5]))\n",
-    "p.set_val('traj.phase0.states:vy', phase.interp('vy', [1.0E-6, 0]))\n",
-    "p.set_val('traj.phase0.states:m', phase.interp('m', [117000, 1163]))\n",
-    "p.set_val('traj.phase0.controls:theta', phase.interp('theta', [1.5, -0.76]))\n",
-    "p.set_val('traj.phase0.parameters:thrust', 2.1, units='MN')\n",
+    "phase.set_time_val(initial=0.0, duration=150.0)\n",
+    "phase.set_state_val('x', [0, 1.15E5])\n",
+    "phase.set_state_val('y', [0, 1.85E5])\n",
+    "phase.set_state_val('vy', [1.0E-6, 0])\n",
+    "phase.set_state_val('m', [117000, 1163])\n",
+    "phase.set_control_val('theta', [1.5, -0.76])\n",
+    "phase.set_parameter_val('thrust', 2.1, units='MN')\n",
     "\n",
     "#\n",
     "# Solve the Problem\n",
@@ -448,7 +447,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.5"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/ssto_moon_linear_tangent/ssto_moon_linear_tangent.ipynb b/docs/dymos_book/examples/ssto_moon_linear_tangent/ssto_moon_linear_tangent.ipynb
index b960506a7..3b6713ee6 100644
--- a/docs/dymos_book/examples/ssto_moon_linear_tangent/ssto_moon_linear_tangent.ipynb
+++ b/docs/dymos_book/examples/ssto_moon_linear_tangent/ssto_moon_linear_tangent.ipynb
@@ -348,15 +348,14 @@
     "\n",
     "p.setup(check=True)\n",
     "\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 500.0\n",
-    "p['traj.phase0.states:x'] = phase.interp('x', [0, 350000.0])\n",
-    "p['traj.phase0.states:y'] = phase.interp('y', [0, 185000.0])\n",
-    "p['traj.phase0.states:vx'] = phase.interp('vx', [0, 1627.0])\n",
-    "p['traj.phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])\n",
-    "p['traj.phase0.states:m'] = phase.interp('m', [50000, 50000])\n",
-    "p['traj.phase0.parameters:a_ctrl'] = -0.01\n",
-    "p['traj.phase0.parameters:b_ctrl'] = 3.0\n",
+    "phase.set_time_val(initial=0.0, duration=500.0)\n",
+    "phase.set_state_val('x', [0, 350000.0])\n",
+    "phase.set_state_val('y', [0, 185000.0])\n",
+    "phase.set_state_val('vx', [0, 1627.0])\n",
+    "phase.set_state_val('vy', [1.0E-6, 0.0])\n",
+    "phase.set_state_val('m', 50000)\n",
+    "phase.set_parameter_val('a_ctrl', -0.01)\n",
+    "phase.set_parameter_val('b_ctrl', 3.0)\n",
     "\n",
     "dm.run_problem(p, simulate=True)"
    ]
@@ -497,7 +496,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/ssto_moon_polynomial_controls/ssto_moon_polynomial_controls.ipynb b/docs/dymos_book/examples/ssto_moon_polynomial_controls/ssto_moon_polynomial_controls.ipynb
index 974bb938a..3bda1da63 100644
--- a/docs/dymos_book/examples/ssto_moon_polynomial_controls/ssto_moon_polynomial_controls.ipynb
+++ b/docs/dymos_book/examples/ssto_moon_polynomial_controls/ssto_moon_polynomial_controls.ipynb
@@ -333,14 +333,13 @@
     "#\n",
     "# Assign initial guesses for the independent variables in the problem.\n",
     "#\n",
-    "p['traj.phase0.t_initial'] = 0.0\n",
-    "p['traj.phase0.t_duration'] = 500.0\n",
-    "p['traj.phase0.states:x'] = phase.interp('x', [0, 350000.0])\n",
-    "p['traj.phase0.states:y'] = phase.interp('y', [0, 185000.0])\n",
-    "p['traj.phase0.states:vx'] = phase.interp('vx', [0, 1627.0])\n",
-    "p['traj.phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])\n",
-    "p['traj.phase0.states:m'] = phase.interp('m', [50000, 50000])\n",
-    "p['traj.phase0.polynomial_controls:tan_theta'] = [[0.5 * np.pi], [0.0]]\n",
+    "phase.set_time_val(initial=0.0, duration=500.0)\n",
+    "phase.set_state_val('x', [0, 350000.0])\n",
+    "phase.set_state_val('y', [0, 185000.0])\n",
+    "phase.set_state_val('vx', [0, 1627.0])\n",
+    "phase.set_state_val('vy', [1.0E-6, 0.0])\n",
+    "phase.set_state_val('m', 50000)\n",
+    "phase.set_polynomial_control_val('tan_theta', [[0.5 * np.pi], [0.0]])\n",
     "\n",
     "#\n",
     "# Solve the problem.\n",
@@ -460,7 +459,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/vanderpol/vanderpol.ipynb b/docs/dymos_book/examples/vanderpol/vanderpol.ipynb
index fe66eb2b5..953271139 100644
--- a/docs/dymos_book/examples/vanderpol/vanderpol.ipynb
+++ b/docs/dymos_book/examples/vanderpol/vanderpol.ipynb
@@ -332,14 +332,13 @@
     "    # setup the problem\n",
     "    p.setup(check=True)\n",
     "\n",
-    "    p['traj.phase0.t_initial'] = 0.0\n",
-    "    p['traj.phase0.t_duration'] = t_final\n",
+    "    phase.set_time_val(0.0, t_final)\n",
     "\n",
     "    # add a linearly interpolated initial guess for the state and control curves\n",
-    "    p['traj.phase0.states:x0'] = phase.interp('x0', [0, 0])\n",
-    "    p['traj.phase0.states:x1'] = phase.interp('x1', [1, 0])\n",
-    "    p['traj.phase0.states:J'] = phase.interp('J', [0, 1])\n",
-    "    p['traj.phase0.controls:u'] = phase.interp('u', [0, 0])\n",
+    "    phase.set_state_val('x0', [1, 0])\n",
+    "    phase.set_state_val('x0', [1, 0])\n",
+    "    phase.set_state_val('x0', [0, 1])\n",
+    "    phase.set_control_val('u', -0.75)\n",
     "\n",
     "    return p"
    ]
@@ -559,7 +558,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/docs/dymos_book/examples/water_rocket/water_rocket.ipynb b/docs/dymos_book/examples/water_rocket/water_rocket.ipynb
index 4ccafcbd2..8cb2bfcb0 100644
--- a/docs/dymos_book/examples/water_rocket/water_rocket.ipynb
+++ b/docs/dymos_book/examples/water_rocket/water_rocket.ipynb
@@ -98,7 +98,6 @@
    ]
   },
   {
-   "attachments": {},
    "cell_type": "markdown",
    "metadata": {},
    "source": [
@@ -162,19 +161,19 @@
    ]
   },
   {
-    "cell_type": "code",
-    "execution_count": null,
-    "metadata": {
-     "tags": [
-      "active-ipynb",
-      "remove-input",
-      "remove-output"
-     ]
-    },
-    "outputs": [],
-    "source": [
-     "%matplotlib inline"
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "tags": [
+     "active-ipynb",
+     "remove-input",
+     "remove-output"
     ]
+   },
+   "outputs": [],
+   "source": [
+    "%matplotlib inline"
+   ]
   },
   {
    "cell_type": "code",
@@ -619,7 +618,7 @@
     "p.model.linear_solver = om.DirectSolver()\n",
     "\n",
     "p.setup()\n",
-    "set_sane_initial_guesses(p, phases)\n",
+    "set_sane_initial_guesses(phases)\n",
     "\n",
     "dm.run_problem(p, run_driver=True, simulate=True)\n",
     "\n",
@@ -736,7 +735,7 @@
     "p.model.linear_solver = om.DirectSolver()\n",
     "\n",
     "p.setup()\n",
-    "set_sane_initial_guesses(p, phases)\n",
+    "set_sane_initial_guesses(phases)\n",
     "\n",
     "dm.run_problem(p, run_driver=True, simulate=True)\n",
     "\n",
@@ -831,6 +830,13 @@
     ":filter: docname in docnames\n",
     "```"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
@@ -858,7 +864,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.6"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/dymos/examples/finite_burn_orbit_raise/finite_burn_orbit_raise_problem.py b/dymos/examples/finite_burn_orbit_raise/finite_burn_orbit_raise_problem.py
index 3d02cb01b..d6d9e9a92 100644
--- a/dymos/examples/finite_burn_orbit_raise/finite_burn_orbit_raise_problem.py
+++ b/dymos/examples/finite_burn_orbit_raise/finite_burn_orbit_raise_problem.py
@@ -242,58 +242,51 @@ def two_burn_orbit_raise_problem(transcription='gauss-lobatto', optimizer='SLSQP
     p.setup(check=True)
 
     # Set Initial Guesses
-    p.set_val('traj.parameters:c', val=1.5, units='DU/TU')
+    traj.set_parameter_val('c', val=1.5, units='DU/TU')
 
     burn1 = p.model.traj.phases.burn1
     burn2 = p.model.traj.phases.burn2
     coast = p.model.traj.phases.coast
 
     if burn1 in p.model.traj.phases._subsystems_myproc:
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]))
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [0.0, 0.0])
 
     if coast in p.model.traj.phases._subsystems_myproc:
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [0, 0]))
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+        coast.set_parameter_val('u1', 0)
 
     if burn2 in p.model.traj.phases._subsystems_myproc:
         if connected:
-            p.set_val('traj.burn2.t_initial', val=7.0)
-            p.set_val('traj.burn2.t_duration', val=-1.75)
-
-            p.set_val('traj.burn2.states:r', val=burn2.interp('r', [r_target, 1]))
-            p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [4.0, 0.0]))
-            p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [0, 0]))
-            p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [np.sqrt(1 / r_target), 1]))
-            p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.2, 0.1]))
-            p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0., 0.1]))
-            p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [0, 0]))
+            burn2.set_time_val(initial=7.0, duration=-1.75)
+            burn2.set_state_val('r', [r_target, 1])
+            burn2.set_state_val('theta', [4, 0])
+            burn2.set_state_val('vr', [0, 0])
+            burn2.set_state_val('vt', [np.sqrt(1 / r_target), 1])
+            burn2.set_state_val('accel', [0.0, 0.1])
+            burn2.set_state_val('deltav', [0.2, 0.1])
+            burn2.set_control_val('u1', [0, 0])
 
         else:
-            p.set_val('traj.burn2.t_initial', val=5.25)
-            p.set_val('traj.burn2.t_duration', val=1.75)
-
-            p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1, r_target]))
-            p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [0, 4.0]))
-            p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [0, 0]))
-            p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / r_target)]))
-            p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-            p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-            p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [0, 0]))
+            burn2.set_time_val(initial=5.25, duration=1.75)
+            burn2.set_state_val('r', [1, r_target])
+            burn2.set_state_val('theta', [0, 4])
+            burn2.set_state_val('vr', [0, 0])
+            burn2.set_state_val('vt', [1, np.sqrt(1 / r_target)])
+            burn2.set_state_val('accel', [0.1, 0.0])
+            burn2.set_state_val('deltav', [0.1, 0.2])
+            burn2.set_control_val('u1', [0, 0])
 
     if run_driver or simulate:
         dm.run_problem(p, run_driver=run_driver, simulate=simulate, restart=restart, make_plots=True,
diff --git a/dymos/examples/robertson_problem/doc/robertson_ode.py b/dymos/examples/robertson_problem/robertson_ode.py
similarity index 100%
rename from dymos/examples/robertson_problem/doc/robertson_ode.py
rename to dymos/examples/robertson_problem/robertson_ode.py
diff --git a/dymos/examples/robot_arm/robot_arm_ode.py b/dymos/examples/robot_arm/robot_arm_ode.py
index e3e183a17..a08c52233 100644
--- a/dymos/examples/robot_arm/robot_arm_ode.py
+++ b/dymos/examples/robot_arm/robot_arm_ode.py
@@ -48,7 +48,6 @@ def setup(self):
         self.declare_partials(of='x4_dot', wrt='x2', rows=r, cols=c)
         self.declare_partials(of='x4_dot', wrt='x4', rows=r, cols=c, val=1.0)
         self.declare_partials(of='x4_dot', wrt='u1', rows=r, cols=c)
-        self.declare_partials(of='x4_dot', wrt='u2', rows=r, cols=c, val=0.0)
 
         self.declare_partials(of='x5_dot', wrt='x0', rows=r, cols=c)
         self.declare_partials(of='x5_dot', wrt='x5', rows=r, cols=c, val=1.0)
diff --git a/dymos/examples/vanderpol/vanderpol_dymos.py b/dymos/examples/vanderpol/vanderpol_dymos.py
index 26612dbfd..858527739 100644
--- a/dymos/examples/vanderpol/vanderpol_dymos.py
+++ b/dymos/examples/vanderpol/vanderpol_dymos.py
@@ -78,14 +78,13 @@ def vanderpol(transcription='gauss-lobatto', num_segments=40, transcription_orde
     # setup the problem
     p.setup(check=True, force_alloc_complex=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = t_final
+    phase.set_time_val(0.0, t_final)
 
     # add a linearly interpolated initial guess for the state and control curves
-    p['traj.phase0.states:x0'] = phase.interp('x0', [1, 0])
-    p['traj.phase0.states:x1'] = phase.interp('x1', [1, 0])
-    p['traj.phase0.states:J'] = phase.interp('J', [0, 1])
-    p['traj.phase0.controls:u'] = phase.interp('u', [-0.75, -0.75])
+    phase.set_state_val('x0', [1, 0])
+    phase.set_state_val('x0', [1, 0])
+    phase.set_state_val('x0', [0, 1])
+    phase.set_control_val('u', -0.75)
 
     return p
 
diff --git a/dymos/examples/water_rocket/phases.py b/dymos/examples/water_rocket/phases.py
index ffd0fc6b9..43cd63ef6 100644
--- a/dymos/examples/water_rocket/phases.py
+++ b/dymos/examples/water_rocket/phases.py
@@ -162,51 +162,31 @@ def new_water_rocket_trajectory(objective):
                   'descent': descent}
 
 
-def set_sane_initial_guesses(problem, phases):
-    p = problem
-    # Set Initial Guesses
-    p.set_val('traj.propelled_ascent.t_initial', 0.0)
-    p.set_val('traj.propelled_ascent.t_duration', 0.3)
+def set_sane_initial_guesses(phases):
+    propelled_ascent = phases['propelled_ascent']
+    ballistic_ascent = phases['ballistic_ascent']
+    descent = phases['descent']
 
-    p.set_val('traj.propelled_ascent.states:r',
-              phases['propelled_ascent'].interp('r', [0, 3]))
-    p.set_val('traj.propelled_ascent.states:h',
-              phases['propelled_ascent'].interp('h', [0, 10]))
+    # Set Initial Guesses
+    propelled_ascent.set_time_val(initial=0.0, duration=0.3)
+    propelled_ascent.set_state_val('r', [0, 3])
+    propelled_ascent.set_state_val('h', [0, 10])
     # Set initial value for velocity as non-zero to avoid undefined EOM
-    p.set_val('traj.propelled_ascent.states:v',
-              phases['propelled_ascent'].interp('v', [0.1, 100]))
-    p.set_val('traj.propelled_ascent.states:gam',
-              phases['propelled_ascent'].interp('gam', [80, 80]),
-              units='deg')
-    p.set_val('traj.propelled_ascent.states:V_w',
-              phases['propelled_ascent'].interp('V_w', [9, 0]),
-              units='L')
-    p.set_val('traj.propelled_ascent.states:p',
-              phases['propelled_ascent'].interp('p', [6.5, 3.5]),
-              units='bar')
-
-    p.set_val('traj.ballistic_ascent.t_initial', 0.3)
-    p.set_val('traj.ballistic_ascent.t_duration', 5)
-
-    p.set_val('traj.ballistic_ascent.states:r',
-              phases['ballistic_ascent'].interp('r', [0, 10]))
-    p.set_val('traj.ballistic_ascent.states:h',
-              phases['ballistic_ascent'].interp('h', [10, 100]))
-    p.set_val('traj.ballistic_ascent.states:v',
-              phases['ballistic_ascent'].interp('v', [60, 20]))
-    p.set_val('traj.ballistic_ascent.states:gam',
-              phases['ballistic_ascent'].interp('gam', [80, 0]),
-              units='deg')
-
-    p.set_val('traj.descent.t_initial', 10.0)
-    p.set_val('traj.descent.t_duration', 10.0)
-
-    p.set_val('traj.descent.states:r',
-              phases['descent'].interp('r', [10, 20]))
-    p.set_val('traj.descent.states:h',
-              phases['descent'].interp('h', [10, 0]))
-    p.set_val('traj.descent.states:v',
-              phases['descent'].interp('v', [20, 60]))
-    p.set_val('traj.descent.states:gam',
-              phases['descent'].interp('gam', [0, -45]),
-              units='deg')
+    propelled_ascent.set_state_val('v', [0.1, 100])
+    propelled_ascent.set_state_val('gam', [80, 80], units='deg')
+    propelled_ascent.set_state_val('V_w', [9, 0], units='L')
+    propelled_ascent.set_state_val('p', [6.5, 3.5], units='bar')
+
+    ballistic_ascent.set_time_val(initial=0.3, duration=5)
+
+    ballistic_ascent.set_state_val('r', [0, 10])
+    ballistic_ascent.set_state_val('h', [10, 100])
+    ballistic_ascent.set_state_val('v', [60, 20])
+    ballistic_ascent.set_state_val('gam', [80, 0], units='deg')
+
+    descent.set_time_val(initial=10, duration=10)
+
+    descent.set_state_val('r', [10, 20])
+    descent.set_state_val('h', [10, 0])
+    descent.set_state_val('v', [20, 60])
+    descent.set_state_val('gam', [0, -45], units='deg')
diff --git a/dymos/phase/phase.py b/dymos/phase/phase.py
index 8684f6211..e9a7b9259 100644
--- a/dymos/phase/phase.py
+++ b/dymos/phase/phase.py
@@ -24,7 +24,7 @@
 
 from ..transcriptions.transcription_base import TranscriptionBase
 from ..transcriptions.grid_data import GaussLobattoGrid, RadauGrid, UniformGrid, BirkhoffGrid
-from ..transcriptions import ExplicitShooting, GaussLobatto, Radau
+from ..transcriptions import ExplicitShooting, GaussLobatto, Radau, Birkhoff
 from ..utils.indexing import get_constraint_flat_idxs
 from ..utils.introspection import configure_time_introspection, _configure_constraint_introspection, \
     configure_controls_introspection, configure_parameters_introspection, \
@@ -1854,6 +1854,145 @@ def set_time_options(self, units=_unspecified, fix_initial=_unspecified,
         if name is not _unspecified:
             self.time_options['name'] = name
 
+    def set_time_val(self, initial=None, duration=None, units=None):
+        """
+        Set the values for initial time and the duration of the phase.
+
+        Parameters
+        ----------
+        initial : float or None
+            Value for the initial time.
+        duration : float or None
+            Value for the phase duration.
+        units : str or None
+            Units of the time. If none are specified, the default units are used.
+        """
+        if units is None:
+            units = self.time_options['units']
+        if initial is not None:
+            self.set_val('t_initial', initial, units=units)
+        if duration is not None:
+            self.set_val('t_duration', duration, units=units)
+
+    def set_state_val(self, name, vals=None, time_vals=None,
+                      units=None, interpolation_kind='linear'):
+        """
+        Set the necessary input values for state as appropriate for the specified transcription.
+
+        Parameters
+        ----------
+        name : str
+            Name of the variable. This should be a state variable.
+        vals : ndarray or Sequence or float or None
+            Array of state values.
+        time_vals :  ndarray or Sequence or None
+            Array of integration variable values.
+        units : str, optional
+            The units of the state values specified.
+            If None, use the units associated with the target.
+            If provided, must be compatible with the target units.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+        """
+        transcription = self.options['transcription']
+        input_data_to_set = transcription._phase_set_state_val(self, name,
+                                                               vals, time_vals,
+                                                               interpolation_kind)
+        if units is None:
+            units = self.state_options[name]['units']
+        for var, value in input_data_to_set.items():
+            self.set_val(var, value, units=units)
+
+    def set_control_val(self, name, vals=None, time_vals=None,
+                        units=None, interpolation_kind='linear'):
+        """
+        Set the control values as appropriate.
+
+        Parameters
+        ----------
+        name : str
+            Name of the variable. This should be a control variable.
+        vals : ndarray or Sequence or None
+            Array of state values.
+        time_vals :  ndarray or Sequence or None
+            Array of integration variable values.
+        units : str, optional
+            The units of the state values specified.
+            If None, use the units associated with the target.
+            If provided, must be compatible with the target units.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+        """
+        if np.isscalar(vals):
+            val = vals
+        else:
+            val = self.interp(name, ys=vals, xs=time_vals, nodes='control_input', kind=interpolation_kind)
+        if units is None:
+            units = self.control_options[name]['units']
+        self.set_val(f'controls:{name}', val=val, units=units)
+
+    def set_polynomial_control_val(self, name, vals=None, time_vals=None,
+                                   units=None, interpolation_kind='linear'):
+        """
+        Set the polynomial control values as appropriate.
+
+        Parameters
+        ----------
+        name : str
+            Name of the variable. This should be a polynomial control variable.
+        vals : ndarray or Sequence or None
+            Array of state values.
+        time_vals :  ndarray or Sequence or None
+            Array of integration variable values.
+        units : str, optional
+            The units of the state values specified.
+            If None, use the units associated with the target.
+            If provided, must be compatible with the target units.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+        """
+        if np.isscalar(vals):
+            val = vals
+        else:
+            val = self.interp(name, ys=vals, xs=time_vals, kind=interpolation_kind)
+        if units is None:
+            units = self.polynomial_control_options[name]['units']
+        self.set_val(f'polynomial_controls:{name}', val=val, units=units)
+
+    def set_parameter_val(self, name, val=None, units=None):
+        """
+        Set the parameter values.
+
+        Parameters
+        ----------
+        name : str
+            Name of the variable. This should be a parameter variable.
+        val : ndarray or Sequence or None
+            Array of state values.
+        units : str, optional
+            The units of the state values specified.
+            If None, use the units associated with the target.
+            If provided, must be compatible with the target units.
+        """
+        if units is None:
+            units = self.parameter_options[name]['units']
+        self.set_val(f'parameters:{name}', val=val, units=units)
+
     def set_duration_balance(self, name, val=0.0, index=None, units=None, mult_val=None, normalize=False):
         """
         Adds a condition for the duration of the phase. This is satisfied using a nonlinear solver.
@@ -2395,7 +2534,7 @@ def get_simulation_phase(self, times_per_seg=_unspecified, method=_unspecified,
                 isinstance(self_tx.grid_data, RadauGrid) or isinstance(self_tx.grid_data, BirkhoffGrid):
             grid = self_tx.grid_data
         else:
-            raise RuntimeError(f'Unexpected grid class for {phase_tx.grid_data}. Only phases with GaussLobatto '
+            raise RuntimeError(f'Unexpected grid class for {self_tx.grid_data}. Only phases with GaussLobatto '
                                f'or Radau grids can be simulated.')
 
         if _times_per_seg is None:
diff --git a/dymos/trajectory/trajectory.py b/dymos/trajectory/trajectory.py
index 0f4c12db1..de75e851c 100644
--- a/dymos/trajectory/trajectory.py
+++ b/dymos/trajectory/trajectory.py
@@ -288,6 +288,25 @@ def add_parameter(self, name, units=_unspecified, val=_unspecified, desc=_unspec
                                    upper=upper, scaler=scaler, adder=adder, ref0=ref0, ref=ref, shape=shape,
                                    dynamic=dynamic, static_target=static_target)
 
+    def set_parameter_val(self, name, val=None, units=None):
+        """
+        Set the parameter values.
+
+        Parameters
+        ----------
+        name : str
+            Name of the variable. This should be a parameter variable.
+        val : ndarray or Sequence or None
+            Array of state values.
+        units : str, optional
+            The units of the state values specified.
+            If None, use the units associated with the target.
+            If provided, must be compatible with the target units.
+        """
+        if units is None:
+            units = self.parameter_options[name]['units']
+        self.set_val(f'parameters:{name}', val=val, units=units)
+
     def _setup_parameters(self):
         """
         Adds an IndepVarComp if necessary and issues appropriate connections based
diff --git a/dymos/transcriptions/explicit_shooting/explicit_shooting.py b/dymos/transcriptions/explicit_shooting/explicit_shooting.py
index 8bcf7b77c..c5d366773 100644
--- a/dymos/transcriptions/explicit_shooting/explicit_shooting.py
+++ b/dymos/transcriptions/explicit_shooting/explicit_shooting.py
@@ -977,3 +977,40 @@ def _get_timeseries_var_source(self, var, output_name, phase):
         meta['shape'] = src_shape
 
         return meta
+
+    def _phase_set_state_val(self, phase, name, vals, time_vals=None, interpolation_kind=None):
+        """
+        Method to interpolate the provided input and return the variables that need to be set
+        along with their appropriate value.
+
+        Parameters
+        ----------
+        phase : dymos.Phase
+            The phase to which this transcription applies.
+        name : str
+            The name of the phase variable to be set.
+        vals : ndarray or Sequence or float
+            Array of control/state/parameter values.
+        time_vals : ndarray or Sequence or None
+            Array of integration variable values.
+        interpolation_kind : str or None
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+
+        Returns
+        -------
+        input_data : dict
+            Dict containing the values that need to be set in the phase
+
+        """
+        if np.isscalar(vals):
+            val = vals
+        else:
+            val = vals[0]
+        input_data = {f'initial_states:{name}': val}
+
+        return input_data
diff --git a/dymos/transcriptions/pseudospectral/birkhoff.py b/dymos/transcriptions/pseudospectral/birkhoff.py
index 3cfbdc693..6e1ffbbed 100644
--- a/dymos/transcriptions/pseudospectral/birkhoff.py
+++ b/dymos/transcriptions/pseudospectral/birkhoff.py
@@ -882,3 +882,47 @@ def _requires_continuity_constraints(self, phase):
         any_rate_continuity = any_rate_continuity and num_seg > 1
 
         return any_state_continuity, any_control_continuity, any_rate_continuity
+
+    def _phase_set_state_val(self, phase, name, vals, time_vals, interpolation_kind):
+        """
+        Method to interpolate the provided input and return the variables that need to be set
+        along with their appropriate value.
+
+        Parameters
+        ----------
+        phase : dymos.Phase
+            The phase to which this transcription applies.
+        name : str
+            The name of the phase variable to be set.
+        vals : ndarray or Sequence or float
+            Array of control/state/parameter values.
+        time_vals : ndarray or Sequence or None
+            Array of integration variable values.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+
+        Returns
+        -------
+        input_data : dict
+            Dict containing the values that need to be set in the phase
+
+        """
+        input_data = {}
+        if np.isscalar(vals):
+            input_data[f'states:{name}'] = vals
+            input_data[f'initial_states:{name}'] = vals
+            input_data[f'final_states:{name}'] = vals
+        else:
+            interp_vals = phase.interp(name, vals, time_vals,
+                                       nodes='state_input',
+                                       kind=interpolation_kind)
+            input_data[f'states:{name}'] = interp_vals
+            input_data[f'initial_states:{name}'] = vals[0]
+            input_data[f'final_states:{name}'] = vals[-1]
+
+        return input_data
diff --git a/dymos/transcriptions/pseudospectral/pseudospectral_base.py b/dymos/transcriptions/pseudospectral/pseudospectral_base.py
index 411440065..5c1e9a05b 100644
--- a/dymos/transcriptions/pseudospectral/pseudospectral_base.py
+++ b/dymos/transcriptions/pseudospectral/pseudospectral_base.py
@@ -672,3 +672,44 @@ def _get_num_timeseries_nodes(self):
             The number of nodes in the default timeseries for this transcription.
         """
         return self.grid_data.num_nodes
+
+    def _phase_set_state_val(self, phase, name, vals, time_vals, interpolation_kind):
+        """
+        Method to interpolate the provided input and return the variables that need to be set
+        along with their appropriate value.
+
+        Parameters
+        ----------
+        phase : dymos.Phase
+            The phase to which this transcription applies.
+        name : str
+            The name of the phase variable to be set.
+        vals : ndarray or Sequence or float
+            Array of control/state/parameter values.
+        time_vals : ndarray or Sequence or None
+            Array of integration variable values.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+
+        Returns
+        -------
+        input_data : dict
+            Dict containing the values that need to be set in the phase
+
+        """
+
+        input_data = {}
+        if np.isscalar(vals):
+            interp_vals = vals
+        else:
+            interp_vals = phase.interp(name, vals, time_vals,
+                                       nodes='state_input',
+                                       kind=interpolation_kind)
+        input_data[f'states:{name}'] = interp_vals
+
+        return input_data
diff --git a/dymos/transcriptions/transcription_base.py b/dymos/transcriptions/transcription_base.py
index adb8f5f87..0f13ff99b 100644
--- a/dymos/transcriptions/transcription_base.py
+++ b/dymos/transcriptions/transcription_base.py
@@ -776,6 +776,38 @@ def _requires_continuity_constraints(self, phase):
         raise NotImplementedError(f'The transcription {self.__class__} does not provide an '
                                   f'implementation of _requires_continuity_constraints')
 
+    def _phase_set_state_val(self, phase, name, vals, times, interpolation_kind):
+        """
+        Method to interpolate the provided input and return the variables that need to be set
+        along with their appropriate value.
+
+        Parameters
+        ----------
+        phase : dymos.Phase
+            The phase to which this transcription applies.
+        name : str
+            The name of the phase variable to be set.
+        vals : ndarray or Sequence or float
+            Array of control/state/parameter values.
+        times : ndarray or Sequence or None
+            Array of integration variable values.
+        interpolation_kind : str
+            Specifies the kind of interpolation, as per the scipy.interpolate package.
+            One of ('linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
+            where 'zero', 'slinear', 'quadratic' and 'cubic' refer to a spline
+            interpolation of zeroth, first, second or third order) or as an
+            integer specifying the order of the spline interpolator to use.
+            Default is 'linear'.
+
+        Returns
+        -------
+        input_data : dict
+            Dict containing the values that need to be set in the phase
+
+        """
+        raise NotImplementedError(f'Transcription {self.__class__.__name__} does not implement method '
+                                  '_phase_set_val.')
+
     def _get_num_timeseries_nodes(self):
         """
         Returns the number of nodes in the default timeseries for this transcription.
diff --git a/dymos/utils/introspection.py b/dymos/utils/introspection.py
index 775fa29bc..2dc4dca4f 100644
--- a/dymos/utils/introspection.py
+++ b/dymos/utils/introspection.py
@@ -569,7 +569,7 @@ def configure_states_introspection(state_options, time_options, control_options,
                     options['shape'] = shape[1:]
 
             if any(['dymos.static_target' in meta['tags'] for meta in targets.values()]):
-                raise ValueError(f"State '{name}' cannot be connected to its targets because one "
+                raise ValueError(f"State '{state_name}' cannot be connected to its targets because one "
                                  f"or more targets are tagged with 'dymos.static_target'.")
 
         # 3. Attempt rate-source introspection


Test patch:
diff --git a/dymos/examples/aircraft_steady_flight/test/test_aircraft_cruise.py b/dymos/examples/aircraft_steady_flight/test/test_aircraft_cruise.py
index b19e9b68f..50d5d8f11 100644
--- a/dymos/examples/aircraft_steady_flight/test/test_aircraft_cruise.py
+++ b/dymos/examples/aircraft_steady_flight/test/test_aircraft_cruise.py
@@ -82,13 +82,12 @@ def test_cruise_results_gl(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 3600.0
-        p['phase0.states:range'] = phase.interp('range', (0, 1296.4))
-        p['phase0.states:mass_fuel'] = phase.interp('mass_fuel', (12236.594555, 1))
-        p['phase0.states:alt'] = 5.0
-        p['phase0.controls:mach'] = 0.8
-        p['phase0.controls:climb_rate'] = 0.0
+        phase.set_time_val(initial=0.0, duration=3600)
+        phase.set_state_val('range', (0, 1296.4))
+        phase.set_state_val('mass_fuel', (12236.594555, 1))
+        phase.set_state_val('alt', 5.0)
+        phase.set_control_val('mach', 0.8)
+        phase.set_control_val('climb_rate', 0.0)
 
         p['assumptions.S'] = 427.8
         p['assumptions.mass_empty'] = 0.15E6
@@ -176,13 +175,12 @@ def test_cruise_results_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 1.0 * 3600.0
-        p['phase0.states:range'] = phase.interp('range', (0, 1296.4))
-        p['phase0.states:mass_fuel'] = phase.interp('mass_fuel', (12236.594555, 0))
-        p['phase0.states:alt'] = 5.0
-        p['phase0.controls:mach'] = 0.8
-        p['phase0.controls:climb_rate'] = 0.0
+        phase.set_time_val(initial=0.0, duration=3600)
+        phase.set_state_val('range', (0, 1296.4))
+        phase.set_state_val('mass_fuel', (12236.594555, 0))
+        phase.set_state_val('alt', 5.0)
+        phase.set_control_val('mach', 0.8)
+        phase.set_control_val('climb_rate', 0.0)
 
         p['assumptions.S'] = 427.8
         p['assumptions.mass_empty'] = 0.15E6
diff --git a/dymos/examples/aircraft_steady_flight/test/test_ex_aircraft_steady_flight.py b/dymos/examples/aircraft_steady_flight/test/test_ex_aircraft_steady_flight.py
index d689797cc..9aa715da4 100644
--- a/dymos/examples/aircraft_steady_flight/test/test_ex_aircraft_steady_flight.py
+++ b/dymos/examples/aircraft_steady_flight/test/test_ex_aircraft_steady_flight.py
@@ -1,5 +1,6 @@
 import unittest
 
+import openmdao
 import openmdao.api as om
 from openmdao.utils.assert_utils import assert_near_equal, assert_no_approx_partials
 from openmdao.utils.testing_utils import use_tempdirs, require_pyoptsparse
@@ -8,6 +9,8 @@
 from dymos.utils.lgl import lgl
 from dymos.examples.aircraft_steady_flight.aircraft_ode import AircraftODE
 
+om_version = tuple([int(s) for s in openmdao.__version__.split('-')[0].split('.')])
+
 
 def ex_aircraft_steady_flight(transcription, optimizer='SLSQP', use_boundary_constraints=False,
                               show_output=True):
@@ -100,25 +103,11 @@ def ex_aircraft_steady_flight(transcription, optimizer='SLSQP', use_boundary_con
 
     p.setup()
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 5000.0
-    p['traj.phase0.states:range'] = phase.interp('range', (0, 800.0))
-    p['traj.phase0.states:mass_fuel'] = phase.interp('mass_fuel', (30000, 1e-3))
-    p['traj.phase0.states:alt'][:] = 10.0
-
-    # TODO: Make this unnecessary
-    if isinstance(transcription, dm.Birkhoff):
-
-        p['traj.phase0.initial_states:range'] = 0.0
-        p['traj.phase0.final_states:range'] = 724.0
-
-        p['traj.phase0.initial_states:mass_fuel'] = 30000
-        p['traj.phase0.final_states:mass_fuel'] = 1.0E-3
-
-        p['traj.phase0.initial_states:alt'] = 10.0
-        p['traj.phase0.final_states:alt'] = 10.0
-
-    p['traj.phase0.controls:mach'][:] = 0.8
+    phase.set_time_val(initial=0.0, duration=5000.0)
+    phase.set_state_val('range', (0, 724.0))
+    phase.set_state_val('mass_fuel', (30000, 1e-3))
+    phase.set_state_val('alt', 10.0)
+    phase.set_control_val('mach', 0.8)
 
     p['assumptions.S'] = 427.8
     p['assumptions.mass_empty'] = 0.15E6
@@ -143,6 +132,7 @@ def test_ex_aircraft_steady_flight_opt_radau(self):
                           726.85, tolerance=1.0E-2)
 
     @require_pyoptsparse(optimizer='IPOPT')
+    @unittest.skipIf(om_version < (3, 32, 2), 'Test requires OpenMDAO 3.32.2 or later')
     def test_ex_aircraft_steady_flight_opt_birkhoff(self):
 
         tx = dm.Birkhoff(grid=dm.BirkhoffGrid(num_nodes=50, grid_type='cgl'),
diff --git a/dymos/examples/balanced_field/doc/test_doc_balanced_field_length.py b/dymos/examples/balanced_field/doc/test_doc_balanced_field_length.py
index b86f81781..ac5d51027 100644
--- a/dymos/examples/balanced_field/doc/test_doc_balanced_field_length.py
+++ b/dymos/examples/balanced_field/doc/test_doc_balanced_field_length.py
@@ -207,37 +207,32 @@ def test_balanced_field_length_for_docs(self):
         #
         p.setup(check=True)
 
-        p.set_val('traj.br_to_v1.t_initial', 0)
-        p.set_val('traj.br_to_v1.t_duration', 35)
-        p.set_val('traj.br_to_v1.states:r', br_to_v1.interp('r', [0, 2500.0]))
-        p.set_val('traj.br_to_v1.states:v', br_to_v1.interp('v', [0, 100.0]))
-        p.set_val('traj.br_to_v1.parameters:alpha', 0, units='deg')
-
-        p.set_val('traj.v1_to_vr.t_initial', 35)
-        p.set_val('traj.v1_to_vr.t_duration', 35)
-        p.set_val('traj.v1_to_vr.states:r', v1_to_vr.interp('r', [2500, 300.0]))
-        p.set_val('traj.v1_to_vr.states:v', v1_to_vr.interp('v', [100, 110.0]))
-        p.set_val('traj.v1_to_vr.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rto.t_initial', 35)
-        p.set_val('traj.rto.t_duration', 35)
-        p.set_val('traj.rto.states:r', rto.interp('r', [2500, 5000.0]))
-        p.set_val('traj.rto.states:v', rto.interp('v', [110, 0]))
-        p.set_val('traj.rto.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rotate.t_initial', 70)
-        p.set_val('traj.rotate.t_duration', 5)
-        p.set_val('traj.rotate.states:r', rotate.interp('r', [1750, 1800.0]))
-        p.set_val('traj.rotate.states:v', rotate.interp('v', [80, 85.0]))
-        p.set_val('traj.rotate.polynomial_controls:alpha', 0.0, units='deg')
-
-        p.set_val('traj.climb.t_initial', 75)
-        p.set_val('traj.climb.t_duration', 15)
-        p.set_val('traj.climb.states:r', climb.interp('r', [5000, 5500.0]), units='ft')
-        p.set_val('traj.climb.states:v', climb.interp('v', [160, 170.0]), units='kn')
-        p.set_val('traj.climb.states:h', climb.interp('h', [0, 35.0]), units='ft')
-        p.set_val('traj.climb.states:gam', climb.interp('gam', [0, 5.0]), units='deg')
-        p.set_val('traj.climb.controls:alpha', 5.0, units='deg')
+        br_to_v1.set_time_val(initial=0.0, duration=35.0)
+        br_to_v1.set_state_val('r', [0, 2500.0])
+        br_to_v1.set_state_val('v', [0.0, 100.0])
+        br_to_v1.set_parameter_val('alpha', 0.0, units='deg')
+
+        v1_to_vr.set_time_val(initial=35.0, duration=35.0)
+        v1_to_vr.set_state_val('r', [2500, 300.0])
+        v1_to_vr.set_state_val('v', [100, 110.0])
+        v1_to_vr.set_parameter_val('alpha', 0.0, units='deg')
+
+        rto.set_time_val(initial=35.0, duration=35.0)
+        rto.set_state_val('r', [2500, 5000.0])
+        rto.set_state_val('v', [110, 0.0])
+        rto.set_parameter_val('alpha', 0.0, units='deg')
+
+        rotate.set_time_val(initial=70.0, duration=5.0)
+        rotate.set_state_val('r', [1750, 1800.0])
+        rotate.set_state_val('v', [80, 85.0])
+        rotate.set_polynomial_control_val('alpha', 0.0, units='deg')
+
+        climb.set_time_val(initial=75.0, duration=15.0)
+        climb.set_state_val('r', [5000, 5500.0], units='ft')
+        climb.set_state_val('v', [160, 170.0], units='kn')
+        climb.set_state_val('h', [0.0, 35.0], units='ft')
+        climb.set_state_val('gam', [0.0, 5.0], units='deg')
+        climb.set_control_val('alpha', 5.0, units='deg')
 
         dm.run_problem(p, run_driver=True, simulate=True, make_plots=True)
 
diff --git a/dymos/examples/balanced_field/test/test_balanced_field_func_comp.py b/dymos/examples/balanced_field/test/test_balanced_field_func_comp.py
index 9182b25b1..7e847333f 100644
--- a/dymos/examples/balanced_field/test/test_balanced_field_func_comp.py
+++ b/dymos/examples/balanced_field/test/test_balanced_field_func_comp.py
@@ -288,37 +288,32 @@ def _run_problem(self, tx):
         #
         p.setup(check=True)
 
-        p.set_val('traj.br_to_v1.t_initial', 0)
-        p.set_val('traj.br_to_v1.t_duration', 35)
-        p.set_val('traj.br_to_v1.states:r', br_to_v1.interp('r', [0, 2500.0]))
-        p.set_val('traj.br_to_v1.states:v', br_to_v1.interp('v', [0, 100.0]))
-        p.set_val('traj.br_to_v1.parameters:alpha', 0, units='deg')
-
-        p.set_val('traj.v1_to_vr.t_initial', 35)
-        p.set_val('traj.v1_to_vr.t_duration', 35)
-        p.set_val('traj.v1_to_vr.states:r', v1_to_vr.interp('r', [2500, 300.0]))
-        p.set_val('traj.v1_to_vr.states:v', v1_to_vr.interp('v', [100, 110.0]))
-        p.set_val('traj.v1_to_vr.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rto.t_initial', 35)
-        p.set_val('traj.rto.t_duration', 35)
-        p.set_val('traj.rto.states:r', rto.interp('r', [2500, 5000.0]))
-        p.set_val('traj.rto.states:v', rto.interp('v', [110, 0]))
-        p.set_val('traj.rto.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rotate.t_initial', 70)
-        p.set_val('traj.rotate.t_duration', 5)
-        p.set_val('traj.rotate.states:r', rotate.interp('r', [1750, 1800.0]))
-        p.set_val('traj.rotate.states:v', rotate.interp('v', [80, 85.0]))
-        p.set_val('traj.rotate.polynomial_controls:alpha', 0.0, units='deg')
-
-        p.set_val('traj.climb.t_initial', 75)
-        p.set_val('traj.climb.t_duration', 15)
-        p.set_val('traj.climb.states:r', climb.interp('r', [5000, 5500.0]), units='ft')
-        p.set_val('traj.climb.states:v', climb.interp('v', [160, 170.0]), units='kn')
-        p.set_val('traj.climb.states:h', climb.interp('h', [0, 35.0]), units='ft')
-        p.set_val('traj.climb.states:gam', climb.interp('gam', [0, 5.0]), units='deg')
-        p.set_val('traj.climb.controls:alpha', 5.0, units='deg')
+        br_to_v1.set_time_val(initial=0.0, duration=35.0)
+        br_to_v1.set_state_val('r', [0, 2500.0])
+        br_to_v1.set_state_val('v', [0.0001, 100.0])
+        br_to_v1.set_parameter_val('alpha', 0.0, units='deg')
+
+        v1_to_vr.set_time_val(initial=35.0, duration=35.0)
+        v1_to_vr.set_state_val('r', [2500, 300.0])
+        v1_to_vr.set_state_val('v', [100, 110.0])
+        v1_to_vr.set_parameter_val('alpha', 0.0, units='deg')
+
+        rto.set_time_val(initial=35.0, duration=1.0)
+        rto.set_state_val('r', [2500, 5000.0])
+        rto.set_state_val('v', [110, 0.0001])
+        rto.set_parameter_val('alpha', 0.0, units='deg')
+
+        rotate.set_time_val(initial=35.0, duration=5.0)
+        rotate.set_state_val('r', [1750, 1800.0])
+        rotate.set_state_val('v', [80, 85.0])
+        rotate.set_polynomial_control_val('alpha', 0.0, units='deg')
+
+        climb.set_time_val(initial=30.0, duration=20.0)
+        climb.set_state_val('r', [5000, 5500.0], units='ft')
+        climb.set_state_val('v', [160, 170.0], units='kn')
+        climb.set_state_val('h', [0.0, 35.0], units='ft')
+        climb.set_state_val('gam', [0.0, 5.0], units='deg')
+        climb.set_control_val('alpha', 5.0, units='deg')
 
         dm.run_problem(p, run_driver=True, simulate=True)
 
diff --git a/dymos/examples/balanced_field/test/test_balanced_field_length.py b/dymos/examples/balanced_field/test/test_balanced_field_length.py
index 30aa78bbd..a53bac10e 100644
--- a/dymos/examples/balanced_field/test/test_balanced_field_length.py
+++ b/dymos/examples/balanced_field/test/test_balanced_field_length.py
@@ -186,37 +186,32 @@ def _make_problem(self):
         #
         p.setup(check=True)
 
-        p.set_val('traj.br_to_v1.t_initial', 0)
-        p.set_val('traj.br_to_v1.t_duration', 35)
-        p.set_val('traj.br_to_v1.states:r', br_to_v1.interp('r', [0, 2500.0]))
-        p.set_val('traj.br_to_v1.states:v', br_to_v1.interp('v', [0.0001, 100.0]))
-        p.set_val('traj.br_to_v1.parameters:alpha', 0, units='deg')
-
-        p.set_val('traj.v1_to_vr.t_initial', 35)
-        p.set_val('traj.v1_to_vr.t_duration', 35)
-        p.set_val('traj.v1_to_vr.states:r', v1_to_vr.interp('r', [2500, 300.0]))
-        p.set_val('traj.v1_to_vr.states:v', v1_to_vr.interp('v', [100, 110.0]))
-        p.set_val('traj.v1_to_vr.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rto.t_initial', 35)
-        p.set_val('traj.rto.t_duration', 1)
-        p.set_val('traj.rto.states:r', rto.interp('r', [2500, 5000.0]))
-        p.set_val('traj.rto.states:v', rto.interp('v', [110, 0.0001]))
-        p.set_val('traj.rto.parameters:alpha', 0.0, units='deg')
-
-        p.set_val('traj.rotate.t_initial', 35)
-        p.set_val('traj.rotate.t_duration', 5)
-        p.set_val('traj.rotate.states:r', rotate.interp('r', [1750, 1800.0]))
-        p.set_val('traj.rotate.states:v', rotate.interp('v', [80, 85.0]))
-        p.set_val('traj.rotate.polynomial_controls:alpha', 0.0, units='deg')
-
-        p.set_val('traj.climb.t_initial', 30)
-        p.set_val('traj.climb.t_duration', 20)
-        p.set_val('traj.climb.states:r', climb.interp('r', [5000, 5500.0]), units='ft')
-        p.set_val('traj.climb.states:v', climb.interp('v', [160, 170.0]), units='kn')
-        p.set_val('traj.climb.states:h', climb.interp('h', [0, 35.0]), units='ft')
-        p.set_val('traj.climb.states:gam', climb.interp('gam', [0, 5.0]), units='deg')
-        p.set_val('traj.climb.controls:alpha', 5.0, units='deg')
+        br_to_v1.set_time_val(initial=0.0, duration=35.0)
+        br_to_v1.set_state_val('r', [0, 2500.0])
+        br_to_v1.set_state_val('v', [0.0001, 100.0])
+        br_to_v1.set_parameter_val('alpha', 0.0, units='deg')
+
+        v1_to_vr.set_time_val(initial=35.0, duration=35.0)
+        v1_to_vr.set_state_val('r', [2500, 300.0])
+        v1_to_vr.set_state_val('v', [100, 110.0])
+        v1_to_vr.set_parameter_val('alpha', 0.0, units='deg')
+
+        rto.set_time_val(initial=35.0, duration=1.0)
+        rto.set_state_val('r', [2500, 5000.0])
+        rto.set_state_val('v', [110, 0.0001])
+        rto.set_parameter_val('alpha', 0.0, units='deg')
+
+        rotate.set_time_val(initial=35.0, duration=5.0)
+        rotate.set_state_val('r', [1750, 1800.0])
+        rotate.set_state_val('v', [80, 85.0])
+        rotate.set_polynomial_control_val('alpha', 0.0, units='deg')
+
+        climb.set_time_val(initial=30.0, duration=20.0)
+        climb.set_state_val('r', [5000, 5500.0], units='ft')
+        climb.set_state_val('v', [160, 170.0], units='kn')
+        climb.set_state_val('h', [0.0, 35.0], units='ft')
+        climb.set_state_val('gam', [0.0, 5.0], units='deg')
+        climb.set_control_val('alpha', 5.0, units='deg')
 
         return p
 
diff --git a/dymos/examples/battery_multibranch/test/test_multibranch_trajectory.py b/dymos/examples/battery_multibranch/test/test_multibranch_trajectory.py
index 29b8b10d8..ff3e8cd49 100644
--- a/dymos/examples/battery_multibranch/test/test_multibranch_trajectory.py
+++ b/dymos/examples/battery_multibranch/test/test_multibranch_trajectory.py
@@ -92,17 +92,10 @@ def test_optimizer_defects(self):
 
         prob.setup()
 
-        prob['traj.phase0.t_initial'] = 0
-        prob['traj.phase0.t_duration'] = 1.0*3600
-
-        prob['traj.phase1.t_initial'] = 1.0*3600
-        prob['traj.phase1.t_duration'] = 1.0*3600
-
-        prob['traj.phase1_bfail.t_initial'] = 1.0*3600
-        prob['traj.phase1_bfail.t_duration'] = 1.0*3600
-
-        prob['traj.phase1_mfail.t_initial'] = 1.0*3600
-        prob['traj.phase1_mfail.t_duration'] = 1.0*3600
+        phase0.set_time_val(initial=0.0, duration=3600)
+        phase1.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_bfail.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_mfail.set_time_val(initial=3600.0, duration=3600.0)
 
         prob.set_solver_print(level=0)
         dm.run_problem(prob)
@@ -176,19 +169,11 @@ def test_solver_defects(self):
 
         prob.setup()
 
-        prob['traj.phase0.t_initial'] = 0
-        prob['traj.phase0.t_duration'] = 1.0*3600
-
-        prob['traj.phase1.t_initial'] = 1.0*3600
-        prob['traj.phase1.t_duration'] = 1.0*3600
-
-        prob['traj.phase1_bfail.t_initial'] = 1.0*3600
-        prob['traj.phase1_bfail.t_duration'] = 1.0*3600
-
-        prob['traj.phase1_mfail.t_initial'] = 1.0*3600
-        prob['traj.phase1_mfail.t_duration'] = 1.0*3600
-
-        prob['traj.phase0.states:state_of_charge'][:] = 1.0
+        phase0.set_time_val(initial=0.0, duration=3600)
+        phase1.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_bfail.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_mfail.set_time_val(initial=3600.0, duration=3600.0)
+        phase0.set_state_val('state_of_charge', 1.0)
 
         prob.set_solver_print(level=0)
         prob.run_model()
@@ -223,9 +208,8 @@ def test_solver_defects_single_phase_reverse_propagation(self):
 
         prob.setup()
 
-        prob['phase0.t_initial'] = 0
-        prob['phase0.t_duration'] = -1.0*3600
-        prob['phase0.states:state_of_charge'][:] = 0.63464982
+        phase0.set_time_val(initial=0.0, duration=-3600)
+        phase0.set_state_val('state_of_charge', 0.63464982)
 
         prob.set_solver_print(level=0)
         prob.run_model()
@@ -266,12 +250,9 @@ def test_solver_defects_reverse_propagation(self):
 
         prob.setup()
 
-        prob['traj.phase0.t_initial'] = 0
-        prob['traj.phase0.t_duration'] = -1.0*3600
-        prob['traj.phase0.states:state_of_charge'][:] = 0.23794217
-
-        prob['traj.phase1.t_initial'] = 0
-        prob['traj.phase1.t_duration'] = -1.0*3600
+        phase0.set_time_val(initial=0.0, duration=-3600)
+        phase1.set_time_val(initial=0.0, duration=-3600.0)
+        phase0.set_state_val('state_of_charge', 0.23794217)
 
         prob.set_solver_print(level=0)
         prob.run_model()
@@ -349,17 +330,10 @@ def test_optimizer_segments_direct_connections(self):
 
         prob.setup(force_alloc_complex=True)
 
-        prob.set_val('traj.phase0.t_initial', 0)
-        prob.set_val('traj.phase0.t_duration', 1.0*3600)
-
-        prob.set_val('traj.phase1.t_initial', 1.0*3600)
-        prob.set_val('traj.phase1.t_duration', 1.0*3600)
-
-        prob.set_val('traj.phase1_bfail.t_initial', 1.0*3600)
-        prob.set_val('traj.phase1_bfail.t_duration', 1.0*3600)
-
-        prob.set_val('traj.phase1_mfail.t_initial', 1.0*3600)
-        prob.set_val('traj.phase1_mfail.t_duration', 1.0*3600)
+        phase0.set_time_val(initial=0.0, duration=3600)
+        phase1.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_bfail.set_time_val(initial=3600.0, duration=3600.0)
+        phase1_mfail.set_time_val(initial=3600.0, duration=3600.0)
 
         prob.run_model()
 
diff --git a/dymos/examples/brachistochrone/test/ex_brachistochrone.py b/dymos/examples/brachistochrone/test/ex_brachistochrone.py
index 393558864..03ed2c850 100644
--- a/dymos/examples/brachistochrone/test/ex_brachistochrone.py
+++ b/dymos/examples/brachistochrone/test/ex_brachistochrone.py
@@ -84,20 +84,14 @@ def brachistochrone_min_time(transcription='gauss-lobatto', num_segments=8, tran
 
     phase.set_simulate_options(method='RK23')
 
-    p['traj0.phase0.t_initial'] = 0.0
-    p['traj0.phase0.t_duration'] = 2.0
-
-    if transcription.startswith('shooting') or transcription == 'birkhoff':
-        p['traj0.phase0.initial_states:x'] = 0
-        p['traj0.phase0.initial_states:y'] = 10
-        p['traj0.phase0.initial_states:v'] = 0
-    else:
-        p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-
-    p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-    p['traj0.phase0.parameters:g'] = 9.80665
+    phase.set_time_val(initial=0.0, duration=2.0)
+
+    phase.set_state_val('x', [0, 10])
+    phase.set_state_val('y', [10, 5])
+    phase.set_state_val('v', [0, 9.9])
+
+    phase.set_control_val('theta', [5, 100])
+    phase.set_parameter_val('g', 9.80665)
 
     dm.run_problem(p, run_driver=run_driver, simulate=True, make_plots=True,
                    simulate_kwargs={'times_per_seg': 100})
diff --git a/dymos/examples/brachistochrone/test/ex_brachistochrone_vector_states.py b/dymos/examples/brachistochrone/test/ex_brachistochrone_vector_states.py
index 257204333..c5ea6ba09 100644
--- a/dymos/examples/brachistochrone/test/ex_brachistochrone_vector_states.py
+++ b/dymos/examples/brachistochrone/test/ex_brachistochrone_vector_states.py
@@ -69,22 +69,15 @@ def brachistochrone_min_time(transcription='gauss-lobatto', num_segments=8, tran
     p.model.linear_solver = om.DirectSolver()
     p.setup(check=True, force_alloc_complex=force_alloc_complex)
 
-    p['traj0.phase0.t_initial'] = 0.0
-    p['traj0.phase0.t_duration'] = 1.8016
+    phase.set_time_val(initial=0.0, duration=1.8016)
 
     pos0 = [0, 10]
     posf = [10, 5]
 
-    p['traj0.phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-    p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-    p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-    p['traj0.phase0.parameters:g'] = 9.80665
-    if isinstance(transcription, dm.Birkhoff):
-        p['traj0.phase0.initial_states:pos'] = pos0
-        p['traj0.phase0.initial_states:v'] = 0.0
-        p['traj0.phase0.final_states:pos'] = posf
-        p['traj0.phase0.final_states:v'] = 9.9
-
+    phase.set_state_val('pos', [pos0, posf])
+    phase.set_state_val('v', [0, 9.9])
+    phase.set_control_val('theta', [5, 100])
+    phase.set_parameter_val('g', 9.80665)
     p.run_model()
     if run_driver:
         p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_birkhoff_constraints.py b/dymos/examples/brachistochrone/test/test_brachistochrone_birkhoff_constraints.py
index b1bc1369f..5ed178422 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_birkhoff_constraints.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_birkhoff_constraints.py
@@ -55,18 +55,14 @@ def test_brachistochrone_control_prefix(self):
 
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 1.5
+        phase.set_time_val(initial=0.0, duration=1.5)
 
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:y'] = 10.0
-        p['traj.phase0.initial_states:v'] = 0.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
         assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-4)
@@ -115,18 +111,14 @@ def test_brachistochrone_control_no_prefix(self):
 
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 1.5
+        phase.set_time_val(initial=0.0, duration=1.5)
 
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:y'] = 10.0
-        p['traj.phase0.initial_states:v'] = 0.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
         assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-4)
@@ -174,18 +166,14 @@ def test_brachistochrone_ode_prefix(self):
 
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 1.5
+        phase.set_time_val(initial=0.0, duration=1.5)
 
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:y'] = 10.0
-        p['traj.phase0.initial_states:v'] = 0.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
         assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-4)
@@ -234,18 +222,14 @@ def test_brachistochrone_ode_no_prefix(self):
 
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 1.5
+        phase.set_time_val(initial=0.0, duration=1.5)
 
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:y'] = 10.0
-        p['traj.phase0.initial_states:v'] = 0.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
         assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1], 1.8016, tolerance=1.0E-4)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_callable_ode_class.py b/dymos/examples/brachistochrone/test/test_brachistochrone_callable_ode_class.py
index 666260945..e1c388e22 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_callable_ode_class.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_callable_ode_class.py
@@ -30,6 +30,10 @@ def _make_problem(self, transcription='gauss-lobatto', num_segments=8, transcrip
             t = dm.Radau(num_segments=num_segments,
                          order=transcription_order,
                          compressed=compressed)
+        elif transcription == 'birkhoff':
+            grid = dm.BirkhoffGrid(num_nodes=transcription_order+1,
+                                   grid_type='cgl')
+            t = dm.Birkhoff(grid=grid)
 
         def ode(num_nodes):
             return om.ExecComp(['vdot = g * cos(theta)',
@@ -75,15 +79,14 @@ def ode(num_nodes):
         phase.add_objective('time_phase', loc='final', scaler=10)
 
         p.setup(check=['unconnected_inputs'], force_alloc_complex=force_alloc_complex)
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj0.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         dm.run_problem(p, run_driver=run_driver, simulate=True)
 
@@ -131,6 +134,10 @@ def test_ex_brachistochrone_gl_uncompressed(self):
         self._make_problem(transcription='gauss-lobatto', compressed=False)
         self.run_asserts()
 
+    def test_ex_brachistochrone_birkhoff_uncompressed(self):
+        self._make_problem(transcription='birkhoff', transcription_order=10)
+        self.run_asserts()
+
 
 @use_tempdirs
 class TestInvalidCallableODEClass(unittest.TestCase):
@@ -287,14 +294,14 @@ def _make_problem(self, transcription='gauss-lobatto', num_segments=8, transcrip
 
         p.setup(check=['unconnected_inputs'], force_alloc_complex=force_alloc_complex)
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj0.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         dm.run_problem(p, run_driver=run_driver, simulate=True)
 
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_control_rate_targets.py b/dymos/examples/brachistochrone/test/test_brachistochrone_control_rate_targets.py
index 63c1011b1..d5d33c26f 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_control_rate_targets.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_control_rate_targets.py
@@ -157,13 +157,12 @@ def test_brachistochrone_control_rate_targets_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -255,13 +254,12 @@ def test_brachistochrone_control_rate_targets_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -353,13 +351,12 @@ def test_brachistochrone_control_rate_targets_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -448,13 +445,12 @@ def test_brachistochrone_control_rate_targets_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -546,13 +542,12 @@ def test_brachistochrone_polynomial_control_rate_targets_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.polynomial_controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -641,13 +636,12 @@ def test_brachistochrone_polynomial_control_rate_targets_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.polynomial_controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -739,13 +733,12 @@ def test_brachistochrone_polynomial_control_rate_targets_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.polynomial_controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -834,13 +827,12 @@ def test_brachistochrone_polynomial_control_rate_targets_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.polynomial_controls:theta'] = phase.interp('theta', [0, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [0, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -932,13 +924,13 @@ def test_brachistochrone_polynomial_control_rate_targets_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.polynomial_controls:theta'] = [0, 10, 40, 60, 80, 100]
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [0, 10, 40, 60, 80, 100],
+                                         time_vals=[0, 0.4, 0.8, 1.2, 1.6, 2.0])
 
         # Solve for the optimal trajectory
         dm.run_problem(p, simulate=True)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_external_control.py b/dymos/examples/brachistochrone/test/test_brachistochrone_external_control.py
index 9739f8728..bf3834c4f 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_external_control.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_external_control.py
@@ -96,10 +96,10 @@ def test_brachistochrone_external_control(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', ys=[10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 9.9]), units='m/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', ys=[5, 100]), units='deg')
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100], units='deg')
 
         # Run the driver to solve the problem
         p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_implicit_recorder.py b/dymos/examples/brachistochrone/test/test_brachistochrone_implicit_recorder.py
index 39311fa3d..5068b2fe6 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_implicit_recorder.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_implicit_recorder.py
@@ -52,13 +52,13 @@ def test_brachistochrone_recording(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]), units='m/s')
-        p.set_val('phase0.controls:theta', phase.interp('theta', [5, 100.5]), units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+
+        phase.set_control_val('theta', [5, 100.5], units='deg')
 
         # Solve for the optimal trajectory
         dm.run_problem(p)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_control.py b/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_control.py
index 7c6d05f62..3c8912e38 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_control.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_control.py
@@ -121,14 +121,13 @@ def test_brachistochrone_integrated_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', ys=[0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', ys=[10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', ys=[0, 9.9]))
-        p.set_val('phase0.states:theta', phase.interp('theta', ys=[5, 100.5]), units='deg')
-        p.set_val('phase0.controls:theta_dot', phase.interp('theta_dot', ys=[50, 50]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_state_val('theta', [5, 100.5], units='deg')
+        phase.set_control_val('theta_dot', [50, 50])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -200,14 +199,13 @@ def test_brachistochrone_integrated_control_radau_ps(self):
 
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 10]))
-        p.set_val('traj.phase0.states:y', phase.interp('y', ys=[10, 5]))
-        p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 9.9]))
-        p.set_val('traj.phase0.states:theta', phase.interp('theta', ys=[5, 100.5]), units='deg')
-        p.set_val('traj.phase0.controls:theta_dot', phase.interp('theta_dot', ys=[50, 50]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_state_val('theta', [5, 100.5], units='deg')
+        phase.set_control_val('theta_dot', [50, 50])
 
         # Solve for the optimal trajectory
         dm.run_problem(p, simulate=True, make_plots=True)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_parameter.py b/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_parameter.py
index 8bdb9eaba..473040b48 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_parameter.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_integrated_parameter.py
@@ -124,14 +124,13 @@ def test_brachistochrone_integrated_param_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.states:theta'] = np.radians(phase.interp('theta', [0.05, 100.0]))
-        p['phase0.parameters:theta_dot'] = 60.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_state_val('theta', [0.5, 100.0], units='deg')
+        phase.set_parameter_val('theta_dot', 60.0)
 
         # Solve for the optimal trajectory
         dm.run_problem(p, refine_iteration_limit=5)
@@ -194,14 +193,13 @@ def test_brachistochrone_integrated_parameter_radau_ps(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.states:theta'] = np.radians(phase.interp('theta', [0.05, 100.0]))
-        p['phase0.parameters:theta_dot'] = 60.0
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_state_val('theta', [0.5, 100], units='deg')
+        phase.set_parameter_val('theta_dot', 60.0)
 
         # Solve for the optimal trajectory
         dm.run_problem(p, refine_iteration_limit=5)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_path_constraint.py b/dymos/examples/brachistochrone/test/test_brachistochrone_path_constraint.py
index e5494c3e7..228b83274 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_path_constraint.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_path_constraint.py
@@ -42,14 +42,14 @@ def _make_problem(self, tx):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
-
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p[f'phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
         return p
 
     def test_brachistochrone_expr_path_constraint(self):
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_quick_start.py b/dymos/examples/brachistochrone/test/test_brachistochrone_quick_start.py
index b270d938d..050869158 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_quick_start.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_quick_start.py
@@ -135,13 +135,10 @@ def test_brachistochrone_quick_start(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+        phase.set_control_val('theta', [90, 90], units='deg')
 
         # Run the driver to solve the problem
         p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_simulate_options.py b/dymos/examples/brachistochrone/test/test_brachistochrone_simulate_options.py
index fadd58a24..3237e3514 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_simulate_options.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_simulate_options.py
@@ -136,13 +136,10 @@ def test_simulate_options(self):
                 p.setup(check=True)
 
                 # Now that the OpenMDAO problem is setup, we can set the values of the states.
-                p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-
-                p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-
-                p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-
-                p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
+                phase.set_state_val('x', [0, 10], units='m')
+                phase.set_state_val('y', [10, 5], units='m')
+                phase.set_state_val('v', [0, 9.9], units='m/s')
+                phase.set_control_val('theta', [90, 90], units='deg')
 
                 # Run the driver to simulate the problem
                 dm.run_problem(p, run_driver=False, simulate=True)
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_solve_segments.py b/dymos/examples/brachistochrone/test/test_brachistochrone_solve_segments.py
index aa9110de2..f3a9029f0 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_solve_segments.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_solve_segments.py
@@ -90,14 +90,14 @@ def _make_problem(transcription='gauss-lobatto', num_segments=8, transcription_o
 
     p.setup(check=['unconnected_inputs'], force_alloc_complex=force_alloc_complex)
 
-    p['traj0.phase0.t_initial'] = 0.0
-    p['traj0.phase0.t_duration'] = 1.5
+    phase.set_time_val(initial=0.0, duration=1.5)
 
-    p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-    p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-    p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-    p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-    p['traj0.phase0.parameters:g'] = 9.80665
+    phase.set_state_val('x', [0, 10])
+    phase.set_state_val('y', [10, 5])
+    phase.set_state_val('v', [0, 9.9])
+
+    phase.set_control_val('theta', [5, 100])
+    phase.set_parameter_val('g', 9.80665)
 
     return p
 
@@ -546,13 +546,13 @@ def test_brachistochrone_solve_segments_radau_krylov_solver(self, optimizer='SLS
         #
         # Set the initial values
         #
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p.set_val('traj0.phase0.states:x', phase.interp('x', ys=[0, 10]))
-        p.set_val('traj0.phase0.states:y', phase.interp('y', ys=[10, 5]))
-        p.set_val('traj0.phase0.states:v', phase.interp('v', ys=[0, 9.9]))
-        p.set_val('traj0.phase0.controls:theta', phase.interp('theta', ys=[5, 100.5]))
+        phase.set_control_val('theta', [5, 100.5])
 
         #
         # Solve for the optimal trajectory
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_subprob_reports.py b/dymos/examples/brachistochrone/test/test_brachistochrone_subprob_reports.py
index 1a71012c1..a01a8ad02 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_subprob_reports.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_subprob_reports.py
@@ -55,14 +55,14 @@ def setup_model_radau(do_reports):
 
     phase.set_simulate_options(method='RK23')
 
-    p['traj0.phase0.t_initial'] = 0.0
-    p['traj0.phase0.t_duration'] = 2.0
+    phase.set_time_val(initial=0.0, duration=2.0)
 
-    p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-    p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-    p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-    p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-    p['traj0.phase0.parameters:g'] = 9.80665
+    phase.set_state_val('x', [0, 10])
+    phase.set_state_val('y', [10, 5])
+    phase.set_state_val('v', [0, 9.9])
+
+    phase.set_control_val('theta', [5, 100.5])
+    phase.set_parameter_val('g', 9.80665)
 
     if do_reports:
         dm.run_problem(p, run_driver=True, simulate=True, simulate_kwargs={'reports': True})
@@ -103,13 +103,14 @@ def setup_model_shooting(do_reports):
 
     prob.setup(force_alloc_complex=True)
 
-    prob.set_val('phase0.t_initial', 0.0)
-    prob.set_val('phase0.t_duration', 2)
-    prob.set_val('phase0.initial_states:x', 0.0)
-    prob.set_val('phase0.initial_states:y', 10.0)
-    prob.set_val('phase0.initial_states:v', 1.0E-6)
-    prob.set_val('phase0.parameters:g', 1.0, units='m/s**2')
-    prob.set_val('phase0.controls:theta', phase.interp('theta', ys=[0.01, 90]), units='deg')
+    phase.set_time_val(initial=0.0, duration=2.0)
+
+    phase.set_state_val('x', [0, 10])
+    phase.set_state_val('y', [10, 5])
+    phase.set_state_val('v', [0, 9.9])
+
+    phase.set_control_val('theta', [0.01, 90], units='deg')
+    phase.set_parameter_val('g', 1.0)
 
     dm.run_problem(prob, run_driver=True, simulate=False)
 
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_timeseries_feedback.py b/dymos/examples/brachistochrone/test/test_brachistochrone_timeseries_feedback.py
index 90a502d0c..7616833c8 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_timeseries_feedback.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_timeseries_feedback.py
@@ -138,15 +138,13 @@ def test_timeseries_feedback(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
 
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
 
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
-
-        p.set_val('traj.parameters:final_time', 0.0, units='s')
+        phase.set_control_val('theta', [90, 90])
+        phase.set_parameter_val('final_time', 0.0, units='s')
 
         # Run the driver to solve the problem
         dm.run_problem(p, run_driver=True, simulate=True)
@@ -156,8 +154,8 @@ def test_timeseries_feedback(self):
 
         final_time_timeseries_sol = sol_case.get_val('traj.phase0.timeseries.time')[-1, ...]
         final_time_traj_param_sol = sol_case.get_val('traj.parameter_vals:final_time')[0, 0]
-        final_time_timeseries_sim = sol_case.get_val('traj.phase0.timeseries.time')[-1, ...]
-        final_time_traj_param_sim = sol_case.get_val('traj.parameter_vals:final_time')[0, 0]
+        final_time_timeseries_sim = sim_case.get_val('traj.phase0.timeseries.time')[-1, ...]
+        final_time_traj_param_sim = sim_case.get_val('traj.parameter_vals:final_time')[0, 0]
 
         p.model.list_outputs(prom_name=True)
 
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_varying_order_control_simulation.py b/dymos/examples/brachistochrone/test/test_brachistochrone_varying_order_control_simulation.py
index 9087d257f..9a068aad6 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_varying_order_control_simulation.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_varying_order_control_simulation.py
@@ -49,14 +49,14 @@ def test_gauss_lobatto(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -126,14 +126,14 @@ def test_radau(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_vector_boundary_constraints.py b/dymos/examples/brachistochrone/test/test_brachistochrone_vector_boundary_constraints.py
index 3dd824a47..56f337133 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_vector_boundary_constraints.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_vector_boundary_constraints.py
@@ -43,16 +43,15 @@ def test_brachistochrone_vector_boundary_constraints_radau_no_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -88,16 +87,15 @@ def test_brachistochrone_vector_boundary_constraints_radau_full_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
diff --git a/dymos/examples/brachistochrone/test/test_brachistochrone_vector_path_constraints.py b/dymos/examples/brachistochrone/test/test_brachistochrone_vector_path_constraints.py
index 57d9f9b32..628a467e5 100644
--- a/dymos/examples/brachistochrone/test/test_brachistochrone_vector_path_constraints.py
+++ b/dymos/examples/brachistochrone/test/test_brachistochrone_vector_path_constraints.py
@@ -47,16 +47,15 @@ def test_brachistochrone_vector_state_path_constraints_radau_partial_indices(sel
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -93,16 +92,15 @@ def test_brachistochrone_vector_ode_path_constraints_radau_partial_indices(self)
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -141,16 +139,15 @@ def test_brachistochrone_vector_ode_path_constraints_radau_no_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -189,16 +186,15 @@ def test_brachistochrone_vector_state_path_constraints_gl_partial_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -241,16 +237,15 @@ def test_brachistochrone_vector_ode_path_constraints_gl_partial_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
@@ -289,16 +284,15 @@ def test_brachistochrone_vector_ode_path_constraints_gl_no_indices(self):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True, force_alloc_complex=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=1.8016)
 
         pos0 = [0, 10]
         posf = [10, 5]
 
-        p['phase0.states:pos'] = phase.interp('pos', [pos0, posf])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase.set_state_val('pos', [pos0, posf])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
diff --git a/dymos/examples/brachistochrone/test/test_doc_brachistochrone_polynomial_controls.py b/dymos/examples/brachistochrone/test/test_doc_brachistochrone_polynomial_controls.py
index e54d2fc93..e9a940672 100644
--- a/dymos/examples/brachistochrone/test/test_doc_brachistochrone_polynomial_controls.py
+++ b/dymos/examples/brachistochrone/test/test_doc_brachistochrone_polynomial_controls.py
@@ -49,13 +49,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -136,13 +135,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -223,20 +221,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
-
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -323,13 +313,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -412,13 +401,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -502,20 +490,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
-
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [1, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -600,13 +580,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -687,13 +666,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -776,20 +754,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
-
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -876,13 +846,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -965,13 +934,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1054,20 +1022,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
-
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1154,13 +1114,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1243,13 +1202,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1332,20 +1290,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
-
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1425,13 +1375,12 @@ def test_brachistochrone_polynomial_control_gauss_lobatto(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1482,13 +1431,12 @@ def test_brachistochrone_polynomial_control_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -1544,20 +1492,12 @@ def test_brachistochrone_polynomial_control_birkhoff(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
-
-        p.set_val('phase0.initial_states:x', 0.0)
-        p.set_val('phase0.initial_states:y', 10.0)
-        p.set_val('phase0.initial_states:v', 0.0)
-        p.set_val('phase0.final_states:x', 10.0)
-        p.set_val('phase0.final_states:y', 5.0)
-        p.set_val('phase0.final_states:v', 9.9)
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('phase0.polynomial_controls:theta', phase.interp('theta', [5, 100]))
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_polynomial_control_val('theta', [5, 100])
 
         # Solve for the optimal trajectory
         p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_duplicate_constraints.py b/dymos/examples/brachistochrone/test/test_duplicate_constraints.py
index 4547146b1..a8f908cfe 100644
--- a/dymos/examples/brachistochrone/test/test_duplicate_constraints.py
+++ b/dymos/examples/brachistochrone/test/test_duplicate_constraints.py
@@ -554,14 +554,13 @@ def test_duplicate_path_constraint_different_constraint_name(self):
 
         p.setup()
 
-        p.set_val('traj0.phase0.t_initial', 0.0)
-        p.set_val('traj0.phase0.t_duration', 2.0)
-
-        p.set_val('traj0.phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('traj0.phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('traj0.phase0.states:v', phase.interp('v', [0.001, 9.9]))
-        p.set_val('traj0.phase0.controls:theta', phase.interp('theta', [5, 90]), units='deg')
-        p.set_val('traj0.phase0.parameters:g', 9.80665)
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0.001, 9.9])
+        phase.set_control_val('theta', [5, 90], units='deg')
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_model()
 
diff --git a/dymos/examples/brachistochrone/test/test_duplicate_timeseries_inputs.py b/dymos/examples/brachistochrone/test/test_duplicate_timeseries_inputs.py
index 4cb53af2b..55bbe841d 100644
--- a/dymos/examples/brachistochrone/test/test_duplicate_timeseries_inputs.py
+++ b/dymos/examples/brachistochrone/test/test_duplicate_timeseries_inputs.py
@@ -76,24 +76,12 @@ def _make_problem(self, transcription):
         # Setup the problem
         p.setup(check=True)
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p.set_val('traj.phase0.states:x',
-                  phase.interp('x', [0, 10]),
-                  units='m')
-
-        p.set_val('traj.phase0.states:y',
-                  phase.interp('y', [10, 5]),
-                  units='m')
-
-        p.set_val('traj.phase0.states:v',
-                  phase.interp('v', [0, 5]),
-                  units='m/s')
-
-        p.set_val('traj.phase0.controls:theta',
-                  phase.interp('theta', [0.01, 90]),
-                  units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0.0, 5], units='m/s')
+        phase.set_control_val('theta', [5, 90], units='deg')
 
         return p
 
diff --git a/dymos/examples/brachistochrone/test/test_ex_brachistochrone.py b/dymos/examples/brachistochrone/test/test_ex_brachistochrone.py
index 64b45e0d1..bb6f0fb8f 100644
--- a/dymos/examples/brachistochrone/test/test_ex_brachistochrone.py
+++ b/dymos/examples/brachistochrone/test/test_ex_brachistochrone.py
@@ -90,7 +90,7 @@ def test_ex_brachistochrone_shooting_gl_compressed(self):
     def test_ex_brachistochrone_birkhoff(self):
         ex_brachistochrone.SHOW_PLOTS = True
         p = ex_brachistochrone.brachistochrone_min_time(transcription='birkhoff',
-                                                        num_segments=1, transcription_order=11)
+                                                        num_segments=1, transcription_order=12)
         self.run_asserts(p)
         self.tearDown()
 
diff --git a/dymos/examples/brachistochrone/test/test_ex_brachistochrone_refine_grid.py b/dymos/examples/brachistochrone/test/test_ex_brachistochrone_refine_grid.py
index 6c6b99f3e..137e6deb1 100644
--- a/dymos/examples/brachistochrone/test/test_ex_brachistochrone_refine_grid.py
+++ b/dymos/examples/brachistochrone/test/test_ex_brachistochrone_refine_grid.py
@@ -30,6 +30,9 @@ def make_problem(self, transcription='radau-ps', num_segments=5, transcription_o
             t = dm.Radau(num_segments=num_segments,
                          order=transcription_order,
                          compressed=compressed)
+        elif transcription == 'birkhoff':
+            grid = dm.BirkhoffGrid(num_nodes=transcription_order+1, grid_type='cgl')
+            t = dm.Birkhoff(grid=grid)
 
         traj = dm.Trajectory()
         phase = dm.Phase(ode_class=BrachistochroneODE, transcription=t)
@@ -59,15 +62,14 @@ def make_problem(self, transcription='radau-ps', num_segments=5, transcription_o
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=['unconnected_inputs'])
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj0.phase0.parameters:g'] = 9.80665
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         return p
 
@@ -111,3 +113,8 @@ def test_refine_brachistochrone_gauss_lobatto_compressed(self):
         p = self.make_problem(transcription='gauss-lobatto', num_segments=5, transcription_order=3, compressed=True)
         dm.run_problem(p)
         self.run_asserts(self.p)
+
+    def test_refine_brachistochrone_birkhoff_compressed(self):
+        p = self.make_problem(transcription='birkhoff', num_segments=1, transcription_order=12, compressed=True)
+        dm.run_problem(p)
+        self.run_asserts(self.p)
diff --git a/dymos/examples/brachistochrone/test/test_ex_brachistochrone_vector_states.py b/dymos/examples/brachistochrone/test/test_ex_brachistochrone_vector_states.py
index f7177f2f0..d50fbc136 100644
--- a/dymos/examples/brachistochrone/test/test_ex_brachistochrone_vector_states.py
+++ b/dymos/examples/brachistochrone/test/test_ex_brachistochrone_vector_states.py
@@ -86,6 +86,17 @@ def test_ex_brachistochrone_vs_gl_uncompressed(self):
         self.assert_results(p)
         self.assert_partials(p)
 
+    def test_ex_brachistochrone_vs_birkhoff(self):
+        ex_brachistochrone_vs.SHOW_PLOTS = True
+        p = ex_brachistochrone_vs.brachistochrone_min_time(transcription='birkhoff',
+                                                           transcription_order=12,
+                                                           compressed=True,
+                                                           force_alloc_complex=True,
+                                                           run_driver=True)
+
+        self.assert_results(p)
+        self.assert_partials(p)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/dymos/examples/brachistochrone/test/test_path_constraints.py b/dymos/examples/brachistochrone/test/test_path_constraints.py
index 99674d089..97c5db368 100644
--- a/dymos/examples/brachistochrone/test/test_path_constraints.py
+++ b/dymos/examples/brachistochrone/test/test_path_constraints.py
@@ -42,13 +42,13 @@ def test_control_rate_path_constraint_gl(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100.5])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         p.run_driver()
@@ -91,13 +91,13 @@ def test_control_rate2_path_constraint_gl(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100.5])
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         failed = p.run_driver()
@@ -143,13 +143,13 @@ def test_control_rate_path_constraint_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['phase0.states:x'] = phase.interp('x', ys=[0, 10])
-        p['phase0.states:y'] = phase.interp('y', ys=[10, 5])
-        p['phase0.states:v'] = phase.interp('v', ys=[0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', ys=[0.9, 101.5])
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         failed = p.run_driver()
@@ -198,13 +198,13 @@ def test_control_rate2_path_constraint_radau(self):
 
         p.setup()
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase.interp('x', [0, 10])
-        p['phase0.states:y'] = phase.interp('y', [10, 5])
-        p['phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['phase0.controls:theta'] = phase.interp('theta', [5, 100.5])
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         failed = p.run_driver()
@@ -255,13 +255,13 @@ def test_state_path_constraint_radau(self):
 
         p.setup()
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj0.phase0.states:x'] = phase.interp('x', ys=[0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', ys=[10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', ys=[0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', ys=[0.9, 101.5])
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         failed = p.run_driver()
@@ -310,13 +310,13 @@ def test_state_path_constraint_gl(self):
 
         p.setup()
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
 
-        p['traj0.phase0.states:x'] = phase.interp('x', ys=[0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', ys=[10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', ys=[0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', ys=[0.9, 101.5])
+        phase.set_control_val('theta', [5, 101.5])
 
         # Solve for the optimal trajectory
         failed = p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_phase_param_introspection_failure.py b/dymos/examples/brachistochrone/test/test_phase_param_introspection_failure.py
index 970fa8012..b83356a54 100644
--- a/dymos/examples/brachistochrone/test/test_phase_param_introspection_failure.py
+++ b/dymos/examples/brachistochrone/test/test_phase_param_introspection_failure.py
@@ -150,13 +150,12 @@ def test_valid_parameters(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 2.0, units='s')
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
-        p.set_val('traj.phase0.parameters:foo', 5.0)
+        phase.set_time_val(initial=0.0, duration=2.0, units='s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+        phase.set_control_val('theta', [90, 90], units='deg')
+        phase.set_parameter_val('foo', 5.0)
 
         # Run the driver to solve the problem
         p.run_driver()
@@ -392,13 +391,13 @@ def test_valid_parameters(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 2.0, units='s')
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
-        p.set_val('traj.phase0.parameters:foo', 5.0)
+
+        phase.set_time_val(initial=0.0, duration=2.0, units='s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+        phase.set_control_val('theta', [90, 90], units='deg')
+        phase.set_parameter_val('foo', 5.0)
 
         # Run the driver to solve the problem
         p.run_driver()
@@ -566,13 +565,12 @@ def test_all_static(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 2.0, units='s')
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
-        p.set_val('traj.phase0.parameters:foo', 5.0)
+        phase.set_time_val(initial=0.0, duration=2.0, units='s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+        phase.set_control_val('theta', [90, 90], units='deg')
+        phase.set_parameter_val('foo', 5.0)
 
         # Run the driver to solve the problem
         p.run_driver()
@@ -660,13 +658,12 @@ def test_mixed_static(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 2.0, units='s')
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [90, 90]), units='deg')
-        p.set_val('traj.phase0.parameters:foo', 5.0)
+        phase.set_time_val(initial=0.0, duration=2.0, units='s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 9.9], units='m/s')
+        phase.set_control_val('theta', [90, 90], units='deg')
+        phase.set_parameter_val('foo', 5.0)
 
         # Run the driver to solve the problem
         p.run_driver()
diff --git a/dymos/examples/brachistochrone/test/test_simulate_units.py b/dymos/examples/brachistochrone/test/test_simulate_units.py
index b998e46cf..a9cf21060 100644
--- a/dymos/examples/brachistochrone/test/test_simulate_units.py
+++ b/dymos/examples/brachistochrone/test/test_simulate_units.py
@@ -76,15 +76,11 @@ def test_brachistochrone_simulate_units(self):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-
-        p.set_val('traj.phase0.states:v', phase.interp('v', [1.0E-6, 5]), units='m/s')
-
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [5, 100]), units='deg')
-
-        p.set_val('traj.phase0.parameters:g', 9.80665, units='m/s**2')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [1E-6, 9.9], units='m/s')
+        phase.set_control_val('theta', [5, 100], units='deg')
+        phase.set_parameter_val('g', 9.80665, units='m/s**2')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True)
diff --git a/dymos/examples/brachistochrone/test/test_state_rate_introspection.py b/dymos/examples/brachistochrone/test/test_state_rate_introspection.py
index e1d1638eb..8667db7fe 100644
--- a/dymos/examples/brachistochrone/test/test_state_rate_introspection.py
+++ b/dymos/examples/brachistochrone/test/test_state_rate_introspection.py
@@ -75,14 +75,13 @@ def _test_integrate_control(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.controls:theta_rate', phase.interp('theta_rate', [10, 10]), units='deg/s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_control_val('theta_rate', [10, 10], units='deg/s')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=False)
@@ -180,14 +179,13 @@ def _test_integrate_control_rate(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [0, 100]), units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_control_val('theta', [0, 100], units='deg')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=False)
@@ -296,16 +294,14 @@ def _test_integrate_control_rate2(self, transcription):
         p.setup(check=True)
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
-
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.states:int_theta_dot', phase.interp('int_theta_dot', [0, 0]), units='deg/s')
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [0, 100]), units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_state_val('int_theta_dot', [0.0, 0.0], units='deg/s')
+        phase.set_control_val('theta', [0, 100], units='deg')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=False, simulate_kwargs={'atol': 1.0E-9, 'rtol': 1.0E-9})
@@ -422,14 +418,13 @@ def _test_integrate_polynomial_control(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.polynomial_controls:theta_rate', 10.0, units='deg/s')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_polynomial_control_val('theta_rate', 10.0, units='deg/s')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=True)
@@ -527,14 +522,13 @@ def _test_integrate_polynomial_control_rate(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.polynomial_controls:theta', 45.0, units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_polynomial_control_val('theta', 45.0, units='deg')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=False)
@@ -645,15 +639,14 @@ def _test_integrate_polynomial_control_rate2(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]), units='m')
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 5]), units='m/s')
-        p.set_val('traj.phase0.states:int_theta', phase.interp('int_theta', [0.1, 45]), units='deg')
-        p.set_val('traj.phase0.states:int_theta_dot', phase.interp('int_theta_dot', [0, 0]), units='deg/s')
-        p.set_val('traj.phase0.polynomial_controls:theta', 45.0, units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_theta', [0.1, 45], units='deg')
+        phase.set_state_val('int_theta_dot', [0.0, 0.0], units='deg/s')
+        phase.set_polynomial_control_val('theta', 45.0, units='deg')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=True)
@@ -773,41 +766,17 @@ def _test_transcription(self, transcription=dm.GaussLobatto, time_name='time'):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
-
-        p.set_val('traj.phase0.parameters:one', 1.0)
-
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]), units='m')
-
-        p.set_val('traj.phase0.states:y',
-                  phase.interp('y', [10, 5]),
-                  units='m')
-
-        p.set_val('traj.phase0.states:v',
-                  phase.interp('v', [0, 5]),
-                  units='m/s')
-
-        p.set_val('traj.phase0.controls:theta',
-                  phase.interp('theta', [0.1, 45], nodes='control_input'),
-                  units='deg')
-
-        # Additional states to test rate sources
-        p.set_val('traj.phase0.states:int_one',
-                  phase.interp('int_one', [0, 10]),
-                  units='s')
-
-        p.set_val('traj.phase0.states:int_time',
-                  phase.interp('int_time', [0, 10]),
-                  units='s**2')
-
-        p.set_val('traj.phase0.states:int_time_phase',
-                  phase.interp('int_time_phase', [0, 10]),
-                  units='s**2')
-
-        p.set_val('traj.phase0.states:int_int_one',
-                  phase.interp('int_int_one', [0, 10]),
-                  units='s**2')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
+
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_state_val('int_one', [0, 10], units='s')
+        phase.set_state_val('int_int_one', [0, 10], units='s**2')
+        phase.set_state_val('int_time', [0, 10], units='s**2')
+        phase.set_state_val('int_time_phase', [0, 10], units='s**2')
+        phase.set_control_val('theta', [0.1, 45], units='deg')
+        phase.set_parameter_val('one', 1.0)
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True)
diff --git a/dymos/examples/brachistochrone/test/test_static_outputs.py b/dymos/examples/brachistochrone/test/test_static_outputs.py
index 56c19feba..b60f084ef 100644
--- a/dymos/examples/brachistochrone/test/test_static_outputs.py
+++ b/dymos/examples/brachistochrone/test/test_static_outputs.py
@@ -127,24 +127,12 @@ def _test_static_ode_output(self, transcription):
 
         # Now that the OpenMDAO problem is setup, we can set the values of the states.
 
-        p.set_val('traj.phase0.t_initial', 0.0, units='s')
-        p.set_val('traj.phase0.t_duration', 5.0, units='s')
+        phase.set_time_val(initial=0.0, duration=5.0, units='s')
 
-        p.set_val('traj.phase0.states:x',
-                  phase.interp('x', [0, 10]),
-                  units='m')
-
-        p.set_val('traj.phase0.states:y',
-                  phase.interp('y', [10, 5]),
-                  units='m')
-
-        p.set_val('traj.phase0.states:v',
-                  phase.interp('v', [0, 5]),
-                  units='m/s')
-
-        p.set_val('traj.phase0.controls:theta',
-                  phase.interp('theta', [0.01, 90]),
-                  units='deg')
+        phase.set_state_val('x', [0, 10], units='m')
+        phase.set_state_val('y', [10, 5], units='m')
+        phase.set_state_val('v', [0, 5], units='m/s')
+        phase.set_control_val('theta', [1, 90], units='deg')
 
         # Run the driver to solve the problem
         dm.run_problem(p, simulate=True, make_plots=False)
diff --git a/dymos/examples/brachistochrone/test/test_tandem_phases.py b/dymos/examples/brachistochrone/test/test_tandem_phases.py
index 86ac656bc..21f74e8da 100644
--- a/dymos/examples/brachistochrone/test/test_tandem_phases.py
+++ b/dymos/examples/brachistochrone/test/test_tandem_phases.py
@@ -151,16 +151,16 @@ def _run_transcription(self, transcription):
         p.model.linear_solver = om.DirectSolver()
         p.setup(check=True)
 
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 2.0
+        phase0.set_time_val(initial=0.0, duration=2.0)
 
-        p['phase0.states:x'] = phase0.interp('x', ys=[0, 10])
-        p['phase0.states:y'] = phase0.interp('y', ys=[10, 5])
-        p['phase0.states:v'] = phase0.interp('v', ys=[0, 9.9])
-        p['phase0.controls:theta'] = phase0.interp('theta', ys=[5, 100])
-        p['phase0.parameters:g'] = 9.80665
+        phase0.set_state_val('x', [0, 10])
+        phase0.set_state_val('y', [10, 5])
+        phase0.set_state_val('v', [0, 9.9])
 
-        p['phase1.states:S'] = 0.0
+        phase0.set_control_val('theta', [5, 100])
+        phase0.set_parameter_val('g', 9.80665)
+
+        phase1.set_state_val('S', 0.0)
 
         p.run_driver()
 
diff --git a/dymos/examples/brachistochrone/test/test_timeseries_units.py b/dymos/examples/brachistochrone/test/test_timeseries_units.py
index d27ba13be..e1c152762 100644
--- a/dymos/examples/brachistochrone/test/test_timeseries_units.py
+++ b/dymos/examples/brachistochrone/test/test_timeseries_units.py
@@ -79,14 +79,14 @@ def ode(num_nodes):
 
         p.setup(check=['unconnected_inputs'], force_alloc_complex=force_alloc_complex)
 
-        p['traj0.phase0.t_initial'] = 0.0
-        p['traj0.phase0.t_duration'] = 2.0
-
-        p['traj0.phase0.states:x'] = phase.interp('x', [0, 10])
-        p['traj0.phase0.states:y'] = phase.interp('y', [10, 5])
-        p['traj0.phase0.states:v'] = phase.interp('v', [0, 9.9])
-        p['traj0.phase0.controls:theta'] = phase.interp('theta', [5, 100])
-        p['traj0.phase0.parameters:g'] = 9.80665
+        phase.set_time_val(initial=0.0, duration=2.0)
+
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         dm.run_problem(p, run_driver=run_driver, simulate=True)
 
diff --git a/dymos/examples/cannonball/doc/test_doc_cannonball_implicit_duration.py b/dymos/examples/cannonball/doc/test_doc_cannonball_implicit_duration.py
index fe61c2514..194dd79b5 100644
--- a/dymos/examples/cannonball/doc/test_doc_cannonball_implicit_duration.py
+++ b/dymos/examples/cannonball/doc/test_doc_cannonball_implicit_duration.py
@@ -226,13 +226,12 @@ def compute(self, inputs, outputs):
 
         guess = initial_guess(t_dur=30.0)
 
-        p.set_val('traj.phase.t_initial', 0.0)
-        p.set_val('traj.phase.t_duration', 30.0)
+        phase.set_time_val(initial=0.0, duration=30.0)
 
-        p.set_val('traj.phase.states:r', phase.interp('r', ys=guess['r'], xs=guess['t']))
-        p.set_val('traj.phase.states:h', phase.interp('h', ys=guess['h'], xs=guess['t']))
-        p.set_val('traj.phase.states:v', phase.interp('v', ys=guess['v'], xs=guess['t']))
-        p.set_val('traj.phase.states:gam', phase.interp('gam', ys=guess['gam'], xs=guess['t']), units='rad')
+        phase.set_state_val('r', vals=guess['r'], time_vals=guess['t'])
+        phase.set_state_val('h', vals=guess['h'], time_vals=guess['t'])
+        phase.set_state_val('v', vals=guess['v'], time_vals=guess['t'])
+        phase.set_state_val('gam', vals=guess['gam'], time_vals=guess['t'], units='rad')
 
         #####################################################
         # Run the optimization and final explicit simulation
diff --git a/dymos/examples/cannonball/doc/test_doc_two_phase_cannonball.py b/dymos/examples/cannonball/doc/test_doc_two_phase_cannonball.py
index 80fa11393..96909213e 100644
--- a/dymos/examples/cannonball/doc/test_doc_two_phase_cannonball.py
+++ b/dymos/examples/cannonball/doc/test_doc_two_phase_cannonball.py
@@ -231,23 +231,21 @@ def compute(self, inputs, outputs):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         #####################################################
         # Run the optimization and final explicit simulation
diff --git a/dymos/examples/cannonball/test/test_cannonball_connected_initial_states.py b/dymos/examples/cannonball/test/test_cannonball_connected_initial_states.py
index 2e93d3e16..9e46256ec 100644
--- a/dymos/examples/cannonball/test/test_cannonball_connected_initial_states.py
+++ b/dymos/examples/cannonball/test/test_cannonball_connected_initial_states.py
@@ -32,7 +32,8 @@ def test_cannonball_connected_initial_states(self):
         p.model.add_design_var('radius', lower=0.01, upper=0.10,
                                ref0=0.01, ref=0.10, units='m')
 
-        traj = p.model.add_subsystem('traj', dm.Trajectory())
+        traj = dm.Trajectory()
+        p.model.add_subsystem('traj', traj)
 
         transcription = dm.Radau(num_segments=5, order=3, compressed=True)
         ascent = dm.Phase(ode_class=CannonballODE, transcription=transcription)
@@ -98,23 +99,21 @@ def test_cannonball_connected_initial_states(self):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp(ys=[0, 100], nodes='state_input'))
-        p.set_val('traj.ascent.states:h', ascent.interp(ys=[0, 100], nodes='state_input'))
-        p.set_val('traj.ascent.states:v', ascent.interp(ys=[200, 150], nodes='state_input'))
-        p.set_val('traj.ascent.states:gam', ascent.interp(ys=[25, 0], nodes='state_input'), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp(ys=[100, 200], nodes='state_input'))
-        p.set_val('traj.descent.states:h', descent.interp(ys=[100, 0], nodes='state_input'))
-        p.set_val('traj.descent.states:v', descent.interp(ys=[150, 200], nodes='state_input'))
-        p.set_val('traj.descent.states:gam', descent.interp(ys=[0, -45], nodes='state_input'), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         # Run the optimization and final explicit simulation
         dm.run_problem(p)
diff --git a/dymos/examples/cannonball/test/test_cannonball_expr_constraint.py b/dymos/examples/cannonball/test/test_cannonball_expr_constraint.py
index bff64e4f8..fa8f5b497 100644
--- a/dymos/examples/cannonball/test/test_cannonball_expr_constraint.py
+++ b/dymos/examples/cannonball/test/test_cannonball_expr_constraint.py
@@ -97,23 +97,21 @@ def test_cannonball_design_boundary_constraint_expression(self):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp(ys=[0, 100], nodes='state_input'))
-        p.set_val('traj.ascent.states:h', ascent.interp(ys=[0, 100], nodes='state_input'))
-        p.set_val('traj.ascent.states:v', ascent.interp(ys=[200, 150], nodes='state_input'))
-        p.set_val('traj.ascent.states:gam', ascent.interp(ys=[25, 0], nodes='state_input'), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp(ys=[100, 200], nodes='state_input'))
-        p.set_val('traj.descent.states:h', descent.interp(ys=[100, 0], nodes='state_input'))
-        p.set_val('traj.descent.states:v', descent.interp(ys=[150, 200], nodes='state_input'))
-        p.set_val('traj.descent.states:gam', descent.interp(ys=[0, -45], nodes='state_input'), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         # Run the optimization and final explicit simulation
         dm.run_problem(p)
diff --git a/dymos/examples/cannonball/test/test_cannonball_matrix_state.py b/dymos/examples/cannonball/test/test_cannonball_matrix_state.py
index bc81b522d..cd20cb848 100644
--- a/dymos/examples/cannonball/test/test_cannonball_matrix_state.py
+++ b/dymos/examples/cannonball/test/test_cannonball_matrix_state.py
@@ -55,12 +55,8 @@ def _make_problem(self, tx):
 
         p.setup()
 
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 5)
-        if isinstance(tx, dm.Birkhoff):
-            p.set_val('traj.phase.initial_states:z', np.array([[0, 0], [10, 10]]))
-            p.set_val('traj.phase.final_states:z', np.array([[10, 0], [10, -10]]))
-        p.set_val('traj.phase.states:z', phase.interp('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]]))
+        phase.set_time_val(initial=0, duration=5)
+        phase.set_state_val('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]])
 
         return p
 
@@ -204,10 +200,8 @@ def _make_problem(self, tx):
 
         p.setup()
 
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 5)
-        p.set_val('traj.phase.states:z',
-                  phase.interp('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]]))
+        phase.set_time_val(initial=0, duration=5)
+        phase.set_state_val('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]])
 
         return p
 
@@ -310,10 +304,8 @@ def _make_problem(self, tx):
 
         p.setup()
 
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 5)
-        p.set_val('traj.phase.states:z',
-                  phase.interp('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]]))
+        phase.set_time_val(initial=0, duration=5)
+        phase.set_state_val('z', [[[0, 0], [10, 10]], [[10, 0], [10, -10]]])
 
         return p
 
diff --git a/dymos/examples/cannonball/test/test_connect_control_to_parameter.py b/dymos/examples/cannonball/test/test_connect_control_to_parameter.py
index f447bb770..d0c925451 100644
--- a/dymos/examples/cannonball/test/test_connect_control_to_parameter.py
+++ b/dymos/examples/cannonball/test/test_connect_control_to_parameter.py
@@ -182,23 +182,21 @@ def test_connect_control_to_parameter(self):
         p.set_val('external_params.radius', 0.05, units='m')
         p.set_val('external_params.dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.ascent.controls:CD', 0.5)
+        ascent.set_control_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p, simulate=True, make_plots=True)
 
diff --git a/dymos/examples/cannonball/test/test_load_case_missing_phase.py b/dymos/examples/cannonball/test/test_load_case_missing_phase.py
index b3f516d24..613727220 100644
--- a/dymos/examples/cannonball/test/test_load_case_missing_phase.py
+++ b/dymos/examples/cannonball/test/test_load_case_missing_phase.py
@@ -116,24 +116,24 @@ def test_load_case_missing_phase(self):
 
         p_ascent_only.setup()
 
-        ascent = p_ascent_only.model.traj.phases.ascent
+        traj = p_ascent_only.model.traj
+        ascent = traj.phases.ascent
 
         # Set pre-trajectory values
         p_ascent_only.set_val('radius', 0.05, units='m')
         p_ascent_only.set_val('dens', 7.87, units='g/cm**3')
 
         # Trajectory parameters
-        p_ascent_only.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
         # Phase ascent times
-        p_ascent_only.set_val('traj.ascent.t_initial', 0.0)
-        p_ascent_only.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
         # Phase ascent state guesses
-        p_ascent_only.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p_ascent_only.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p_ascent_only.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p_ascent_only.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
         dm.run_problem(p_ascent_only)
 
@@ -149,25 +149,24 @@ def test_load_case_missing_phase(self):
         p.set_val('dens', 7.87, units='g/cm**3')
 
         # Trajectory parameters
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        # Phase ascent times
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
         # Phase ascent state guesses
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
-
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
-
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
+
+        # Phase descent times
+        descent.set_time_val(initial=10.0, duration=10.0)
+
+        # Phase descent state guesses
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         case = om.CaseReader('dymos_solution.db').get_case('final')
         if om_version < (3, 26, 1):
diff --git a/dymos/examples/cannonball/test/test_traj_param_static_and_dynamic.py b/dymos/examples/cannonball/test/test_traj_param_static_and_dynamic.py
index d717576b8..4be60db40 100644
--- a/dymos/examples/cannonball/test/test_traj_param_static_and_dynamic.py
+++ b/dymos/examples/cannonball/test/test_traj_param_static_and_dynamic.py
@@ -191,23 +191,21 @@ def test_traj_param_static_and_dynamic(self):
         p.set_val('external_params.radius', 0.05, units='m')
         p.set_val('external_params.dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.ascent.controls:CD', 0.5)
+        ascent.set_control_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p, simulate=True, make_plots=True)
 
diff --git a/dymos/examples/cannonball/test/test_two_phase_cannonball_birkhoff.py b/dymos/examples/cannonball/test/test_two_phase_cannonball_birkhoff.py
index 29c6e2740..cd2b3097d 100644
--- a/dymos/examples/cannonball/test/test_two_phase_cannonball_birkhoff.py
+++ b/dymos/examples/cannonball/test/test_two_phase_cannonball_birkhoff.py
@@ -145,7 +145,8 @@ def make_problem(self, connected=False):
         p.model.add_design_var('radius', lower=0.01, upper=0.10,
                                ref0=0.01, ref=0.10, units='m')
 
-        traj = p.model.add_subsystem('traj', dm.Trajectory())
+        traj = dm.Trajectory()
+        p.model.add_subsystem('traj', traj)
 
         transcription = dm.Birkhoff(grid=dm.BirkhoffGrid(num_nodes=10))
         ascent = dm.Phase(ode_class=CannonballODE, transcription=transcription)
@@ -229,27 +230,21 @@ def make_problem(self, connected=False):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.initial_states:r', 0.0)
-        p.set_val('traj.ascent.initial_states:h', 0.0)
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
-        p.set_val('traj.ascent.final_states:gam', 0.0, units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
-        p.set_val('traj.descent.final_states:h', 0.0)
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p)
         assert_near_equal(p.get_val('traj.descent.states:r')[-1],
diff --git a/dymos/examples/cannonball/test/test_two_phase_cannonball_ode_output_linkage.py b/dymos/examples/cannonball/test/test_two_phase_cannonball_ode_output_linkage.py
index c0f1a579a..880355651 100644
--- a/dymos/examples/cannonball/test/test_two_phase_cannonball_ode_output_linkage.py
+++ b/dymos/examples/cannonball/test/test_two_phase_cannonball_ode_output_linkage.py
@@ -109,23 +109,21 @@ def test_two_phase_cannonball_ode_output_linkage(self):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p)
 
@@ -241,23 +239,21 @@ def test_traj_param_target_none(self):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p)
 
@@ -362,23 +358,21 @@ def test_traj_param_target_unspecified_units(self):
         p.set_val('radius', 0.05, units='m')
         p.set_val('dens', 7.87, units='g/cm**3')
 
-        p.set_val('traj.parameters:CD', 0.5)
+        traj.set_parameter_val('CD', 0.5)
 
-        p.set_val('traj.ascent.t_initial', 0.0)
-        p.set_val('traj.ascent.t_duration', 10.0)
+        ascent.set_time_val(initial=0.0, duration=10.0)
 
-        p.set_val('traj.ascent.states:r', ascent.interp('r', [0, 100]))
-        p.set_val('traj.ascent.states:h', ascent.interp('h', [0, 100]))
-        p.set_val('traj.ascent.states:v', ascent.interp('v', [200, 150]))
-        p.set_val('traj.ascent.states:gam', ascent.interp('gam', [25, 0]), units='deg')
+        ascent.set_state_val('r', [0, 100])
+        ascent.set_state_val('h', [0, 100])
+        ascent.set_state_val('v', [200, 150])
+        ascent.set_state_val('gam', [25, 0], units='deg')
 
-        p.set_val('traj.descent.t_initial', 10.0)
-        p.set_val('traj.descent.t_duration', 10.0)
+        descent.set_time_val(initial=10.0, duration=10.0)
 
-        p.set_val('traj.descent.states:r', descent.interp('r', [100, 200]))
-        p.set_val('traj.descent.states:h', descent.interp('h', [100, 0]))
-        p.set_val('traj.descent.states:v', descent.interp('v', [150, 200]))
-        p.set_val('traj.descent.states:gam', descent.interp('gam', [0, -45]), units='deg')
+        descent.set_state_val('r', [100, 200])
+        descent.set_state_val('h', [100, 0])
+        descent.set_state_val('v', [150, 200])
+        descent.set_state_val('gam', [0, -45], units='deg')
 
         dm.run_problem(p)
 
diff --git a/dymos/examples/cart_pole/test/test_cartpole_opt.py b/dymos/examples/cart_pole/test/test_cartpole_opt.py
index 63e193f7f..a63237316 100644
--- a/dymos/examples/cart_pole/test/test_cartpole_opt.py
+++ b/dymos/examples/cart_pole/test/test_cartpole_opt.py
@@ -82,13 +82,13 @@ def test_optimization(self):
         # --- set initial guess ---
         # The initial condition of cart-pole (i.e., state values at time 0) is set here
         # because we set `fix_initial=True` when declaring the states.
-        p.set_val("traj.phase.t_initial", 0.0)  # set initial time to 0.
-        p.set_val("traj.phase.states:x", phase.interp(xs=[0, 1, 2], ys=[0, 1, 1], nodes="state_input"), units="m")
-        p.set_val("traj.phase.states:x_dot", phase.interp(xs=[0, 1, 2], ys=[0, 0.1, 0], nodes="state_input"), units="m/s")
-        p.set_val("traj.phase.states:theta", phase.interp(xs=[0, 1, 2], ys=[0, np.pi/2, np.pi], nodes="state_input"), units="rad")
-        p.set_val("traj.phase.states:theta_dot", phase.interp(xs=[0, 1, 2], ys=[0, 1, 0], nodes="state_input"), units="rad/s")
-        p.set_val("traj.phase.states:energy", phase.interp(xs=[0, 1, 2], ys=[0, 30, 60], nodes="state_input"))
-        p.set_val("traj.phase.controls:f", phase.interp(xs=[0, 1, 2], ys=[3, -1, 0], nodes="control_input"), units="N")
+        phase.set_time_val(initial=0.0)  # set initial time to 0.
+        phase.set_state_val('x', vals=[0, 1, 1], time_vals=[0, 1, 2], units='m')
+        phase.set_state_val('x_dot', vals=[0, 0.1, 0], time_vals=[0, 1, 2], units='m/s')
+        phase.set_state_val('theta', vals=[0, np.pi/2, np.pi], time_vals=[0, 1, 2], units='rad')
+        phase.set_state_val('theta_dot', vals=[0, 1, 0], time_vals=[0, 1, 2], units='rad/s')
+        phase.set_state_val('energy', vals=[0, 30, 60], time_vals=[0, 1, 2])
+        phase.set_control_val('f', vals=[3, -1, 0], time_vals=[0, 1, 2], units='N')
 
         # --- run optimization ---
         dm.run_problem(p, run_driver=True, simulate=False, simulate_kwargs={"method": "Radau", "times_per_seg": 10})
diff --git a/dymos/examples/double_integrator/doc/test_doc_double_integrator.py b/dymos/examples/double_integrator/doc/test_doc_double_integrator.py
index 06877c0e4..8e3dbbe26 100644
--- a/dymos/examples/double_integrator/doc/test_doc_double_integrator.py
+++ b/dymos/examples/double_integrator/doc/test_doc_double_integrator.py
@@ -68,12 +68,10 @@ def test_double_integrator_for_docs(self):
         #
         p.setup(check=True)
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 1.0
-
-        p.set_val('traj.phase0.states:x', phase.interp('x', ys=[0, 0.25]))
-        p.set_val('traj.phase0.states:v', phase.interp('v', ys=[0, 0]))
-        p.set_val('traj.phase0.controls:u', phase.interp('u', ys=[1, -1]))
+        phase.set_time_val(initial=0.0, duration=1.0)
+        phase.set_state_val('x', [0, 0.25])
+        phase.set_state_val('v', [0, 0])
+        phase.set_control_val('u', [1, -1])
 
         #
         # Solve the problem.
diff --git a/dymos/examples/double_integrator/test/test_double_integrator.py b/dymos/examples/double_integrator/test/test_double_integrator.py
index 30f98222b..02b2c5e97 100644
--- a/dymos/examples/double_integrator/test/test_double_integrator.py
+++ b/dymos/examples/double_integrator/test/test_double_integrator.py
@@ -52,17 +52,10 @@ def double_integrator(transcription='gauss-lobatto', compressed=True, grid_type=
 
     p.setup(check=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 1.0
-
-    p['traj.phase0.states:x'] = phase.interp('x', [0, 0.25])
-    p['traj.phase0.states:v'] = phase.interp('v', [0, 0])
-    p['traj.phase0.controls:u'] = phase.interp('u', [1, -1])
-
-    if transcription == 'birkhoff':
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:v'] = 0.0
-        p['traj.phase0.final_states:v'] = 0.0
+    phase.set_time_val(initial=0.0, duration=1.0)
+    phase.set_state_val('x', [0, 0.25])
+    phase.set_state_val('v', [0, 0])
+    phase.set_control_val('u', [1, -1])
 
     simulate_kwargs = {'times_per_seg': 100 if transcription == 'birkhoff' else 10}
     dm.run_problem(p, simulate=False, make_plots=True, simulate_kwargs=simulate_kwargs)
@@ -219,9 +212,9 @@ def test_ex_double_integrator_input_times_compressed(self):
         p['t0'] = 0.0
         p['tp'] = 1.0
 
-        p['phase0.states:x'] = phase.interp('x', [0, 0.25])
-        p['phase0.states:v'] = phase.interp('v', [0, 0])
-        p['phase0.controls:u'] = phase.interp('u', [1, -1])
+        phase.set_state_val('x', [0, 0.25])
+        phase.set_state_val('v', [0, 0])
+        phase.set_control_val('u', [1, -1])
 
         p.run_driver()
 
diff --git a/dymos/examples/double_integrator/test/test_double_integrator_breakwell.py b/dymos/examples/double_integrator/test/test_double_integrator_breakwell.py
index d05e2262b..c314b3fb3 100644
--- a/dymos/examples/double_integrator/test/test_double_integrator_breakwell.py
+++ b/dymos/examples/double_integrator/test/test_double_integrator_breakwell.py
@@ -66,16 +66,11 @@ def double_integrator_direct_collocation(transcription='gauss-lobatto', compress
 
     p.setup(check=True, force_alloc_complex=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 1.0
-    p['traj.phase0.states:x'] = phase.interp('x', [0, 0])
-    p['traj.phase0.states:v'] = phase.interp('v', [1, 0])
-    p['traj.phase0.states:J'] = phase.interp('J', [0, 4])
-    p['traj.phase0.controls:u'] = phase.interp('u', [-5, -5])
-    if transcription == 'birkhoff':
-        p['traj.phase0.initial_states:x'] = 0.0
-        p['traj.phase0.initial_states:v'] = 1.0
-        p['traj.phase0.initial_states:J'] = 0.0
+    phase.set_time_val(initial=0.0, duration=1.0)
+    phase.set_state_val('x', [0, 0])
+    phase.set_state_val('v', [1, 0])
+    phase.set_state_val('J', [0, 4])
+    phase.set_control_val('u', [-5, -5])
 
     return p
 
diff --git a/dymos/examples/double_integrator/test/test_double_integrator_timeseries_units.py b/dymos/examples/double_integrator/test/test_double_integrator_timeseries_units.py
index 376991054..de5b7d259 100644
--- a/dymos/examples/double_integrator/test/test_double_integrator_timeseries_units.py
+++ b/dymos/examples/double_integrator/test/test_double_integrator_timeseries_units.py
@@ -43,12 +43,10 @@ def double_integrator_direct_collocation(transcription=dm.GaussLobatto, compress
 
     p.setup(check=True)
 
-    p.set_val('traj.phase0.t_initial', 0.0)
-    p.set_val('traj.phase0.t_duration', 1.0)
-
-    p.set_val('traj.phase0.states:x', phase.interp('x', [0, 0.25]), units='m')
-    p.set_val('traj.phase0.states:v', phase.interp('v', [0, 0]), units='m/s')
-    p.set_val('traj.phase0.controls:u', phase.interp('u', [1, -1]), units='m/s**2')
+    phase.set_time_val(initial=0.0, duration=1.0, units='s')
+    phase.set_state_val('x', [0, 0.25], units='m')
+    phase.set_state_val('v', [0, 0], units='m/s')
+    phase.set_control_val('u', [1, -1], units='m/s**2')
 
     dm.run_problem(p, simulate=True, make_plots=True, simulate_kwargs={'times_per_seg': 10})
 
diff --git a/dymos/examples/finite_burn_orbit_raise/doc/test_doc_finite_burn_orbit_raise.py b/dymos/examples/finite_burn_orbit_raise/doc/test_doc_finite_burn_orbit_raise.py
index bb956b7b4..672b7b5f6 100644
--- a/dymos/examples/finite_burn_orbit_raise/doc/test_doc_finite_burn_orbit_raise.py
+++ b/dymos/examples/finite_burn_orbit_raise/doc/test_doc_finite_burn_orbit_raise.py
@@ -133,42 +133,36 @@ def test_finite_burn_orbit_raise(self):
         p.setup(check=True, mode='fwd')
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5, units='DU/TU')
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
 
         burn1 = p.model.traj.phases.burn1
         burn2 = p.model.traj.phases.burn2
         coast = p.model.traj.phases.coast
 
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]))
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1, 3.]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [0, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [0, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3.)]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [0, 0]))
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1, 3])
+        burn2.set_state_val('theta', [0, 4])
+        burn2.set_state_val('vr', [0, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [0, 0])
 
         dm.run_problem(p)
 
diff --git a/dymos/examples/finite_burn_orbit_raise/test/test_ex_two_burn_orbit_raise_bokeh_plots.py b/dymos/examples/finite_burn_orbit_raise/test/test_ex_two_burn_orbit_raise_bokeh_plots.py
index c1fe0be7d..90331500b 100644
--- a/dymos/examples/finite_burn_orbit_raise/test/test_ex_two_burn_orbit_raise_bokeh_plots.py
+++ b/dymos/examples/finite_burn_orbit_raise/test/test_ex_two_burn_orbit_raise_bokeh_plots.py
@@ -4,199 +4,26 @@
 import unittest
 import pathlib
 
-import numpy as np
-
 try:
     import matplotlib
 except ImportError:
     matplotlib = None
 
-import openmdao.api as om
 from openmdao.utils.testing_utils import require_pyoptsparse
 from openmdao.utils.general_utils import set_pyoptsparse_opt
 from openmdao.utils.testing_utils import use_tempdirs
 
 
 import dymos as dm
-from dymos.examples.finite_burn_orbit_raise.finite_burn_eom import FiniteBurnODE
+from dymos.examples.finite_burn_orbit_raise.finite_burn_orbit_raise_problem import two_burn_orbit_raise_problem
 from dymos.utils.testing_utils import _get_reports_dir
 
 _, optimizer = set_pyoptsparse_opt('IPOPT', fallback=True)
 bokeh_available = importlib.util.find_spec('bokeh') is not None
 
 
-def make_traj(transcription='gauss-lobatto', transcription_order=3, compressed=False):
-
-    t = {'gauss-lobatto': dm.GaussLobatto(num_segments=5, order=transcription_order, compressed=compressed),
-         'radau': dm.Radau(num_segments=20, order=transcription_order, compressed=compressed)}
-
-    traj = dm.Trajectory()
-
-    traj.add_parameter('c', opt=False, val=1.5, units='DU/TU',
-                       targets={'burn1': ['c'], 'burn2': ['c']})
-
-    # First Phase (burn)
-
-    burn1 = dm.Phase(ode_class=FiniteBurnODE, transcription=t[transcription])
-
-    burn1 = traj.add_phase('burn1', burn1)
-
-    burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10), units='TU')
-    burn1.add_state('r', fix_initial=True, fix_final=False, defect_scaler=100.0,
-                    rate_source='r_dot', units='DU')
-    burn1.add_state('theta', fix_initial=True, fix_final=False, defect_scaler=100.0,
-                    rate_source='theta_dot', units='rad')
-    burn1.add_state('vr', fix_initial=True, fix_final=False, defect_scaler=100.0,
-                    rate_source='vr_dot', units='DU/TU')
-    burn1.add_state('vt', fix_initial=True, fix_final=False, defect_scaler=100.0,
-                    rate_source='vt_dot', units='DU/TU')
-    burn1.add_state('accel', fix_initial=True, fix_final=False,
-                    rate_source='at_dot', units='DU/TU**2')
-    burn1.add_state('deltav', fix_initial=True, fix_final=False,
-                    rate_source='deltav_dot', units='DU/TU')
-    burn1.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg', scaler=0.01,
-                      rate_continuity_scaler=0.001, rate2_continuity_scaler=0.001,
-                      lower=-30, upper=30)
-    # Second Phase (Coast)
-    coast = dm.Phase(ode_class=FiniteBurnODE, transcription=t[transcription])
-
-    coast.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 50), duration_ref=50, units='TU')
-    coast.add_state('r', fix_initial=False, fix_final=False, defect_scaler=100.0,
-                    rate_source='r_dot', units='DU')
-    coast.add_state('theta', fix_initial=False, fix_final=False, defect_scaler=100.0,
-                    rate_source='theta_dot', units='rad')
-    coast.add_state('vr', fix_initial=False, fix_final=False, defect_scaler=100.0,
-                    rate_source='vr_dot', units='DU/TU')
-    coast.add_state('vt', fix_initial=False, fix_final=False, defect_scaler=100.0,
-                    rate_source='vt_dot', units='DU/TU')
-    coast.add_state('accel', fix_initial=True, fix_final=True,
-                    rate_source='at_dot', units='DU/TU**2')
-    coast.add_state('deltav', fix_initial=False, fix_final=False,
-                    rate_source='deltav_dot', units='DU/TU')
-
-    coast.add_parameter('u1', opt=False, val=0.0, units='deg')
-    coast.add_parameter('c', val=0.0, units='DU/TU')
-
-    # Third Phase (burn)
-    burn2 = dm.Phase(ode_class=FiniteBurnODE, transcription=t[transcription])
-
-    traj.add_phase('coast', coast)
-    traj.add_phase('burn2', burn2)
-
-    burn2.set_time_options(initial_bounds=(0.5, 50), duration_bounds=(.5, 10), initial_ref=10, units='TU')
-    burn2.add_state('r', fix_initial=False, fix_final=True, defect_scaler=100.0,
-                    rate_source='r_dot', targets=['r'], units='DU')
-    burn2.add_state('theta', fix_initial=False, fix_final=False, defect_scaler=100.0,
-                    rate_source='theta_dot', targets=['theta'], units='rad')
-    burn2.add_state('vr', fix_initial=False, fix_final=True, defect_scaler=1000.0,
-                    rate_source='vr_dot', targets=['vr'], units='DU/TU')
-    burn2.add_state('vt', fix_initial=False, fix_final=True, defect_scaler=1000.0,
-                    rate_source='vt_dot', targets=['vt'], units='DU/TU')
-    burn2.add_state('accel', fix_initial=False, fix_final=False, defect_scaler=1.0,
-                    rate_source='at_dot', targets=['accel'], units='DU/TU**2')
-    burn2.add_state('deltav', fix_initial=False, fix_final=False, defect_scaler=1.0,
-                    rate_source='deltav_dot', units='DU/TU')
-
-    burn2.add_objective('deltav', loc='final', scaler=100.0)
-
-    burn2.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg',
-                      scaler=0.01, lower=-180, upper=180, targets=['u1'])
-
-    burn1.add_timeseries_output('pos_x')
-    coast.add_timeseries_output('pos_x')
-    burn2.add_timeseries_output('pos_x')
-
-    burn1.add_timeseries_output('pos_y')
-    coast.add_timeseries_output('pos_y')
-    burn2.add_timeseries_output('pos_y')
-
-    traj.link_phases(phases=['burn1', 'coast', 'burn2'],
-                     vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav'])
-
-    traj.link_phases(phases=['burn1', 'burn2'], vars=['accel'])
-
-    return traj
-
-
-@require_pyoptsparse(optimizer='SLSQP')
-def two_burn_orbit_raise_problem(transcription='gauss-lobatto', optimizer='SLSQP', r_target=3.0,
-                                 transcription_order=3, compressed=False,
-                                 show_output=True):
-
-    p = om.Problem(model=om.Group())
-
-    p.driver = om.pyOptSparseDriver()
-    p.driver.options['optimizer'] = optimizer
-    p.driver.declare_coloring()
-    if optimizer == 'SNOPT':
-        p.driver.opt_settings['Major iterations limit'] = 100
-        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
-        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
-        if show_output:
-            p.driver.opt_settings['iSumm'] = 6
-    elif optimizer == 'IPOPT':
-        p.driver.opt_settings['hessian_approximation'] = 'limited-memory'
-        p.driver.opt_settings['nlp_scaling_method'] = 'gradient-based'
-        p.driver.opt_settings['print_level'] = 0
-        p.driver.opt_settings['linear_solver'] = 'mumps'
-        p.driver.opt_settings['mu_strategy'] = 'adaptive'
-
-    traj = make_traj(transcription=transcription, transcription_order=transcription_order,
-                     compressed=compressed)
-    p.model.add_subsystem('traj', subsys=traj)
-
-    # Needed to move the direct solver down into the phases for use with MPI.
-    #  - After moving down, used fewer iterations (about 30 less)
-
-    p.setup(check=True)
-
-    # Set Initial Guesses
-    p.set_val('traj.parameters:c', val=1.5, units='DU/TU')
-
-    burn1 = p.model.traj.phases.burn1
-    burn2 = p.model.traj.phases.burn2
-    coast = p.model.traj.phases.coast
-
-    if burn1 in p.model.traj.phases._subsystems_myproc:
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]))
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-    if coast in p.model.traj.phases._subsystems_myproc:
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-    if burn2 in p.model.traj.phases._subsystems_myproc:
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [0, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [0, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
-
-    dm.run_problem(p, run_driver=False, simulate=True, make_plots=True)
-
-    return p
-
-
 @use_tempdirs
+@require_pyoptsparse(optimizer='SLSQP')
 class TestExampleTwoBurnOrbitRaise(unittest.TestCase):
 
     def setUp(self):
@@ -217,7 +44,8 @@ def test_bokeh_plots(self):
         dm.options['plots'] = 'bokeh'
 
         p = two_burn_orbit_raise_problem(transcription='gauss-lobatto', transcription_order=3,
-                                         compressed=False, optimizer='SLSQP', show_output=False)
+                                         compressed=False, optimizer='SLSQP', show_output=False,
+                                         run_driver=False)
 
         html_file = pathlib.Path(_get_reports_dir(p)) / 'traj_results_report.html'
         self.assertTrue(html_file.exists(), msg=f'{html_file} does not exist!')
@@ -227,7 +55,8 @@ def test_mpl_plots(self):
         dm.options['plots'] = 'matplotlib'
 
         p = two_burn_orbit_raise_problem(transcription='gauss-lobatto', transcription_order=3,
-                                         compressed=False, optimizer='SLSQP', show_output=False)
+                                         compressed=False, optimizer='SLSQP', show_output=False,
+                                         run_driver=False)
 
         expected_files = ('deltav.png', 'r.png', 'accel.png',
                           'u1.png', 'vr.png', 'pos_x.png',
diff --git a/dymos/examples/finite_burn_orbit_raise/test/test_two_burn_orbit_raise_linkages.py b/dymos/examples/finite_burn_orbit_raise/test/test_two_burn_orbit_raise_linkages.py
index a435f4f8b..240df462c 100644
--- a/dymos/examples/finite_burn_orbit_raise/test/test_two_burn_orbit_raise_linkages.py
+++ b/dymos/examples/finite_burn_orbit_raise/test/test_two_burn_orbit_raise_linkages.py
@@ -354,38 +354,32 @@ def test_two_burn_orbit_raise_gl_radau_gl_constrained(self):
         p.setup(check=True, force_alloc_complex=True)
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5)
-
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]), )
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1.8, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [3.2, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [.5, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
+
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1, 3])
+        burn2.set_state_val('theta', [0, 4])
+        burn2.set_state_val('vr', [0.5, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [1, 1])
 
         p.run_driver()
 
@@ -588,38 +582,32 @@ def test_two_burn_orbit_raise_link_control_to_param(self):
             p.setup(check=True, force_alloc_complex=True)
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5)
-
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]), )
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1.8, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [3.2, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [.5, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
+
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1.8, 3])
+        burn2.set_state_val('theta', [3.2, 4.0])
+        burn2.set_state_val('vr', [0.5, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [1, 1])
 
         p.run_driver()
 
@@ -750,38 +738,32 @@ def test_two_burn_orbit_raise_gl_list_add_timeseries_output(self):
         p.setup(check=True, force_alloc_complex=True)
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5)
-
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]), )
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1.8, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [3.2, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [.5, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
+
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1, 3])
+        burn2.set_state_val('theta', [0, 4])
+        burn2.set_state_val('vr', [0.5, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [1, 1])
 
         p.run_driver()
 
@@ -904,38 +886,32 @@ def test_two_burn_orbit_raise_gl_wildcard_add_timeseries_output(self):
         p.setup(check=True, force_alloc_complex=True)
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5)
-
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]), )
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1.8, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [3.2, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [.5, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
+
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1, 3])
+        burn2.set_state_val('theta', [0, 4])
+        burn2.set_state_val('vr', [0.5, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [1, 1])
 
         p.run_driver()
 
@@ -1068,38 +1044,32 @@ def test_two_burn_orbit_raise_radau_wildcard_add_timeseries_output(self):
         p.setup(check=True, force_alloc_complex=True)
 
         # Set Initial Guesses
-        p.set_val('traj.parameters:c', val=1.5)
-
-        p.set_val('traj.burn1.t_initial', val=0.0)
-        p.set_val('traj.burn1.t_duration', val=2.25)
-
-        p.set_val('traj.burn1.states:r', val=burn1.interp('r', [1, 1.5]))
-        p.set_val('traj.burn1.states:theta', val=burn1.interp('theta', [0, 1.7]))
-        p.set_val('traj.burn1.states:vr', val=burn1.interp('vr', [0, 0]))
-        p.set_val('traj.burn1.states:vt', val=burn1.interp('vt', [1, 1]))
-        p.set_val('traj.burn1.states:accel', val=burn1.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn1.states:deltav', val=burn1.interp('deltav', [0, 0.1]), )
-        p.set_val('traj.burn1.controls:u1', val=burn1.interp('u1', [-3.5, 13.0]))
-
-        p.set_val('traj.coast.t_initial', val=2.25)
-        p.set_val('traj.coast.t_duration', val=3.0)
-
-        p.set_val('traj.coast.states:r', val=coast.interp('r', [1.3, 1.5]))
-        p.set_val('traj.coast.states:theta', val=coast.interp('theta', [2.1767, 1.7]))
-        p.set_val('traj.coast.states:vr', val=coast.interp('vr', [0.3285, 0]))
-        p.set_val('traj.coast.states:vt', val=coast.interp('vt', [0.97, 1]))
-        p.set_val('traj.coast.states:accel', val=coast.interp('accel', [0, 0]))
-
-        p.set_val('traj.burn2.t_initial', val=5.25)
-        p.set_val('traj.burn2.t_duration', val=1.75)
-
-        p.set_val('traj.burn2.states:r', val=burn2.interp('r', [1.8, 3]))
-        p.set_val('traj.burn2.states:theta', val=burn2.interp('theta', [3.2, 4.0]))
-        p.set_val('traj.burn2.states:vr', val=burn2.interp('vr', [.5, 0]))
-        p.set_val('traj.burn2.states:vt', val=burn2.interp('vt', [1, np.sqrt(1 / 3)]))
-        p.set_val('traj.burn2.states:accel', val=burn2.interp('accel', [0.1, 0]))
-        p.set_val('traj.burn2.states:deltav', val=burn2.interp('deltav', [0.1, 0.2]))
-        p.set_val('traj.burn2.controls:u1', val=burn2.interp('u1', [1, 1]))
+        traj.set_parameter_val('c', val=1.5, units='DU/TU')
+
+        burn1.set_time_val(initial=0.0, duration=2.25)
+        burn1.set_state_val('r', [1, 1.5])
+        burn1.set_state_val('theta', [0, 1.7])
+        burn1.set_state_val('vr', [0, 0])
+        burn1.set_state_val('vt', [1, 1])
+        burn1.set_state_val('accel', [0.1, 0.0])
+        burn1.set_state_val('deltav', [0, 0.1])
+        burn1.set_control_val('u1', [-3.5, 13.0])
+
+        coast.set_time_val(initial=2.25, duration=3.0)
+        coast.set_state_val('r', [1.3, 1.5])
+        coast.set_state_val('theta', [2.1767, 1.7])
+        coast.set_state_val('vr', [0.3285, 0])
+        coast.set_state_val('vt', [0.97, 1])
+        coast.set_state_val('accel', [0, 0])
+
+        burn2.set_time_val(initial=5.25, duration=1.75)
+        burn2.set_state_val('r', [1, 3])
+        burn2.set_state_val('theta', [0, 4])
+        burn2.set_state_val('vr', [0.5, 0])
+        burn2.set_state_val('vt', [1, np.sqrt(1 / 3)])
+        burn2.set_state_val('accel', [0.1, 0.0])
+        burn2.set_state_val('deltav', [0.1, 0.2])
+        burn2.set_control_val('u1', [1, 1])
 
         p.run_driver()
 
diff --git a/dymos/examples/flying_robot/test/test_flying_robot.py b/dymos/examples/flying_robot/test/test_flying_robot.py
index 341012b5c..985dbc176 100644
--- a/dymos/examples/flying_robot/test/test_flying_robot.py
+++ b/dymos/examples/flying_robot/test/test_flying_robot.py
@@ -22,6 +22,9 @@ def flying_robot_direct_collocation(transcription='gauss-lobatto', compressed=Tr
         t = dm.GaussLobatto(num_segments=8, order=5, compressed=compressed)
     elif transcription == "radau-ps":
         t = dm.Radau(num_segments=8, order=5, compressed=compressed)
+    elif transcription == 'birkhoff':
+        grid = dm.BirkhoffGrid(num_nodes=30)
+        t = dm.Birkhoff(grid=grid)
     else:
         raise ValueError('invalid transcription')
 
@@ -45,12 +48,10 @@ def flying_robot_direct_collocation(transcription='gauss-lobatto', compressed=Tr
 
     p.setup(check=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 1.0
-
-    p['traj.phase0.states:x'] = phase.interp('x', [[0.0, 0.0], [-100.0, 100.0]])
-    p['traj.phase0.states:v'] = phase.interp('v', [[0.0, 0.0], [0.0, 0.0]])
-    p['traj.phase0.controls:u'] = phase.interp('u', [[1, 1], [-1, -1]])
+    phase.set_time_val(initial=0.0, duration=1.0)
+    phase.set_state_val('x', [[0.0, 0.0], [-100.0, 100.0]])
+    phase.set_state_val('v', [[0.0, 0.0], [0.0, 0.0]])
+    phase.set_control_val('u', [[1, 1], [-1, -1]])
 
     p.run_driver()
 
@@ -66,7 +67,7 @@ def tearDownClass(cls):
             if os.path.exists(filename):
                 os.remove(filename)
 
-    def _assert_results(self, p, tol=1.0E-4):
+    def _assert_results(self, p, tol=1.0E-3):
         t = p.get_val('traj.phase0.timeseries.time')
         x = p.get_val('traj.phase0.timeseries.x')
         v = p.get_val('traj.phase0.timeseries.v')
@@ -96,6 +97,10 @@ def test_flying_robot_radau_uncompressed(self):
                                             compressed=False)
         self._assert_results(p)
 
+    def test_flying_robot_birkhoff(self):
+        p = flying_robot_direct_collocation('birkhoff')
+        self._assert_results(p)
+
 
 if __name__ == "__main__":
 
diff --git a/dymos/examples/goddard_rocket_problem/test/test_goddard_rocket_problem.py b/dymos/examples/goddard_rocket_problem/test/test_goddard_rocket_problem.py
index 9e42758b9..fa1538898 100644
--- a/dymos/examples/goddard_rocket_problem/test/test_goddard_rocket_problem.py
+++ b/dymos/examples/goddard_rocket_problem/test/test_goddard_rocket_problem.py
@@ -52,20 +52,11 @@ def goddard_rocket_direct_collocation(grid_type='lgl'):
 
     p.setup(check=True, force_alloc_complex=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 40.0
-
-    p['traj.phase0.initial_states:h'] = 0.0
-    p['traj.phase0.initial_states:v'] = 0.0
-    p['traj.phase0.initial_states:m'] = 3.0
-    p['traj.phase0.final_states:h'] = 10000.0
-    p['traj.phase0.final_states:v'] = 0.0
-    p['traj.phase0.final_states:m'] = 1.0
-
-    p['traj.phase0.states:h'] = phase.interp('h', [0.0, 10000.0])
-    p['traj.phase0.states:v'] = phase.interp('v', [0.0, 0.0])
-    p['traj.phase0.states:m'] = phase.interp('m', [3.0, 3.0])
-    p['traj.phase0.controls:T'] = phase.interp('T', [0.0, 0.0])
+    phase.set_time_val(initial=0.0, duration=40.0)
+    phase.set_state_val('h', [0.0, 10000.0])
+    phase.set_state_val('v', [0.0, 0.0])
+    phase.set_state_val('m', [3.0, 1.0])
+    phase.set_control_val('T', [0.0, 0.0])
 
     return p
 
diff --git a/dymos/examples/hull_problem/test/test_hull_problem.py b/dymos/examples/hull_problem/test/test_hull_problem.py
index cd03a7d6e..f346574cf 100644
--- a/dymos/examples/hull_problem/test/test_hull_problem.py
+++ b/dymos/examples/hull_problem/test/test_hull_problem.py
@@ -39,16 +39,10 @@ def make_problem(transcription=GaussLobatto, numseg=30):
 
         p.setup(check=True)
 
-        if transcription is ExplicitShooting:
-            p.set_val('traj.phase.initial_states:x', 1.5)
-            p.set_val('traj.phase.initial_states:xL', 0.0)
-        else:
-            p.set_val('traj.phase.states:x', phase0.interp('x', [1.5, 1]))
-            p.set_val('traj.phase.states:xL', phase0.interp('xL', [0, 1]))
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 10)
-        p.set_val('traj.phase.controls:u', phase0.interp('u', [-7, -0.14]))
-
+        phase0.set_state_val('x', [1.5, 1])
+        phase0.set_state_val('xL', [0, 1])
+        phase0.set_time_val(initial=0.0, duration=10.0)
+        phase0.set_control_val('u', [-7, -0.14])
         return p
 
     @staticmethod
diff --git a/dymos/examples/hyper_sensitive/doc/test_doc_hyper_sensitive.py b/dymos/examples/hyper_sensitive/doc/test_doc_hyper_sensitive.py
index 005bb1982..71e5731f7 100644
--- a/dymos/examples/hyper_sensitive/doc/test_doc_hyper_sensitive.py
+++ b/dymos/examples/hyper_sensitive/doc/test_doc_hyper_sensitive.py
@@ -74,11 +74,10 @@ def test_hyper_sensitive_for_docs(self):
 
         p.setup(check=True)
 
-        p.set_val('traj.phase0.states:x', phase.interp('x', [1.5, 1]))
-        p.set_val('traj.phase0.states:xL', phase.interp('xL', [0, 1]))
-        p.set_val('traj.phase0.t_initial', 0)
-        p.set_val('traj.phase0.t_duration', tf)
-        p.set_val('traj.phase0.controls:u', phase.interp('u', [-0.6, 2.4]))
+        phase.set_time_val(initial=0, duration=tf)
+        phase.set_state_val('x', [1.5, 1])
+        phase.set_state_val('xL', [0, 1])
+        phase.set_control_val('u', [-0.6, 2.4])
 
         #
         # Solve the problem.
diff --git a/dymos/examples/hyper_sensitive/test/test_hyper_sensitive.py b/dymos/examples/hyper_sensitive/test/test_hyper_sensitive.py
index 40e9a01a2..b6b960478 100644
--- a/dymos/examples/hyper_sensitive/test/test_hyper_sensitive.py
+++ b/dymos/examples/hyper_sensitive/test/test_hyper_sensitive.py
@@ -66,7 +66,6 @@ def make_problem(self, transcription=dm.GaussLobatto, optimizer='SLSQP', numseg=
         phase0.add_state('xL', fix_initial=True, fix_final=False, rate_source='L', ref=100)
         phase0.add_control('u', opt=True, targets=['u'])
 
-        # phase0.add_boundary_constraint('x', loc='final', equals=1)
         phase0.add_boundary_constraint('x', loc='initial', equals=1.5)
         phase0.add_boundary_constraint('x', loc='final', equals=1)
 
@@ -78,16 +77,10 @@ def make_problem(self, transcription=dm.GaussLobatto, optimizer='SLSQP', numseg=
         p.set_solver_print(0)
         p.setup(check=True, force_alloc_complex=True)
 
-        if transcription == 'birkhoff':
-            p.set_val('traj.phase0.initial_states:x', 1.5)
-            p.set_val('traj.phase0.initial_states:xL', 0.0)
-
-        p.set_val('traj.phase0.states:x', phase0.interp('x', [1.5, 1]))
-        p.set_val('traj.phase0.states:xL', phase0.interp('xL', [0, 1]))
-
-        p.set_val('traj.phase0.t_initial', 0)
-        p.set_val('traj.phase0.t_duration', tf)
-        p.set_val('traj.phase0.controls:u', phase0.interp('u', [-0.6, 2.4]))
+        phase0.set_time_val(initial=0, duration=tf)
+        phase0.set_state_val('x', [1.5, 1])
+        phase0.set_state_val('xL', [0, 1])
+        phase0.set_control_val('u', [-0.6, 2.4])
 
         return p
 
diff --git a/dymos/examples/length_constrained_brachistochrone/doc/test_doc_length_constrained_brachistochrone.py b/dymos/examples/length_constrained_brachistochrone/doc/test_doc_length_constrained_brachistochrone.py
index d47dbff22..8020ad5b9 100644
--- a/dymos/examples/length_constrained_brachistochrone/doc/test_doc_length_constrained_brachistochrone.py
+++ b/dymos/examples/length_constrained_brachistochrone/doc/test_doc_length_constrained_brachistochrone.py
@@ -77,14 +77,12 @@ def test_length_constrained_brachistochrone(self):
 
         p.setup(check=True)
 
-        p.set_val('traj.phase0.t_initial', 0.0)
-        p.set_val('traj.phase0.t_duration', 2.0)
-
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 10]))
-        p.set_val('traj.phase0.states:y', phase.interp('y', [10, 5]))
-        p.set_val('traj.phase0.states:v', phase.interp('v', [0, 9.9]))
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [5, 100]))
-        p.set_val('traj.phase0.parameters:g', 9.80665)
+        phase.set_time_val(initial=0.0, duration=2.0)
+        phase.set_state_val('x', [0, 10])
+        phase.set_state_val('y', [10, 5])
+        phase.set_state_val('v', [0, 9.9])
+        phase.set_control_val('theta', [5, 100])
+        phase.set_parameter_val('g', 9.80665)
 
         p.run_driver()
 
diff --git a/dymos/examples/low_thrust_spiral/test/test_low_thrust_spiral.py b/dymos/examples/low_thrust_spiral/test/test_low_thrust_spiral.py
index 510884a03..57ecf3d88 100644
--- a/dymos/examples/low_thrust_spiral/test/test_low_thrust_spiral.py
+++ b/dymos/examples/low_thrust_spiral/test/test_low_thrust_spiral.py
@@ -46,21 +46,12 @@ def low_thrust_spiral_direct_collocation(grid_type='lgl'):
 
     p.setup(check=True, force_alloc_complex=True)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 300.0
-
-    p['traj.phase0.initial_states:r'] = 1.0
-    p['traj.phase0.initial_states:theta'] = 0.0
-    p['traj.phase0.initial_states:vr'] = 0.0
-    p['traj.phase0.initial_states:vt'] = 1.0
-    p['traj.phase0.final_states:r'] = 6.0
-    p['traj.phase0.final_states:vr'] = 0.0
-    p['traj.phase0.final_states:vt'] = 1/np.sqrt(6)
-
-    p['traj.phase0.states:r'] = phase.interp('r', [1.0, 3.0])
-    p['traj.phase0.states:vr'] = phase.interp('vr', [0.0, 0.0])
-    p['traj.phase0.states:vt'] = phase.interp('vt', [1.0, 1.0])
-    p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])
+    phase.set_time_val(initial=0.0, duration=300.0)
+    phase.set_state_val('r', [1.0, 6.0])
+    phase.set_state_val('theta', [0.0, 0.0])
+    phase.set_state_val('vr', [0.0, 0.0])
+    phase.set_state_val('vt', [1.0, 1/np.sqrt(6)])
+    phase.set_control_val('alpha', [0.0, 0.0])
 
     return p
 
diff --git a/dymos/examples/min_time_climb/test/test_doc_min_time_climb_partial_coloring.py b/dymos/examples/min_time_climb/test/test_doc_min_time_climb_partial_coloring.py
index c42e88e06..bc2684e64 100644
--- a/dymos/examples/min_time_climb/test/test_doc_min_time_climb_partial_coloring.py
+++ b/dymos/examples/min_time_climb/test/test_doc_min_time_climb_partial_coloring.py
@@ -101,15 +101,13 @@ def test_min_time_climb_partial_coloring(self):
         #
         p.setup()
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 500
-
-        p['traj.phase0.states:r'] = phase.interp('r', [0.0, 50000.0])
-        p['traj.phase0.states:h'] = phase.interp('h', [100.0, 20000.0])
-        p['traj.phase0.states:v'] = phase.interp('v', [135.964, 283.159])
-        p['traj.phase0.states:gam'] = phase.interp('gam', [0.0, 0.0])
-        p['traj.phase0.states:m'] = phase.interp('m', [19030.468, 10000.])
-        p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])
+        phase.set_time_val(initial=0.0, duration=350)
+        phase.set_state_val('r', [0.0, 50000.0])
+        phase.set_state_val('h', [100.0, 20000.0])
+        phase.set_state_val('v', [135.964, 283.159])
+        phase.set_state_val('gam', [0.0, 0.0])
+        phase.set_state_val('m', [19030.468, 10000.])
+        phase.set_control_val('alpha', [0.0, 0.0])
 
         #
         # Solve for the optimal trajectory
diff --git a/dymos/examples/min_time_climb/test/test_ex_min_time_climb.py b/dymos/examples/min_time_climb/test/test_ex_min_time_climb.py
index a4351b59b..bb6edfbdb 100644
--- a/dymos/examples/min_time_climb/test/test_ex_min_time_climb.py
+++ b/dymos/examples/min_time_climb/test/test_ex_min_time_climb.py
@@ -1,5 +1,6 @@
 import unittest
 import numpy as np
+import openmdao
 from numpy.polynomial import Polynomial as P
 try:
     import matplotlib.pyplot as plt
@@ -17,6 +18,8 @@
 
 from openmdao.utils.testing_utils import use_tempdirs, require_pyoptsparse
 
+om_version = tuple([int(s) for s in openmdao.__version__.split('-')[0].split('.')])
+
 
 def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto',
                    transcription_order=3, force_alloc_complex=False, add_rate=False, time_name='time',
@@ -120,29 +123,18 @@ def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto',
     p['traj.phase0.t_initial'] = 0.0
     p['traj.phase0.t_duration'] = 350.0
 
-    p['traj.phase0.states:r'] = phase.interp('r', [0.0, 111319.54])
-    p['traj.phase0.states:h'] = phase.interp('h', [100.0, 20000.0])
-    p['traj.phase0.states:v'] = phase.interp('v', [135.964, 283.159])
-    p['traj.phase0.states:gam'] = phase.interp('gam', [0.0, 0.0])
-    p['traj.phase0.states:m'] = phase.interp('m', [19030.468, 16841.431])
-    p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])
+    phase.set_time_val(initial=0.0, duration=350.0)
+    phase.set_state_val('r', [0.0, 111319.54])
+    phase.set_state_val('h', [100.0, 20000.0])
+    phase.set_state_val('v', [135.964, 283.159])
+    phase.set_state_val('gam', [0.0, 0.0])
+    phase.set_state_val('m', [19030.468, 16841.431])
+    phase.set_control_val('alpha', [0.0, 0.0])
 
     if transcription == 'birkhoff':
-        p['traj.phase0.initial_states:r'] = 0.0
-        p['traj.phase0.final_states:r'] = 111319.54
-
-        p['traj.phase0.initial_states:h'] = 100.0
-        p['traj.phase0.final_states:h'] = 20000.0
-
-        p['traj.phase0.initial_states:v'] = 135.964
-        p['traj.phase0.final_states:v'] = 283.159
-
-        p['traj.phase0.initial_states:gam'] = 0.0
-        p['traj.phase0.final_states:gam'] = 0.0
-
-        p['traj.phase0.initial_states:m'] = 19030.468
-        p['traj.phase0.final_states:m'] = 16841.431
+        phase.set_simulate_options(times_per_seg=200, atol=1.0E-6, rtol=1.0E-6)
 
+    if transcription == 'birkhoff':
         phase.set_simulate_options(times_per_seg=200, atol=1.0E-6, rtol=1.0E-6)
 
     p.run_model()
@@ -285,6 +277,7 @@ def test_results_radau(self):
         self._test_mach_rate(p, plot=False)
 
     @require_pyoptsparse(optimizer='IPOPT')
+    @unittest.skipIf(om_version < (3, 32, 2), 'Test requires OpenMDAO 3.31.2 or later')
     def test_results_birkhoff(self):
         NUM_SEG = 1
         ORDER = 30
diff --git a/dymos/examples/min_time_climb/test/test_min_time_climb_simulate_failure.py b/dymos/examples/min_time_climb/test/test_min_time_climb_simulate_failure.py
index 9b6fadd74..56c9dfda0 100644
--- a/dymos/examples/min_time_climb/test/test_min_time_climb_simulate_failure.py
+++ b/dymos/examples/min_time_climb/test/test_min_time_climb_simulate_failure.py
@@ -69,15 +69,13 @@ def min_time_climb(num_seg=3, transcription_order=3, force_alloc_complex=False):
 
     p.setup(check=True, force_alloc_complex=force_alloc_complex)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 300.0
-
-    p['traj.phase0.states:r'] = phase.interp('r', [0.0, 111319.54])
-    p['traj.phase0.states:h'] = phase.interp('h', [100.0, 20000.0])
-    p['traj.phase0.states:v'] = phase.interp('v', [135.964, 283.159])
-    p['traj.phase0.states:gam'] = phase.interp('gam', [0.0, 0.0])
-    p['traj.phase0.states:m'] = phase.interp('m', [19030.468, 16841.431])
-    p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])
+    phase.set_time_val(initial=0.0, duration=300.0)
+    phase.set_state_val('r', [0.0, 111319.54])
+    phase.set_state_val('h', [100.0, 20000.0])
+    phase.set_state_val('v', [135.964, 283.159])
+    phase.set_state_val('gam', [0.0, 0.0])
+    phase.set_state_val('m', [19030.468, 16841.431])
+    phase.set_control_val('alpha', [0.0, 0.0])
 
     return p
 
diff --git a/dymos/examples/min_time_climb/test/test_refine_with_shaped_parameter.py b/dymos/examples/min_time_climb/test/test_refine_with_shaped_parameter.py
index c9eb8314d..28143828f 100644
--- a/dymos/examples/min_time_climb/test/test_refine_with_shaped_parameter.py
+++ b/dymos/examples/min_time_climb/test/test_refine_with_shaped_parameter.py
@@ -130,15 +130,13 @@ def min_time_climb(optimizer='SLSQP', num_seg=3, transcription='gauss-lobatto',
 
     p.setup(check=True, force_alloc_complex=force_alloc_complex)
 
-    p['traj.phase0.t_initial'] = 0.0
-    p['traj.phase0.t_duration'] = 300.0
-
-    p['traj.phase0.states:r'] = phase.interp('r', [0.0, 111319.54])
-    p['traj.phase0.states:h'] = phase.interp('h', [100.0, 20000.0])
-    p['traj.phase0.states:v'] = phase.interp('v', [135.964, 283.159])
-    p['traj.phase0.states:gam'] = phase.interp('gam', [0.0, 0.0])
-    p['traj.phase0.states:m'] = phase.interp('m', [19030.468, 16841.431])
-    p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])
+    phase.set_time_val(initial=0.0, duration=300.0)
+    phase.set_state_val('r', [0.0, 111319.54])
+    phase.set_state_val('h', [100.0, 20000.0])
+    phase.set_state_val('v', [135.964, 283.159])
+    phase.set_state_val('gam', [0.0, 0.0])
+    phase.set_state_val('m', [19030.468, 16841.431])
+    phase.set_control_val('alpha', [0.0, 0.0])
 
     dm.run_problem(p, refine_iteration_limit=1)
 
diff --git a/dymos/examples/moon_landing/test/test_moon_landing_problem.py b/dymos/examples/moon_landing/test/test_moon_landing_problem.py
index edbd187af..0ef628c3c 100644
--- a/dymos/examples/moon_landing/test/test_moon_landing_problem.py
+++ b/dymos/examples/moon_landing/test/test_moon_landing_problem.py
@@ -44,12 +44,11 @@ def make_problem(self, grid_type):
 
         self.p.setup(check=True, force_alloc_complex=True)
 
-        self.p.set_val('traj.phase.initial_states:h', 1.0)
-        self.p.set_val('traj.phase.initial_states:v', -0.783)
-        self.p.set_val('traj.phase.initial_states:m', 1.0)
-        self.p.set_val('traj.phase.t_initial', 0)
-        self.p.set_val('traj.phase.t_duration', 1.0)
-        self.p.set_val('traj.phase.controls:T', phase.interp('T', [0.0, 1.227]))
+        phase.set_time_val(initial=0.0, duration=1.0)
+        phase.set_state_val('h', [1.0, 0.0])
+        phase.set_state_val('v', [-0.783, 0.0])
+        phase.set_state_val('m', [1.0, 0.2])
+        phase.set_control_val('T', [0.0, 1.227])
 
     def test_problem_lgl(self):
 
diff --git a/dymos/examples/oscillator/test/test_oscillator.py b/dymos/examples/oscillator/test/test_oscillator.py
index 1989fc6b3..b8544f916 100644
--- a/dymos/examples/oscillator/test/test_oscillator.py
+++ b/dymos/examples/oscillator/test/test_oscillator.py
@@ -45,15 +45,12 @@ def test_ivp(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Perform a single execution of the model (executing the model is required before simulation).
         prob.run_model()
@@ -110,15 +107,12 @@ def test_ivp_solver(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Now converge the dynamics using a nonlinear solver to find the trajectory without optimization.
         prob.run_model()
@@ -185,15 +179,12 @@ def test_ivp_driver(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Now we're using the optimization driver to iteratively run the model and vary the
         # phase duration until the final y value is 0.
@@ -261,15 +252,12 @@ def test_ivp_driver_10_segs(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Now we're using the optimization driver to iteratively run the model and vary the
         # phase duration until the final y value is 0.
@@ -337,15 +325,12 @@ def test_ivp_driver_4_segs_7_order(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Now we're using the optimization driver to iteratively run the model and vary the
         # phase duration until the final y value is 0.
@@ -413,15 +398,12 @@ def test_ivp_driver_run_problem(self):
         prob.setup()
 
         # Assign values to the times and states
-        prob.set_val('traj.phase0.t_initial', 0.0)
-        prob.set_val('traj.phase0.t_duration', 15.0)
-
-        prob.set_val('traj.phase0.states:x', 10.0)
-        prob.set_val('traj.phase0.states:v', 0.0)
-
-        prob.set_val('traj.phase0.parameters:k', 1.0)
-        prob.set_val('traj.phase0.parameters:c', 0.5)
-        prob.set_val('traj.phase0.parameters:m', 1.0)
+        phase.set_time_val(initial=0.0, duration=15.0)
+        phase.set_state_val('x', 10.0)
+        phase.set_state_val('v', 0.0)
+        phase.set_parameter_val('k', 1.0)
+        phase.set_parameter_val('c', 0.5)
+        phase.set_parameter_val('m', 1.0)
 
         # Now we're using the optimization driver to iteratively run the model and vary the
         # phase duration until the final y value is 0.
diff --git a/dymos/examples/racecar/test/test_racecar.py b/dymos/examples/racecar/test/test_racecar.py
index 8b3530d7e..a20ddc271 100644
--- a/dymos/examples/racecar/test/test_racecar.py
+++ b/dymos/examples/racecar/test/test_racecar.py
@@ -42,11 +42,10 @@ def test_racecar_for_docs(self):
 
         txs = {'radau': dm.Radau(num_segments=50, order=3, compressed=True),
                'gauss-lobatto': dm.GaussLobatto(num_segments=50, order=3, compressed=True),
-               'birkhoff': dm.Birkhoff(grid=dm.BirkhoffGrid(num_nodes=50))}
+               'birkhoff': dm.Birkhoff(grid=dm.BirkhoffGrid(num_nodes=100))}
 
         for tx_name, tx in txs.items():
             with self.subTest(tx_name):
-
                 # Define the OpenMDAO problem
                 p = om.Problem(model=om.Group())
 
@@ -167,21 +166,21 @@ def test_racecar_for_docs(self):
 
                 # States
                 # Nonzero velocity to avoid division by zero errors
-                p.set_val('traj.phase0.states:V', phase.interp('V', [20, 20]), units='m/s')
+                phase.set_state_val('V', 20.0, units='m/s')
                 # All other states start at 0
-                p.set_val('traj.phase0.states:lambda', phase.interp('lambda', [0.0, 0.0]), units='rad')
-                p.set_val('traj.phase0.states:omega', phase.interp('omega', [0.0, 0.0]), units='rad/s')
-                p.set_val('traj.phase0.states:alpha', phase.interp('alpha', [0.0, 0.0]), units='rad')
-                p.set_val('traj.phase0.states:ax', phase.interp('ax', [0.0, 0.0]), units='m/s**2')
-                p.set_val('traj.phase0.states:ay', phase.interp('ay', [0.0, 0.0]), units='m/s**2')
-                p.set_val('traj.phase0.states:n', phase.interp('n', [0.0, 0.0]), units='m')
+                phase.set_state_val('lambda', 0.0, units='rad')
+                phase.set_state_val('omega', 0.0, units='rad/s')
+                phase.set_state_val('alpha', 0.0, units='rad')
+                phase.set_state_val('ax', 0.0, units='m/s**2')
+                phase.set_state_val('ay', 0.0, units='m/s**2')
+                phase.set_state_val('n', 0.0, units='m')
                 # initial guess for what the final time should be
-                p.set_val('traj.phase0.states:t', phase.interp('t', [0.0, 100.0]), units='s')
+                phase.set_state_val('t', [0.0, 100.0], units='s')
 
                 # Controls
                 # a small amount of thrust can speed up convergence
-                p.set_val('traj.phase0.controls:delta', phase.interp('delta', [0.0, 0.0]), units='rad')
-                p.set_val('traj.phase0.controls:thrust', phase.interp('thrust', [0.1, 0.1]), units=None)
+                phase.set_control_val('delta', 0.0, units='rad')
+                phase.set_control_val('thrust', 0.1, units=None)
 
                 dm.run_problem(p, run_driver=True)
 
diff --git a/dymos/examples/robertson_problem/doc/test_doc_robertson_problem.py b/dymos/examples/robertson_problem/doc/test_doc_robertson_problem.py
index 2f12d7764..f6a42a6ce 100644
--- a/dymos/examples/robertson_problem/doc/test_doc_robertson_problem.py
+++ b/dymos/examples/robertson_problem/doc/test_doc_robertson_problem.py
@@ -10,7 +10,7 @@
     matplotlib = None
 
 from openmdao.utils.testing_utils import use_tempdirs
-from dymos.examples.robertson_problem.doc.robertson_ode import RobertsonODE
+from dymos.examples.robertson_problem.robertson_ode import RobertsonODE
 
 
 @use_tempdirs
@@ -52,12 +52,10 @@ def robertson_problem(self, t_final=1.0):
         #
         # Set the initial values
         #
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = t_final
-
-        p.set_val('traj.phase0.initial_states:x0', phase.interp('x0', ys=[1.0, 0.7]))
-        p.set_val('traj.phase0.initial_states:y0', phase.interp('y0', ys=[0.0, 1e-5]))
-        p.set_val('traj.phase0.initial_states:z0', phase.interp('z0', ys=[0.0, 0.3]))
+        phase.set_time_val(initial=0.0, duration=t_final)
+        phase.set_state_val('x0', [1.0, 0.7])
+        phase.set_state_val('y0', [0.0, 1e-5])
+        phase.set_state_val('z0', [0.0, 0.3])
 
         return p
 
diff --git a/dymos/examples/robot_arm/doc/test_doc_robot_arm.py b/dymos/examples/robot_arm/doc/test_doc_robot_arm.py
index 86722e7a2..b25c9d9fa 100644
--- a/dymos/examples/robot_arm/doc/test_doc_robot_arm.py
+++ b/dymos/examples/robot_arm/doc/test_doc_robot_arm.py
@@ -62,29 +62,13 @@ def make_problem(self, tx, optimizer='SLSQP', numseg=30):
 
         p.setup(check=True, force_alloc_complex=False, mode='auto')
 
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 10)
-
-        if isinstance(tx, dm.Birkhoff):
-            p.set_val('traj.phase.initial_states:x0', 4.5)
-            p.set_val('traj.phase.initial_states:x1', 0.0)
-            p.set_val('traj.phase.initial_states:x2', np.pi / 4)
-            p.set_val('traj.phase.initial_states:x3', 0.0)
-            p.set_val('traj.phase.initial_states:x4', 0.0)
-            p.set_val('traj.phase.initial_states:x5', 0.0)
-            p.set_val('traj.phase.final_states:x0', 4.5)
-            p.set_val('traj.phase.final_states:x1', 2 * np.pi / 3)
-            p.set_val('traj.phase.final_states:x2', np.pi / 4)
-            p.set_val('traj.phase.final_states:x3', 0.0)
-            p.set_val('traj.phase.final_states:x4', 0.0)
-            p.set_val('traj.phase.final_states:x5', 0.0)
-        else:
-            p.set_val('traj.phase.states:x0', phase.interp('x0', [4.5, 4.5]))
-            p.set_val('traj.phase.states:x1', phase.interp('x1', [0.0, 2 * np.pi / 3]))
-            p.set_val('traj.phase.states:x2', phase.interp('x2', [np.pi / 4, np.pi / 4]))
-            p.set_val('traj.phase.states:x3', phase.interp('x3', [0.0, 0.0]))
-            p.set_val('traj.phase.states:x4', phase.interp('x4', [0.0, 0.0]))
-            p.set_val('traj.phase.states:x5', phase.interp('x5', [0.0, 0.0]))
+        phase.set_time_val(initial=0, duration=10)
+        phase.set_state_val('x0', [4.5, 4.5])
+        phase.set_state_val('x1', [0.0, 2 * np.pi / 3])
+        phase.set_state_val('x2', [np.pi / 4, np.pi / 4])
+        phase.set_state_val('x3', [0.0, 0.0])
+        phase.set_state_val('x4', [0.0, 0.0])
+        phase.set_state_val('x5', [0.0, 0.0])
 
         return p
 
diff --git a/dymos/examples/robot_arm/test/test_robot_arm.py b/dymos/examples/robot_arm/test/test_robot_arm.py
index 316e96a93..9c9e3d661 100644
--- a/dymos/examples/robot_arm/test/test_robot_arm.py
+++ b/dymos/examples/robot_arm/test/test_robot_arm.py
@@ -71,29 +71,13 @@ def make_problem(self, tx, optimizer='SLSQP', numseg=30):
 
         p.setup(check=True, force_alloc_complex=False, mode='auto')
 
-        p.set_val('traj.phase.t_initial', 0)
-        p.set_val('traj.phase.t_duration', 10)
-
-        if isinstance(tx, dm.Birkhoff):
-            p.set_val('traj.phase.initial_states:x0', 4.5)
-            p.set_val('traj.phase.initial_states:x1', 0.0)
-            p.set_val('traj.phase.initial_states:x2', np.pi / 4)
-            p.set_val('traj.phase.initial_states:x3', 0.0)
-            p.set_val('traj.phase.initial_states:x4', 0.0)
-            p.set_val('traj.phase.initial_states:x5', 0.0)
-            p.set_val('traj.phase.final_states:x0', 4.5)
-            p.set_val('traj.phase.final_states:x1', 2 * np.pi / 3)
-            p.set_val('traj.phase.final_states:x2', np.pi / 4)
-            p.set_val('traj.phase.final_states:x3', 0.0)
-            p.set_val('traj.phase.final_states:x4', 0.0)
-            p.set_val('traj.phase.final_states:x5', 0.0)
-        else:
-            p.set_val('traj.phase.states:x0', phase.interp('x0', [4.5, 4.5]))
-            p.set_val('traj.phase.states:x1', phase.interp('x1', [0.0, 2 * np.pi / 3]))
-            p.set_val('traj.phase.states:x2', phase.interp('x2', [np.pi / 4, np.pi / 4]))
-            p.set_val('traj.phase.states:x3', phase.interp('x3', [0.0, 0.0]))
-            p.set_val('traj.phase.states:x4', phase.interp('x4', [0.0, 0.0]))
-            p.set_val('traj.phase.states:x5', phase.interp('x5', [0.0, 0.0]))
+        phase.set_time_val(initial=0, duration=10)
+        phase.set_state_val('x0', [4.5, 4.5])
+        phase.set_state_val('x1', [0.0, 2 * np.pi / 3])
+        phase.set_state_val('x2', [np.pi / 4, np.pi / 4])
+        phase.set_state_val('x3', [0.0, 0.0])
+        phase.set_state_val('x4', [0.0, 0.0])
+        phase.set_state_val('x5', [0.0, 0.0])
 
         return p
 
diff --git a/dymos/examples/shuttle_reentry/doc/test_doc_reentry.py b/dymos/examples/shuttle_reentry/doc/test_doc_reentry.py
index 6dc3cc9d0..96e52add2 100644
--- a/dymos/examples/shuttle_reentry/doc/test_doc_reentry.py
+++ b/dymos/examples/shuttle_reentry/doc/test_doc_reentry.py
@@ -69,26 +69,15 @@ def test_reentry(self):
 
         p.setup(check=True)
 
-        p.set_val('traj.phase0.t_initial', 0, units='s')
-        p.set_val('traj.phase0.t_duration', 2000, units='s')
-
-        p.set_val('traj.phase0.states:h',
-                  phase0.interp('h', [260000, 80000]), units='ft')
-        p.set_val('traj.phase0.states:gamma',
-                  phase0.interp('gamma', [-1, -5]), units='deg')
-        p.set_val('traj.phase0.states:phi',
-                  phase0.interp('phi', [0, 75]), units='deg')
-        p.set_val('traj.phase0.states:psi',
-                  phase0.interp('psi', [90, 10]), units='deg')
-        p.set_val('traj.phase0.states:theta',
-                  phase0.interp('theta', [0, 25]), units='deg')
-        p.set_val('traj.phase0.states:v',
-                  phase0.interp('v', [25600, 2500]), units='ft/s')
-
-        p.set_val('traj.phase0.controls:alpha',
-                  phase0.interp('alpha', ys=[17.4, 17.4]), units='deg')
-        p.set_val('traj.phase0.controls:beta',
-                  phase0.interp('beta', ys=[-75, 0]), units='deg')
+        phase0.set_time_val(initial=0, duration=2000, units='s')
+        phase0.set_state_val('h', [260000, 80000], units='ft')
+        phase0.set_state_val('gamma', [-1, -5], units='deg')
+        phase0.set_state_val('phi', [0, 75], units='deg')
+        phase0.set_state_val('psi', [90, 10], units='deg')
+        phase0.set_state_val('theta', [0, 25], units='deg')
+        phase0.set_state_val('v', [25600, 2500], units='ft/s')
+        phase0.set_control_val('alpha', 17.4, units='deg')
+        phase0.set_control_val('beta', [-75, 0], units='deg')
 
         # Run the driver
         dm.run_problem(p)
diff --git a/dymos/examples/shuttle_reentry/test/test_reentry.py b/dymos/examples/shuttle_reentry/test/test_reentry.py
index 32f825dc9..10cfb05e4 100644
--- a/dymos/examples/shuttle_reentry/test/test_reentry.py
+++ b/dymos/examples/shuttle_reentry/test/test_reentry.py
@@ -71,37 +71,15 @@ def make_problem(self, constrained=True, transcription=dm.GaussLobatto, optimize
 
         p.setup(check=True, force_alloc_complex=True)
 
-        p.set_val('traj.phase0.states:h',
-                  phase0.interp('h', [260000, 80000]), units='ft')
-        p.set_val('traj.phase0.states:gamma',
-                  phase0.interp('gamma', [-1 * np.pi / 180, -5 * np.pi / 180]),
-                  units='rad')
-        p.set_val('traj.phase0.states:phi',
-                  phase0.interp('phi', [0, 75 * np.pi / 180]), units='rad')
-        p.set_val('traj.phase0.states:psi',
-                  phase0.interp('psi', [90 * np.pi / 180, 10 * np.pi / 180]),
-                  units='rad')
-        p.set_val('traj.phase0.states:theta',
-                  phase0.interp('theta', [0, 25 * np.pi / 180]), units='rad')
-        p.set_val('traj.phase0.states:v', phase0.interp('v', [25600, 2500]), units='ft/s')
-        p.set_val('traj.phase0.t_initial', 0, units='s')
-        p.set_val('traj.phase0.t_duration', 2000, units='s')
-        p.set_val('traj.phase0.controls:alpha',
-                  phase0.interp('alpha', [17.4 * np.pi / 180, 17.4 * np.pi / 180]), units='rad')
-        p.set_val('traj.phase0.controls:beta',
-                  phase0.interp('beta', [-75 * np.pi / 180, 0 * np.pi / 180]), units='rad')
-
-        if isinstance(transcription, dm.Birkhoff):
-            p.set_val('traj.phase0.initial_states:h', 260000, units='ft')
-            p.set_val('traj.phase0.initial_states:gamma', -1 * np.pi / 180, units='rad')
-            p.set_val('traj.phase0.initial_states:phi', 0.0, units='rad')
-            p.set_val('traj.phase0.initial_states:psi', 90 * np.pi / 180, units='rad')
-            p.set_val('traj.phase0.initial_states:theta', 0.0, units='rad')
-            p.set_val('traj.phase0.initial_states:v', 25600, units='ft/s')
-
-            p.set_val('traj.phase0.final_states:h', 80000, units='ft')
-            p.set_val('traj.phase0.final_states:gamma', -5 * np.pi / 180, units='rad')
-            p.set_val('traj.phase0.final_states:v', 2500, units='ft/s')
+        phase0.set_time_val(initial=0, duration=2000, units='s')
+        phase0.set_state_val('h', [260000, 80000], units='ft')
+        phase0.set_state_val('gamma', [-1 * np.pi / 180, -5 * np.pi / 180], units='rad')
+        phase0.set_state_val('phi', [0, 75 * np.pi / 180], units='rad')
+        phase0.set_state_val('psi', [90 * np.pi / 180, 10 * np.pi / 180], units='rad')
+        phase0.set_state_val('theta', [0, 25 * np.pi / 180], units='rad')
+        phase0.set_state_val('v', [25600, 2500], units='ft/s')
+        phase0.set_control_val('alpha', [17.4 * np.pi / 180, 17.4 * np.pi / 180], units='rad')
+        phase0.set_control_val('beta', [-75 * np.pi / 180, 0 * np.pi / 180], units='rad')
 
         return p
 
diff --git a/dymos/examples/ssto/doc/test_doc_ssto_earth.py b/dymos/examples/ssto/doc/test_doc_ssto_earth.py
index c86a39f30..3ade491c9 100644
--- a/dymos/examples/ssto/doc/test_doc_ssto_earth.py
+++ b/dymos/examples/ssto/doc/test_doc_ssto_earth.py
@@ -74,14 +74,13 @@ def test_doc_ssto_earth(self):
         #
         p.setup(check=True)
 
-        p.set_val('traj.phase0.t_initial', 0.0)
-        p.set_val('traj.phase0.t_duration', 150.0)
-        p.set_val('traj.phase0.states:x', phase.interp('x', [0, 1.15E5]))
-        p.set_val('traj.phase0.states:y', phase.interp('y', [0, 1.85E5]))
-        p.set_val('traj.phase0.states:vy', phase.interp('vx', [1.0E-6, 0]))
-        p.set_val('traj.phase0.states:m', phase.interp('vy', [117000, 1163]))
-        p.set_val('traj.phase0.controls:theta', phase.interp('theta', [1.5, -0.76]))
-        p.set_val('traj.phase0.parameters:thrust', 2.1, units='MN')
+        phase.set_time_val(initial=0.0, duration=150.0)
+        phase.set_state_val('x', [0, 1.15E5])
+        phase.set_state_val('y', [0, 1.85E5])
+        phase.set_state_val('vy', [1.0E-6, 0])
+        phase.set_state_val('m', [117000, 1163])
+        phase.set_control_val('theta', [1.5, -0.76])
+        phase.set_parameter_val('thrust', 2.1, units='MN')
 
         #
         # Solve the Problem
diff --git a/dymos/examples/ssto/doc/test_doc_ssto_linear_tangent_guidance.py b/dymos/examples/ssto/doc/test_doc_ssto_linear_tangent_guidance.py
index adfa0c783..7b35fcb65 100644
--- a/dymos/examples/ssto/doc/test_doc_ssto_linear_tangent_guidance.py
+++ b/dymos/examples/ssto/doc/test_doc_ssto_linear_tangent_guidance.py
@@ -264,15 +264,14 @@ def setup(self):
 
         p.setup(check=True)
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 500.0
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 350000.0])
-        p['traj.phase0.states:y'] = phase.interp('y', [0, 185000.0])
-        p['traj.phase0.states:vx'] = phase.interp('vx', [0, 1627.0])
-        p['traj.phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])
-        p['traj.phase0.states:m'] = phase.interp('m', [50000, 50000])
-        p['traj.phase0.parameters:a_ctrl'] = -0.01
-        p['traj.phase0.parameters:b_ctrl'] = 3.0
+        phase.set_time_val(initial=0.0, duration=500.0)
+        phase.set_state_val('x', [0, 350000.0])
+        phase.set_state_val('y', [0, 185000.0])
+        phase.set_state_val('vx', [0, 1627.0])
+        phase.set_state_val('vy', [1.0E-6, 0.0])
+        phase.set_state_val('m', 50000)
+        phase.set_parameter_val('a_ctrl', -0.01)
+        phase.set_parameter_val('b_ctrl', 3.0)
 
         dm.run_problem(p)
 
diff --git a/dymos/examples/ssto/doc/test_doc_ssto_polynomial_control.py b/dymos/examples/ssto/doc/test_doc_ssto_polynomial_control.py
index 90553f02d..1c30937a6 100644
--- a/dymos/examples/ssto/doc/test_doc_ssto_polynomial_control.py
+++ b/dymos/examples/ssto/doc/test_doc_ssto_polynomial_control.py
@@ -248,14 +248,13 @@ def setup(self):
         #
         # Assign initial guesses for the independent variables in the problem.
         #
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 500.0
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 350000.0])
-        p['traj.phase0.states:y'] = phase.interp('y', [0, 185000.0])
-        p['traj.phase0.states:vx'] = phase.interp('vx', [0, 1627.0])
-        p['traj.phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])
-        p['traj.phase0.states:m'] = phase.interp('m', [50000, 50000])
-        p['traj.phase0.polynomial_controls:tan_theta'] = [[0.5 * np.pi], [0.0]]
+        phase.set_time_val(initial=0.0, duration=500.0)
+        phase.set_state_val('x', [0, 350000.0])
+        phase.set_state_val('y', [0, 185000.0])
+        phase.set_state_val('vx', [0, 1627.0])
+        phase.set_state_val('vy', [1.0E-6, 0.0])
+        phase.set_state_val('m', 50000)
+        phase.set_polynomial_control_val('tan_theta', [[0.5 * np.pi], [0.0]])
 
         #
         # Solve the problem.
diff --git a/dymos/examples/ssto/test/test_linear_tangent_traj_params.py b/dymos/examples/ssto/test/test_linear_tangent_traj_params.py
index e39f608eb..fd6a9b73c 100644
--- a/dymos/examples/ssto/test/test_linear_tangent_traj_params.py
+++ b/dymos/examples/ssto/test/test_linear_tangent_traj_params.py
@@ -308,15 +308,14 @@ def test_opt_traj_param_ode_targets(self):
 
         p.setup(check=True)
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = 500.0
-        p['traj.phase0.states:x'] = phase.interp('x', [0, 350000.0])
-        p['traj.phase0.states:y'] = phase.interp('y', [0, 185000.0])
-        p['traj.phase0.states:vx'] = phase.interp('vx', [0, 1627.0])
-        p['traj.phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])
-        p['traj.phase0.states:m'] = phase.interp('m', [50000, 50000])
-        p['traj.phase0.parameters:a_ctrl'] = -0.01
-        p['traj.phase0.parameters:b_ctrl'] = 3.0
+        phase.set_time_val(initial=0.0, duration=500.0)
+        phase.set_state_val('x', [0, 350000.0])
+        phase.set_state_val('y', [0, 185000.0])
+        phase.set_state_val('vx', [0, 1627.0])
+        phase.set_state_val('vy', [1.0E-6, 0.0])
+        phase.set_state_val('m', 50000)
+        phase.set_parameter_val('a_ctrl', -0.01)
+        phase.set_parameter_val('b_ctrl', 3.0)
 
         dm.run_problem(p, simulate=True)
 
diff --git a/dymos/examples/ssto/test/test_simulate_root_trajectory.py b/dymos/examples/ssto/test/test_simulate_root_trajectory.py
index fd74491bb..fd6b1588a 100644
--- a/dymos/examples/ssto/test/test_simulate_root_trajectory.py
+++ b/dymos/examples/ssto/test/test_simulate_root_trajectory.py
@@ -253,14 +253,13 @@ def setup(self):
         #
         # Assign initial guesses for the independent variables in the problem.
         #
-        p['phase0.t_initial'] = 0.0
-        p['phase0.t_duration'] = 500.0
-        p['phase0.states:x'] = phase.interp('x', [0, 350000.0])
-        p['phase0.states:y'] = phase.interp('y', [0, 185000.0])
-        p['phase0.states:vx'] = phase.interp('vx', [0, 1627.0])
-        p['phase0.states:vy'] = phase.interp('vy', [1.0E-6, 0])
-        p['phase0.states:m'] = phase.interp('m', [50000, 50000])
-        p['phase0.polynomial_controls:tan_theta'] = [[0.5 * np.pi], [0.0]]
+        phase.set_time_val(initial=0.0, duration=500.0)
+        phase.set_state_val('x', [0, 350000.0])
+        phase.set_state_val('y', [0, 185000.0])
+        phase.set_state_val('vx', [0, 1627.0])
+        phase.set_state_val('vy', [1.0E-6, 0.0])
+        phase.set_state_val('m', 50000)
+        phase.set_polynomial_control_val('tan_theta', [[0.5 * np.pi], [0.0]])
 
         #
         # Solve the problem.
diff --git a/dymos/examples/vanderpol/doc/test_doc_vanderpol.py b/dymos/examples/vanderpol/doc/test_doc_vanderpol.py
index 20abb1907..8897552a4 100644
--- a/dymos/examples/vanderpol/doc/test_doc_vanderpol.py
+++ b/dymos/examples/vanderpol/doc/test_doc_vanderpol.py
@@ -123,14 +123,13 @@ def test_vanderpol_delay_mpi(self):
         # setup the problem
         p.setup(check=True)
 
-        p['traj.phase0.t_initial'] = 0.0
-        p['traj.phase0.t_duration'] = t_final
+        phase.set_time_val(0.0, t_final)
 
         # add a linearly interpolated initial guess for the state and control curves
-        p['traj.phase0.states:x0'] = phase.interp('x0', [1, 0])
-        p['traj.phase0.states:x1'] = phase.interp('x1', [1, 0])
-        p['traj.phase0.states:J'] = phase.interp('J', [0, 1])
-        p['traj.phase0.controls:u'] = phase.interp('u', [-0.75, -0.75])
+        phase.set_state_val('x0', [1, 0])
+        phase.set_state_val('x0', [1, 0])
+        phase.set_state_val('x0', [0, 1])
+        phase.set_control_val('u', -0.75)
 
         dm.run_problem(p, run_driver=True, simulate=False)
 
diff --git a/dymos/examples/water_rocket/test/test_water_rocket.py b/dymos/examples/water_rocket/test/test_water_rocket.py
index 20de13efa..8ba2a9b96 100644
--- a/dymos/examples/water_rocket/test/test_water_rocket.py
+++ b/dymos/examples/water_rocket/test/test_water_rocket.py
@@ -39,7 +39,7 @@ def test_water_rocket_height_for_docs(self):
         p.model.linear_solver = om.DirectSolver()
 
         p.setup()
-        set_sane_initial_guesses(p, phases)
+        set_sane_initial_guesses(phases)
 
         dm.run_problem(p, run_driver=True, simulate=True)
 
@@ -79,7 +79,7 @@ def test_water_rocket_range_for_docs(self):
         p.model.linear_solver = om.DirectSolver()
 
         p.setup()
-        set_sane_initial_guesses(p, phases)
+        set_sane_initial_guesses(phases)
 
         p.run_driver()