Skip to content
Snippets Groups Projects
animate_3d.py 2.28 KiB
Newer Older
  • Learn to ignore specific revisions
  • import plotly.graph_objects as go
    from misc import quaternion
    from misc.matrix_building import Rt_3d
    from vis import triangulated_surface as vtrs
    from vis import triangulated_thruster_model as vttm
    
    
    def loop_sim(model, x, q, u, dt, scene=None, is_quaternion=False, **kwargs):
        """
    
        :param model: triangulated surface
        :param x: k, 3 | 3d position of center of model
        :param q: k, 3 | exponential map representation for 3d orientation
        - iff is_quaternion=True, instead treat as k, 4 quaternions
        :param u: k, n | control inputs
        :param dt:
        :param scene:
        :param kwargs:
        :return:
        """
        k = x.shape[0]
        frame_data = []
        for i in range(k):
            if is_quaternion:
                Aq = quaternion.quaternion2rotation_matrix(q[i])
            else:
                Aq = quaternion.exp_map2rotation_matrix(q[i])
            Rt = Rt_3d(Aq.T, x[i])
            data = [vtrs.make_model_mesh(model, Rt)]
            data.extend(vttm.make_thrust_vectors(model, scales=u[i], Rt=Rt))
            frame_data.append(data)
        drawn_frames = [go.Frame(
            data=frame_data[i],
            layout=go.Layout(
                title_text='t = {:2.2f}s'.format(i * dt),
                scene=dict(
                    xaxis=dict(range=x[i, 0] + [-10, 10], autorange=False),
                    yaxis=dict(range=x[i, 1] + [-10, 10], autorange=False),
                    zaxis=dict(range=x[i, 2] + [-10, 10], autorange=False),
                    aspectmode='cube',
                ),
            )
        ) for i in range(len(frame_data))]
    
        fig = go.Figure(
            data=frame_data[0],
            layout=go.Layout(
                title='t = {:2.2f}s'.format(0),
                autosize=False,
                width=1200, height=800,
                scene=dict(
                    xaxis=dict(range=x[0, 0] + [-10, 10], autorange=False),
                    yaxis=dict(range=x[0, 1] + [-10, 10], autorange=False),
                    zaxis=dict(range=x[0, 2] + [-10, 10], autorange=False),
                    aspectmode='cube',
                ),
                updatemenus=[dict(
                    type="buttons",
                    buttons=[dict(label='Play',
                                  method='animate',
                                  args=[None, {'frame': {'duration': 200, 'redraw': True}, }])])]
            ),
            frames=drawn_frames
        )
        fig.update_layout(transition_duration=500)
        fig.show()