目录:
2.将电机链接在traitlets控件上(交互式控件的使用)
ipywidgets.widgets和traitlets的几个函数的含义
from jetbot import bgr8_to_jpeg #from jetcam.utils import bgr8_to_jpeg from jetbot import Camera camera = Camera.instance(width=300, height=300) ''' from jetcam.usb_camera import USBCamera camera = USBCamera(capture_device=1,width=224, height=224) camera.running=True print("camera created") '''
Nvidia Nano上从头构建Jetbot镜像安装指南
jupyter_clickable_image_widget的安装
from jetbot import Robot robot = Robot()
# 机器人前进 robot.forward(speed=0.3) # 机器人以百分之三十的速度前进
# 机器人后退 robot.backward(speed=0.3) # 机器人以百分之三十的速度后退
# 机器人左转 robot.left(speed=0.3) # 机器人以百分之三十的速度左转
# 机器人右转 robot.right(speed=0.3) # 机器人以百分之三十的速度右转
# 机器人停止 robot.stop()
1.单独控制电机
上面我们看到了如何使用left,right等命令控制机器人。但是如果我们想要单独设置每个电机速度怎么办?那么,有两种方法可以做到这一点。
第一种方法是调用 set_motors 方法。 例如,左转一秒,我们可以将左电机速度设置为 30%,将右电机设置为 60%,这将实现不同弧度的转向方式,如下所示。
robot.set_motors(0.3, 0.6) time.sleep(1.0) robot.stop()
通过上面的操作,你应该见到机器人向左转。但实际上我们可以使用另一种方式来完成同样的事情。
在 Robot 类中还有两个名为 left_motor 和 right_motor 的属性,分别表示左电机和右电机的速度值。 这些属性是 Motor 类实例中的,每一个实例都包含一个 value 值。当这个 value 发生了变化就会触发 events,重新分配电机的速度值。
所以在这个电机类中,我们附加的一个函数,只要值发生变化就会更新电机命令。
因此,为了完成我们上面所做的完全相同的事情,我们可以执行以下操作
robot.left_motor.value = 0.3 robot.right_motor.value = 0.6 time.sleep(1.0) robot.left_motor.value = 0.0 robot.right_motor.value = 0.0
您应该看到机器人以相同的方式移动
2.将电机链接在traitlets控件上
import ipywidgets.widgets as widgets 制作图形小按钮 from IPython.display import display 显示容器 import traitlets 链接图形小按钮,连接这些小部件进行控制操作
在Jupyter Notbooks可以让我们在这个页面上制作图形小按钮,而traitlets可以连接这些小部件进行控制操作。这样,我们就可以通过浏览器按按钮的方式去控制我们的小车。
我们先创建并显示两个用于控制电机的滑块
import ipywidgets.widgets as widgets from IPython.display import display # 创建两个竖直滑块,范围是 [-1.0, 1.0] left_slider = widgets.FloatSlider(description='left', min=-1.0, max=1.0, step=0.01, orientation='vertical') right_slider = widgets.FloatSlider(description='right', min=-1.0, max=1.0, step=0.01, orientation='vertical') # 创建一个水平框容器以将滑块彼此相邻放置 slider_container = widgets.HBox([left_slider, right_slider]) # 在此单元格的输出中显示容器 display(slider_container)
输出:

