【机械臂】Windows11下配置KINOVA GEN3机械臂的Python环境并运行

Windows11下配置KINOVA GEN3机械臂的Python环境并运行

在这里插入图片描述

一、开机前的准备

  1. 检查电源连接

确保机械臂的电源适配器已正确连接到机械臂的电源接口,并且另一端已连接到电源插座。将红色按钮按起来,而不是按下去,按下去是紧急停止。

  1. 检查安全事项

确保机械臂周围没有障碍物或人员,避免在开机过程中发生意外。

  1. 按下电源按钮

找到机械臂底座上的电源按钮,按下并保持3秒钟,直到电源指示灯亮起。

  1. 等待系统初始化

机械臂开机后,系统需要一段时间进行初始化。此时,电源指示灯会保持蓝色闪烁状态。

  1. 验证开机成功

当系统初始化完成后,电源指示灯将变为蓝色常亮,表示机械臂已成功开机并处于待机状态。

二、通过Kortex Web App验证

(1)连接网络

使用网线将计算机和机械臂连接,然后在计算机上配置网络

  1. 控制面板>网络和Internet>网络连接中选择以太网连接

  2. 配置 IP 地址:

    • 滚动到“IPv4”部分。
    • 将“IPv4 配置”切换为“手动”。
    • 输入以下信息:
      • IP 地址:192.168.1.11
      • 子网掩码:255.255.255.0
      • 默认网关:不填

    在这里插入图片描述

(2)打开Kortex Web App

在浏览器中输入机械臂的IP地址(默认为192.168.1.10),然后按回车键。

(3)登录

在登录页面中输入默认的用户名和密码(均为admin),然后点击“CONNECT”按钮。

(4)检查状态

在Kortex Web App的“Monitoring”页面中,您可以查看机械臂的实时状态,包括各关节的角度、速度、扭矩等信息,以确认机械臂是否正常工作。

然后再Monitoring界面中找到机械臂的固件版本,在system information中的Base下找到Bootloader Version,我的是2.5.0-2

在这里插入图片描述

在这里插入图片描述

三、配置Python环境并运行示例

(1)下载Python的API工具包

根据以上查询到的固件版本,下载对应版本的API工具包,点击API的2.6.0

https://github.com/Kinovarobotics/Kinova-kortex2_Gen3_G3L

在这里插入图片描述

点击左侧2.5的文件夹,下在.whl文件
在这里插入图片描述

下载到本地,为单独创建一个conda环境后,安装到指定的conda环境中,

conda create -n arm38 python=3.8

conda activate arm38

pip install kortex_api-2.5.0.post6-py3-none-any.whl

(2)安装Mosquitto服务

进入mosquitto官网【Eclipse Mosquitto官网】,下载exe安装包,安装成功后,在安装路径下,运行exe安装后,配置环境变量"C:\Program Files\mosquitto",然后打开配置文件“C:\Program Files\mosquitto\mosquitto.conf”,修改监听地址,ctrl+F搜“ listener port-number ”在下面一行增加2行.

listener 1883 192.168.1.11 # 注意这里是以太网的IP,不是机械臂的IP“192.168.1.11”
allow_anonymous true          # 允许匿名连接(测试阶段)

在aclfile.example文件中添加允许匿名用户操作的规则:

topic readwrite #
user anonymous  # 若匿名用户需单独定义

最后在cmd中输入mosquitto,启动服务,或者以下方法。

  1. Win + R 打开运行窗口,输入 services.msc,然后按回车。
  2. 在服务管理器中,查找与 MQTT 相关的服务(例如 Mosquitto Broker 或其他 MQTT 服务名称)。
  3. 检查服务的状态:
    • 如果状态为“正在运行”,则 MQTT 服务已启动。
    • 如果状态为“已停止”,则 MQTT 服务未启动,可以右键点击服务并选择“启动”。
      在这里插入图片描述

(3)检查端口

  1. 打开命令提示符。

  2. 运行以下命令查看正在监听的端口:

    netstat -ano | findstr :1883
    

TCP 192.168.1.11:1883 0.0.0.0:0 LISTENING 19144

  • 如果输出中包含 192.168.1.1:1883 ,则 MQTT 服务正在监听端口 1883
  • 如果没有输出,则 MQTT 服务未监听该端口。

(4)运行Demo程序

从官网的库下载示例程序:https://github.com/Kinovarobotics/Kinova-kortex2_Gen3_G3L/tree/master/api_python/examples

比如以下的程序将机械臂伸直的操作

#! /usr/bin/env python3

###
# KINOVA (R) KORTEX (TM)
#
# Copyright (c) 2018 Kinova inc. All rights reserved.
#
# This software may be modified and distributed
# under the terms of the BSD 3-Clause license.
#
# Refer to the LICENSE file for details.
#
###

import time
import sys
import os
import threading

from kortex_api.autogen.client_stubs.BaseClientRpc import BaseClient
from kortex_api.autogen.client_stubs.BaseCyclicClientRpc import BaseCyclicClient

from kortex_api.autogen.messages import Session_pb2, Base_pb2, BaseCyclic_pb2

# Maximum allowed waiting time during actions (in seconds)
TIMEOUT_DURATION = 20

