黄工无刷电机学习
直播中

h1654155275.5748

7年用户 877经验值
私信 关注
[问答]

如何对机械臂的关节速度进行动态绘图?

如何对机械臂的关节速度进行动态绘图?

回帖(1)

薛珊珊

2021-11-3 09:04:24
我们在做机器人实验的时候,一般需要实时地观察机械臂的各个状态信息,所以动态绘图是不可避免的,下面我们将介绍如何对机械臂的关节速度进行动态绘图。


Codes
        实现代码比较简单,我们以baxter机器人单个关节的关节角(“right_s0”)为例介绍如何对其速度信息进行实时绘图:
#! /usr/bin/python


import rospy
from sensor_msgs.msg import JointState


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


# global variable for vel.
vel_info = np.zeros(100)
vel_info_temp = vel_info


vel_temp = 0


# global variables for plot.
fig, ax = plt.subplots()
line, = ax.plot(vel_info)
ax.set_ylim(-6e-2, 6e-2)
ax.set_ylabel("joint vel: rad/s")
ax.set_xlabel("time")


def stateMsgReceived(state_msg):
    global vel_temp
    vel_temp = state_msg.velocity[15]
    print vel_temp


def update(frame):
    global vel_info
    global vel_info_temp
    global line


    vel_info[0:-1] = vel_info_temp[1:]
    vel_info[-1] = vel_temp
    vel_info_temp = vel_info


    line.set_ydata(vel_info)
    return line




def main():
    global vel_info
    global fig
    rospy.init_node("joint_vel_drawer")
    joint_sub = rospy.Subscriber("/robot/joint_states", JointState, stateMsgReceived)


    ani = animation.FuncAnimation(fig, update, frames=None, interval=50)
    plt.show()




if __name__ == "__main__":
    main()
代码理解
        首先是导入了ROS相关的包:


import rospy
from sensor_msgs.msg import JointState


        然后是导入数据处理包numpy以及绘图包matplotlib:


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
        设置用于绘制速度曲线的全局变量:


# global variable for vel.
vel_curve = np.zeros(100)
vel_curve_temp = vel_curve
vel_temp = 0
        其中vel_curve表示用于绘图的点的向量,比如这里用100个点来绘图;vel_curve_temp用于暂时保存vel_curve的数据,并在后面用于对vel_curve中的数据进行更新;vel_temp保存最近时刻的速度数据。


        接着我们对所需绘制的图像进行设置,比如y值范围是(-6e-2, 6e-2),x、y轴的label分别为time和joint vel:


# global variables for plot.
fig, ax = plt.subplots()
line, = ax.plot(vel_info)
ax.set_ylim(-6e-2, 6e-2)
ax.set_ylabel("joint vel: rad/s")
ax.set_xlabel("time")


        然后我们定义了/robot/joint_states话题的回调函数:


def stateMsgReceived(state_msg):
    global vel_temp
    vel_temp = state_msg.velocity[15]
    print vel_temp


        主要也就是取出关节“right_s0”的数据放置到vel_temp中。


        接下来定义最最最重要的动态绘图更新函数:


def update(frame):
    global vel_info
    global vel_info_temp
    global line


    vel_info[0:-1] = vel_info_temp[1:]
    vel_info[-1] = vel_temp
    vel_info_temp = vel_info


    line.set_ydata(vel_info)
    return line


        在这里,我们首先将vel_info中的数据往前移一个点,也即将最早的一个速度点扔掉,然后用vel_temp这一最新数据补充到vel_info中,最后将我们的fig要绘制的曲线line中的数据设置为vel_info即可。


        理解了上面的内容之后,主函数的内容也就不难理解了:


def main():
    global vel_info
    global fig
    rospy.init_node("joint_vel_drawer")
    joint_sub = rospy.Subscriber("/robot/joint_states", JointState, stateMsgReceived)


    ani = animation.FuncAnimation(fig, update, frames=None, interval=50)
    plt.show()


        首先是订阅/joint_states话题,因为是用的rospy,所以会自己开辟一个线程/进程去执行回调函数,如果是用C++写的话,使用ros::AsyncSpinner()即可。然后用animation.FuncAnimation来绘制曲线,其中fig表示我们要绘制的图像,update表示更新图像数据所调用的函数,interval=50表示的是每隔50ms调用一次update函数对数据进行更新,并在fig上显示出来。最后,我们使用plt.show()打开显示窗口即可~


        绘制得到的关节速度动态曲线如下(这里就不放动态图了……):
举报

更多回帖

发帖
×
20
完善资料,
赚取积分