尝试单击并上下拖动滑块,会见到数值的变化。 请注意,当前我们移动滑块时 JetBot 的电机是没有任何反应的,那是因为我们还没有将它们连接到电机上! 下面我们将通过使用traitlets 包中的 link 函数来实现
import traitlets left_link = traitlets.link((left_slider, 'value'), (robot.left_motor, 'value')) right_link = traitlets.link((right_slider, 'value'), (robot.right_motor, 'value'))
现在尝试拖动滑块(要先慢慢地拖动),您应该看到相应的电机在转动!
我们上面创建的 link 函数实际上创建了一个双向链接! 那意味着, 如果我们在其他地方设置电机值,滑块将更新! 尝试执行下面的代码块
robot.forward(0.3) time.sleep(1.0) robot.stop()
执行上面代码你应该看见滑块也发生了改变,响应了电机的速度值。如果我们要断开此连接,我们可以调用 unlink 方法逐一断开连接
left_link.unlink()
right_link.unlink()
但是如果我们不想要一个双向的连接,比如说我们只想用滑块来显示电机的速度值,而不想用来控制,那么要实现这种功能,我们就可以使用 dlink 函数,左边是来源,右边是目标,(数据来源于电机,然后要显示在目标上)
left_link = traitlets.dlink((robot.left_motor, 'value'), (left_slider, 'value')) right_link = traitlets.dlink((robot.right_motor, 'value'), (right_slider, 'value'))
现在你可以上下移动滑块,你应该看到机器人的电机是没有一点反应。但当我们设置电机的速度值并执行的时候,滑块将会作出响应的数值更新
3.将函数关联到事件
使用 traitlets 另一种方法是把函数附加到事件中(例如 forward) 。只要对象发生改变,就会调用函数,并将传递改变了的一些信息,例如 old 值和 new值
先让我们创建一些用来控制机器人的按钮显示在 notbook 上
# 创建按键 button_layout = widgets.Layout(width='100px', height='80px', align_self='center') stop_button = widgets.Button(description='stop', button_style='danger', layout=button_layout) forward_button = widgets.Button(description='forward', layout=button_layout) backward_button = widgets.Button(description='backward', layout=button_layout) left_button = widgets.Button(description='left', layout=button_layout) right_button = widgets.Button(description='right', layout=button_layout) # 显示按键 middle_box = widgets.HBox([left_button, stop_button, right_button], layout=widgets.Layout(align_self='center')) controls_box = widgets.VBox([forward_button, middle_box, backward_button]) display(controls_box)
输出:

你应该看到上面显示的一组机器人控制按钮,但现在你点击按钮并不会做任何事。要做到控制,我们需要创建一些函数附加到按钮 on_click 事件的中
def stop(change): robot.stop() def step_forward(change): robot.forward(0.4) time.sleep(0.5) robot.stop() def step_backward(change): robot.backward(0.4) time.sleep(0.5) robot.stop() def step_left(change): robot.left(0.3) time.sleep(0.5) robot.stop() def step_right(change): robot.right(0.3) time.sleep(0.5) robot.stop()
现在我们已经定义了那些函数,让我们把这些函数附加到每一个按钮的 on_click 事件
# 将按钮链接到操作 stop_button.on_click(stop) forward_button.on_click(step_forward) backward_button.on_click(step_backward) left_button.on_click(step_left) right_button.on_click(step_right)
执行以上代码,现在当你点击每一个按钮,你应该看到机器都会移动!
4.Heartbeat 紧急停止开关
用户可以使用 'heartbeat'来停止机器的的移动。这是一种检测机器人是否激活的简单方法。可以通过下面显示的滑块调整心跳周期(以秒为单位),如果两次心跳之内不能在浏览器之间往返通信的,那么心跳的 'status' (状态)属性值将会设置为 dead,一旦连接恢复连接,status 属性将设置为 alive。
from jetbot import Heartbeat heartbeat = Heartbeat() # this function will be called when heartbeat 'alive' status changes def handle_heartbeat_status(change): if change['new'] == Heartbeat.Status.dead: robot.stop() heartbeat.observe(handle_heartbeat_status, names='status') period_slider = widgets.FloatSlider(description='period', min=0.001, max=0.5, step=0.01, value=0.5) traitlets.dlink((period_slider, 'value'), (heartbeat, 'period')) display(period_slider, heartbeat.pulseout)
输出:

执行下面的代码来启动电机,看页面右上角的圆圈闪烁频率,就是heartbeat的频率,然后通过断开PC机的网络连接,看看会发生什么事情
robot.left(0.3)
浙公网安备 33010602011771号