# Create closure to set an event after an END or an ABORT
def check_for_sequence_end_or_abort(e):
    """Return a closure checking for END or ABORT notifications on a sequence

    Arguments:
    e -- event to signal when the action is completed
        (will be set when an END or ABORT occurs)
    """

    def check(notification, e = e):
        event_id = notification.event_identifier
        task_id = notification.task_index
        if event_id == Base_pb2.SEQUENCE_TASK_COMPLETED:
            print("Sequence task {} completed".format(task_id))
        elif event_id == Base_pb2.SEQUENCE_ABORTED:
            print("Sequence aborted with error {}:{}"\
                .format(\
                    notification.abort_details,\
                    Base_pb2.SubErrorCodes.Name(notification.abort_details)))
            e.set()
        elif event_id == Base_pb2.SEQUENCE_COMPLETED:
            print("Sequence completed.")
            e.set()
    return check

# Create closure to set an event after an END or an ABORT
def check_for_end_or_abort(e):
    """Return a closure checking for END or ABORT notifications

    Arguments:
    e -- event to signal when the action is completed
        (will be set when an END or ABORT occurs)
    """
    def check(notification, e = e):
        print("EVENT : " + \
              Base_pb2.ActionEvent.Name(notification.action_event))
        if notification.action_event == Base_pb2.ACTION_END \
        or notification.action_event == Base_pb2.ACTION_ABORT:
            e.set()
    return check

#
# Example related functions
#

def create_angular_action(actuator_count):
    
    print("Creating angular action")
    action = Base_pb2.Action()
    action.name = "Example angular action"
    action.application_data = ""
    
    for joint_id in range(actuator_count):
        joint_angle = action.reach_joint_angles.joint_angles.joint_angles.add()
        joint_angle.value = 0.0

    return action

def create_cartesian_action(base_cyclic):
    
    print("Creating Cartesian action")
    action = Base_pb2.Action()
    action.name = "Example Cartesian action"
    action.application_data = ""

    feedback = base_cyclic.RefreshFeedback()

    cartesian_pose = action.reach_pose.target_pose
    cartesian_pose.x = feedback.base.tool_pose_x          # (meters)
    cartesian_pose.y = feedback.base.tool_pose_y - 0.1    # (meters)
    cartesian_pose.z = feedback.base.tool_pose_z - 0.2    # (meters)
    cartesian_pose.theta_x = feedback.base.tool_pose_theta_x # (degrees)
    cartesian_pose.theta_y = feedback.base.tool_pose_theta_y # (degrees)
    cartesian_pose.theta_z = feedback.base.tool_pose_theta_z # (degrees)

    return action

#
#
# Example core functions
#

def example_move_to_home_position(base):
    # Make sure the arm is in Single Level Servoing mode
    base_servo_mode = Base_pb2.ServoingModeInformation()
    base_servo_mode.servoing_mode = Base_pb2.SINGLE_LEVEL_SERVOING
    base.SetServoingMode(base_servo_mode)
    
    # Move arm to ready position
    print("Moving the arm to a safe position")
    action_type = Base_pb2.RequestedActionType()
    action_type.action_type = Base_pb2.REACH_JOINT_ANGLES
    action_list = base.ReadAllActions(action_type)
    action_handle = None
    for action in action_list.action_list:
        if action.name == "Home":
            action_handle = action.handle

    if action_handle == None:
        print("Can't reach safe position. Exiting")
        sys.exit(0)

    e = threading.Event()
    notification_handle = base.OnNotificationActionTopic(
        check_for_end_or_abort(e),
        Base_pb2.NotificationOptions()
    )

    base.ExecuteActionFromReference(action_handle)

    # Leave time to action to complete
    finished = e.wait(TIMEOUT_DURATION)
    base.Unsubscribe(notification_handle)

    if not finished:
        print("Timeout on action notification wait")
    return finished

def example_create_sequence(base, base_cyclic):
    print("Creating Action for Sequence")

    actuator_count = base.GetActuatorCount().count
    angular_action = create_angular_action(actuator_count)
    cartesian_action = create_cartesian_action(base_cyclic)

    print("Creating Sequence")
    sequence = Base_pb2.Sequence()
    sequence.name = "Example sequence"

    print("Appending Actions to Sequence")
    task_1 = sequence.tasks.add()
    task_1.group_identifier = 0
    task_1.action.CopyFrom(cartesian_action)
    
    task_2 = sequence.tasks.add()
    task_2.group_identifier = 1 # sequence elements with same group_id are played at the same time
    task_2.action.CopyFrom(angular_action)

    e = threading.Event()
    notification_handle = base.OnNotificationSequenceInfoTopic(
        check_for_sequence_end_or_abort(e),
        Base_pb2.NotificationOptions()
    )

    print("Creating sequence on device and executing it")
    handle_sequence = base.CreateSequence(sequence)
    base.PlaySequence(handle_sequence)

    print("Waiting for movement to finish ...")
    finished = e.wait(TIMEOUT_DURATION)
    base.Unsubscribe(notification_handle)

    if not finished:
        print("Timeout on action notification wait")
    return finished

def main():
    # Import the utilities helper module
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
    import utilities

    # Parse arguments
    args = utilities.parseConnectionArguments()
    
    # Create connection to the device and get the router
    with utilities.DeviceConnection.createTcpConnection(args) as router:

        # Create required services
        base = BaseClient(router)
        base_cyclic = BaseCyclicClient(router)

        # Example core
        success = True
        success &= example_move_to_home_position(base)
        success &= example_create_sequence(base, base_cyclic)
        
        # You can also refer to the 110-Waypoints examples for an alternate way to execute
        # a trajectory defined by a series of waypoints in joint space or in Cartesian space

        return 0 if success else 1

if __name__ == "__main__":
    exit(main())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Better Bench

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值