您的位置:首页 > 其它

libbarrett_programming_manual中文翻译

2017-07-05 14:05 190 查看

1 物理资料

1.1 了解你的WAM手臂

欢迎来到WAM机器人手臂的世界! WAM主要由飞机级铝制成,其基座具有独立的PC和安全系统。 它是一种“电缆驱动”臂,无需常规齿轮。 使用这些电缆,每个关节的移动摩擦力明显低于齿轮驱动的对应部件,使得WAM具有高度的“可逆驱动”或易于操作。

WAM具有4和7自由度(DOF)模型。 下图是7自由度WAM,附有BarrettHand。 虽然这两种型号几乎相同,但是7-DOF包括一个3自由度手腕模块,而4自由度手臂仅具有一个中空手腕用于连接目的。 本指南涉及4自由度WAM模型。

WAM的电机由巴雷特专利的电机控制器Pucks™驱动。 pucks非常小,它们放置在整个WAM手臂中,而不是存储在机器人外部的电机控制器盒中。 pucks通过CAN总线(控制器局域网)与控制PC进行通信,所有通信由安全板监控。 安全板是WAM基座中的大型PCB,用于监控臂的速度,发送到电机的扭矩指令的大小,控制PC和Puck之间的通信速率以及按钮的状态显示在面板上(见下一页)。

CAN总线是2线差分串行总线,提供1 Mbps的数字通信,具有高抗干扰能力。 所使用的协议是专用于WAM(不是CANopen)。 有关CAN的更多信息,请访问http://en.wikipedia.org/wiki/CAN_bus

pucks是程序员需要理解的最低级别的控制。 它们将电机位置发送到WAM PC,并在单个控制回路中从控制PC接收电机转矩。 控制回路可以以高达1 kHz的速率运行,但默认速率为500 Hz。 当您发送命令时,将其转换为CAN信号并发送给相应的Pucks。 下面的图片显示了一个pucks。

1.2 了解您的WAM安全系统

尽管WAM手臂由于其可反向驱动的性质而比大多数机器人本身更安全,但安全板可防止大多数可能的错误导致可反向驱动不能防止。 WAM的安全功能包括一个专用的安全板和两个安全面板。

WAM在施加电源时有三种可能的状态:活动,空闲和故障。 在这些状态下,向WAM读取数据或发送命令的电源状态和能力如下所示。

必须在执行任何命令之前手动激活WAM。 如果有问题,它将自动空闲或故障。 此外,可以通过按下紧急停止按钮手动空转或发生故障。 紧急停止将立即停止机器人,并且必须通过在重新激活WAM之前顺时针转动按钮四分之一圈来复位。 当功率不被施加到pucks时,WAM“电阻制动”意味着它不会积极地施加任何力,而是轻轻地抵抗施加到其上的任何力。 这导致WAM缓慢下降,直到遇到物理障碍。 它还允许操作者将WAM轻松地移动到静止位置。

有两件挂在WAM上的面板。 “控制”和“显示”面板都显示WAM的状态并具有紧急停止按钮,但只有“控制”挂件可以空闲或激活WAM。 下图显示了控制挂件并描述了其功能。

控制挂件

只要安全系统确定安全系统确定安全系统,就可以在移动按钮将WAM更改为该状态的同时按下空闲或激活按钮。 WAM必须空闲才能激活。

这些灯显示影响WAM状态的不同因素的状态。 如果它们都是绿色的,则WAM是活动的或者能被激活。 如果一个或多个是红色的,则WAM发生故障并停止。 如果在WAM活动时发出警告,则不会停止; 然而,应该指出的是,如果是这种情况,程序可能正在接近安全操作的限制。

1.3 关节力矩 关节位置 笛卡尔位置

开始编程序之前,有三种输入类型要好好学习:关节位置,关节力矩和笛卡尔位置。所有的输入都会被软件转换成关节力矩,这个关节力矩传送给wam内的puck。

最终,机械臂以关节力矩作为输入,输出关节位置。笛卡尔位置是从力矩和位置计算来的,而不是直接反馈的。

最容易理解的是笛卡尔位置输入。WAM了解直角位置的原点位于关节轴线1, 2路口,和3。这种控制方法允许用户精确地控制臂末端的位置(点x、y、z),但不能保证臂的精确位置。

WAM PC接收一个笛卡尔位置,然后计算出虚拟路径(“条”)需要以获得臂的端部到终点。然而,在手臂的末端将达到终点时,WAM没有碰撞检测所以笛卡尔控制应小心使用,否则可能发生的故障和损坏和扭矩。下面的图表概述了笛卡尔网格。

关节位置和力矩往往放弃WAM的方向控制。WAM提供位置的反馈形式,因此,没有完美的转换控制在笛卡尔和关节方法之间。一个笛卡尔位置只有三维,WAM有4或者7个关节维度,直角位置包含的信息不足够来唯一地描述WAM的每一个可能的位置。在需要这种控制的情况下,通常避免笛卡尔位置,并选择关节空间单元来控制。

2 介绍WAM代码

2.1 操作理论

WAM为了执行命令正确使用一种所谓的实时计算。实时计算保证行动发生在一个给定的频率,可以精确定时的代码没有操作系统延迟时钟和扭曲时间读数。WAM在默认情况下以500赫兹的频率工作。每个周期包括PC要求的puck运动位置,位置的结果发送给PC机,PC基于PID模块计算一套新的电机力矩,并且把新的电机力矩发送给pucks。这是非常重要的,任何代码不妨碍时间的方式,否则机器人将读取“心跳故障”,并注意在通信和关闭的滞后。阻塞函数和输入/输出函数经常改变程序的时间,然后延迟代码(从而消除代码的有效性),应该在实时代码中避免。

为了避免这些问题,WAM控制系统实时和非实时编码写入是单独的。从本质上讲,在运行一个WAM计算机很少有虚拟的“机器”,这是连在一起的,他们可以通过彼此之间可以传递信息。这些机器,称为系统(在2.3节解释)包含在一个WAM大多数实时编码。该系统被称为一个main()方法行动,直接或间接地处理阻塞和I/O功能,从而使实时代码流畅的不间断运行。

例如,控制WAM,放到一个单独的机器和数据包通过以太网WAM PC最小化潜在的定时发送然后值问题。这台电脑然后接收这些数据包中的非实时处理,将包成一个WAM跟随样条,那些命令放到实时代码可在CAN总线发送到pucks。这部分代码在实时发生的实际传递命令到pucks的WAM的PC,所有的阻断功能参与发送和接收数据包不能被保证在完美的时间发生。一旦曲线进行了计算,WAM的电脑有一个队列的力矩发送到pucks,不需要等待一个单独的扭矩每周期。下面的流程图显示了从用户信息的途径WAM PC和WAM电机。

2.2 通用术语

PID控制器–PID控制器通过采集误差反馈和试图通过控制移动对象的输出最小化误差控制流体过程的输出,在wam中,控制的是电机的转矩。具体来说,它们与误差、误差的积分和误差的导数成比例地运算。对于控制器存在的任何系统,必须调整这些比例。更多信息看http://en.wikipedia.org/wiki/PID_Controller.

一级过滤器–这是一种滤波器,可以衰减通过它的信号的高频分量,
4000
使其“平滑化”,从而防止突然的变化。 下图显示滤波信号和未滤波信号之间的差异

梯形速度曲线–这是速度随时间的函数,其中存在恒定加速度的周期,恒定速度的周期,然后是恒定减速时间,形成梯形。 这通常被WAM用来平滑地将其关节移动到给定的位置。 以图表形式的这种关系的一个例子如下。

2.3 libbarrett和wam对象是什么?

Libbarrett是为WAM手臂设计的C ++代码库,允许用户控制和操作WAM。 它包含几个类,包括WAM对象,可以帮助您编写自己的应用程序。 有关主要功能定义和库的结构,请参见下表以及下一页的流程图。

系统 - Libbarrett主要由这些组成。 系统就像小型虚拟机,从其输入处理信息,并将其传递到其输出。 如果他们的输出没有连接到任何东西,信息就会丢失。 输出可以连接到多个输入,但输入只能从一个输出接收信息。 这就是WAM代码中的信息如何移动 - 通过使用connect()和disconnect()函数管理的虚拟“软管”。 系统被设计为在RealTime中工作,并且实现一组允许由ExecutionManager调用的参数。

ExecutionManager - 这是监督所有实时操作的对象。 它具有程序中所有系统的列表,并以设定的速率(通常为500 Hz)告诉他们处理其输入并将信息放入其输出。 每当执行周期发生时,数据从一个系统传递到下一个系统。

jp_type,jv_type,jt_type,cp_type - 这些是来自units.h头文件的关节位置,速度,扭矩和笛卡尔位置的类型定义(typedef)。 它们是已经被格式化以防止混淆的数组,并且在许多情况下,当运行WAM时在系统之间传递的实际数据。 下表总结了这些类型及其单位:

Wam - 这是一个类,其中包含使用给定DOF操作现实生活中的WAM所需的所有系统和其他对象。 这个对象不是一个系统,而是主要由各种系统组成。 以下是每个WAM对象中包含的类:

LowLevelWam - 这是WAM对象的核心,它代表实际的硬件WAM,并处理软件和手臂。 它是一个将关节扭矩作为输入的系统,将其转换为发送到Pucks的电机扭矩,并从Pucks接收电机扭矩,将其转换为关节位置和关节速度以及其输出位置。

jtSummer - 一个将所有输入添加到一起并将结果馈送到其输出的对象。 在这种情况下,在虚拟WAM对象中,它将关节扭矩加在一起。

jpOutput和jvOutput - 这些是分别用于关节位置和速度的虚拟插口,您可以连接连接WAM系统的输入/输出软管。

toolOrientation和toolPosition - 这些是计算WAM终点的位置和方向的系统。

supervisoryController - 此对象接受WAM对象中的PID控制器可以接受的任何输入。 但它不是系统。 它决定哪个控制器应该处理输入,并将其传递给该控制器。 然后它处理该控制器的输出并将其传递给jtSummer。 被告知哪个信号跟wam.trackReferenceSignal()调用,并可以通过wam.idle()调用重置。

gravityCompensator - 当连接到jtSummer时,该对象计算WAM上的重力,并通过向臂提供适当的关节扭矩来补偿它。

要为WAM编写程序,请创建一个虚拟WAM对象。 WAM对象是系统的集合,可以更容易地编写其余的代码。 LowLevelWam是直接处理系统核心的真实WAM手臂的对象。 虽然可以编写直接与LowLevelWam进行交互的代码,但是通常使用围绕它构建的工具更容易,因为它们将产生比关节扭矩更容易理解的值。

“LowLevelWam”周围的“工具”主要是系统,当您在代码中创建新的WAM对象时,它们将被创建并连接在一起。 下图显示了这个框架,以及系统之间的信息流,在一个全新的WAM对象中。 注意清晰的控制循环,其中一系列控制器已经从WAM接收到反馈,并且它们都包含在“supervisoryController”中。监控控制器根据接收到的参考信号将控制器系统连接到Summer(默认情况下无连接),并且Summer将所有控制转矩加入到LowLevelWam中。 这个循环是所有WAM程序与之交互或修改的。

3 wam编程

3.1 实现

在阅读了libbarrett代码后面的概念结构后,了解一些实现及其实际用途很重要。 大多数实现在每个代码开始时都有多个#includes和typedef。 为简化目的,typedef已被合并到stddhr.h(并非所有这些都是每个WAM程序都必须的):

#Stddhr.h
#ifndef STDHDR_H_
#define STDHDR_H_
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/thread.hpp>
#include <libconfig.h++>
#include <barrett/thread/abstract/mutex.h>
#include <barrett/math.h>
#include <barrett/units.h>
#include <barrett/log.h>
#include <barrett/systems.h>
#include <barrett/wam.h>
namespace math = barrett::math;
namespace systems = barrett::systems;
namespace units = barrett::units;
using barrett::Wam;
using systems::connect;
using systems::reconnect;
using systems::disconnect;
const int DOF = 4;
const double T_s = 0.002;
typedef units::JointTorques<DOF>::type jt_type;
typedef units::JointPositions<DOF>::type jp_type;
typedef units::JointVelocities<DOF>::type jv_type;
typedef units::CartesianPosition::type cp_type;
inline void waitForEnter()
{
static std::string line;
std::getline(std::cin, line);
}
#endif /* STDHDR_H_ */


此代码包括所有必需的libbarrett组件,然后为了方便重命名几个命名空间。 之后,它创建了两个控制编码环境的常数:DOF表示WAM的类型(通常为4或7),T_s是实时代码操作的周期,这意味着系统都会每0.002秒运行一次。 为了方便,已经包括底部的typedef和waitForEnter()方法。

3.2 基本的演示程序

该程序打开和关闭重力补偿器。 在运行此程序(或大多数程序)之前,WAM必须都空闲并放置在已知的“home”位置(默认位置如图左侧所示)。 代码如下:

#first_program.cpp
#include “stdhdr.h”
int main(int argc, char** argv)
{
libconfig::Config config;
config.readFile("/etc/barrett/wam4.conf");

systems::RealTimeExecutionManager rtem(T_s, false); systems::System::defaultExecutionManager = &rtem;

Wam<DOF> wam(config.lookup("wam"));

rtem.start();

std::cout << "Press [Enter] to compensate for gravity.\n";
waitForEnter();
wam.gravityCompensate();

std::cout << "Play as long as you want, then idle the WAM and press [Enter] to exit.\n";
waitForEnter();

rtem.stop();
}


第一部分读取可互换的配置文件。 该文件包含重力补偿和其他内部WAM组件的校准设置。 但是,配置文件仅适用于重力校准(第4节)。

代码的第二部分调用执行管理器。 管理器是程序正常运行所必需的,因为它跟踪所有连接的系统,并告诉他们每0.002秒更新一次。 没有它,没有实时代码执行。

在创建WAM虚拟对象之前,WAM必须空闲并移动到原始位置,因为代码必须能够与物理WAM进行通信。 如果WAM尚未准备好通信,则会发生故障或错误。

当gravityCompensate()被调用时,这个函数是连接或断开连接系统的虚拟“软管”之一。 以下是libbarrett中的gravityCompensate()代码:

# gravityCompensate from wam-inl.h
void Wam<DOF>::gravityCompensate(bool compensate = true)
{
if (compensate) {
systems::forceConnect(gravity.output, jtSum.getInput(GRAVITY_INPUT));
} else {
systems::disconnect(jtSum.getInput(GRAVITY_INPUT));
}
}


这是将重力补偿器连接到Summer的代码。 将此代码与WAM对象的框图进行比较,以获得更好的视角。 我们实现了系统的预期效果; 他们可以随意连接,断开连接和混合,使代码灵活稳定,并使用上述的短代码进行链接。

3.3 设计原则

一个好的WAM程序既模块化又可靠。 代码应该是模块化的,所以它可以很容易地应用到任何编码序列中,而不需要太多的配置。 想想它就像每个类都是一个包含通道的块。 代码必须是可靠的,因为它可不可以破坏硬件。 例如,如果远程控制WAM,并且在控制PC和WAM PC之间切断连接,则需要以安全的方式写入代码,以避免碰撞和扭矩故障。

遵循这些准则,使程序更加健壮:

不要使用4或7,您可以使用变量DOF。许多程序,如果写得好,可以通过改变自由度的价值与任何一种手段一起工作。

使用循环递归数组,而不是通过硬数字引用它们。这使得代码更容易扩展。

给你的新代码尽可能少LITTLE信息;写入库以隔离数据,从而防止意外修改。

尽可能依赖libbarrett。您希望编写的代码(至少在第一个)可能比您认为是使用库的内置功能要简单得多。

从实时代码中分离出“思考”。实时传递信息,执行简洁的计算。它不用于等待输入,写入输出或处理大量数据。如果您尝试实时执行太多操作,则代码执行时间过长,并干扰控制WAM。

3.4 一个更加复杂的程序

在掌握了libbarrett的基础知识后,尝试使用更复杂的代码来利用libbarrett的所有功能是件好事。 一个例子如下所示:

#complex_program.cpp
#include “stdhdr.h”
int main(int argc, char** argv)
{
barrett::installExceptionHandler();

libconfig::Config config;
config.readFile("/etc/barrett/wam4.conf");

systems::RealTimeExecutionManager rtem(T_s, false); systems::System::defaultExecutionManager = &rtem;

Wam<DOF> wam(config.lookup("wam"));
system::ExposedOutput<jp_type> holder;

rtem.start();

std::cout << "Press [Enter] to compensate for gravity.\n";
waitForEnter();
wam.gravityCompensate(true);


请注意,直到这一点的代码与前一程序中的代码相同。 WAM对象被创建并被告知要补偿重力,使其处于一个稳定的平衡状态。 这是一个完美的“跳板”到下面的代码,这给了用户几种模式来放置WAM注意下面的代码如何监督 - 它不“做”任何事情,它只是传递执行执行管理器 到“做”。这是一个分离实时和非实时代码的例子。

bool going = true;
std::string line;
jp_type setPoint;
cp_type cartSetPoint;
std::cout << “Please enter a command below:\n”;
std::cout << “i = Idle (Gravity Compensation ONLY)\n”;
std::cout << “h = Hold Position\n”;
std::cout << “p = Go to Position\n”;
std::cout << “x = Exit\n\n”;
while (going) {
std::cout << “>>> ”;
std::getline(std::cin, line);
switch(line[0]) {
case ‘x’:
going = false;
break;
case ‘i’:
wam.idle();
break;
case ‘h’:
holder.setOutput(wam.getJointPositions()); wam.trackReferenceSignal(holder.output);
break;
case ‘p’:
std::cout << “x = ”;
std::cin >> cartSetPoint[0];
std::cout << “y = ”;
std::cin >> cartSetPoint[1];
std::cout >> “z = ”;
std::cin >> cartSetPoint[2];
wam.moveTo(cartSetPoint);
break;
}
}
rtem.stop();
}


该代码为用户提供了四个选项:hit’i’,’h’或’p’。

第一个“i”空闲,留下重力补偿,但是通过使用wam.idle()方法断开PID控制器,取消WAM可能关闭的所有其他命令。

第二个“h”使WAM试图通过WAM的关节位置的快照来告诉它维持它的位置。 TrackReferenceSignal()是非常有用的,因为它可以接受关节位置,扭矩,速度和笛卡尔位置,并有效地处理它们(这是监督控制器的一个特征)。 虽然它可以接受所有这些类型,但它们必须来自另一个系统的输出,以便控制器接受它们。

第三个,’p’将笛卡尔位置作为输入,并命令WAM将手臂的端点移动到该位置。 这使用moveTo()调用,其中几个WAM方法之一。 moveTo可以处理监督控制器可以的任何类型。

最后,’x’是退出选择; 它会导致循环中断和程序退出。

3.5 有系统的程序

现在,您可以尝试使用第一个系统进行简单的操作。 本手册中详细介绍了WAM中有四个关节。 尝试匹配关节,如3号关节和1号、4号关节和2号。当“匹配”时,如果抬起关节1,关节3也会上升。 为此,您首先需要获得关节位置的输入,然后链接两者。 最后,将结果设置为输出以发送到WAM。

为了使关节连接在一起,我们要连接的关节的关节位置必须被切换。 这(力)迫使其中一个移动到另一个移动的地方。 以下是所有操作发生的系统(LOCK_JOINTS):

#lock_joints.h
#ifndef LOCK_JOINTS_H_
#define LOCK_JOINTS_H_
#include <algorithm>
#include <barrett/units.h>
#include <barrett/systems/abstract/single_io.h>
class LockJoints : public barrett::systems::SingleIO<jp_type, jp_type> {
public:
static const int DOF = 4; typedef barrett::units::JointPositions<DOF>::type jp_type;
protected:
virtual void operate() {
jp = input.getValue();
std::swap(jp[0], jp[2]); std::swap(jp[1], jp[3]);
outputValue->setValue(jp);
}
private:
jp_type jp;
};
#endif /* LOCK_JOINTS_H_ */


这个类的关键是operation()函数。 这是ExecutionManager每.002秒调用的函数,以及所有其他系统中所有其他的operating()函数。 该系统从systems :: SingleIO模板接收值,该模板给它单个输入和单个输出。 operate()获取输入,进行操作,然后通过输出将其发送出去。 这是所有系统运行的基础 - 该系统将通过其输入和输出连接到其他系统,数据将通过这些连接移动通过系统网络。

了解实时代码后,了解实时代码的监督代码的作用也很重要。 以下是该程序的代码:

#lock_joints.cpp
#include “stdhdr.h”
#include “lock_joints.h”
int main(int argc, char** argv) {
std::cout << "Idle the WAM then press [Enter].\n";
waitForEnter();
libconfig::Config config;
config.readFile("/etc/barrett/wam4.conf");
systems::RealTimeExecutionManager rtem(T_s, false); systems::System::defaultExecutionManager = &rtem;
Wam<DOF> wam(config.lookup("wam"));
systems::LockJoints lockingSystem;
connect(wam.jpOutput, lockingSystem.input);
rtem.start();
std::cout << "Activate the WAM now.\n";
std::cout << "Press [Enter] to compensate for gravity.\n";
waitForEnter();
wam.gravityCompensate();
bool locked = false;
bool going = true;
std::string line;
while (going) {
std::cout << ">>> ";
std::getline(std::cin, line);
switch (line[0]) {
case 'x':
going = false;
break;
case 'l':
locked = !locked;
if (locked){
wam.moveTo(jp_type(0.0));
wam.trackReferenceSignal(lockingSystem.output);
} else {
wam.idle();
} break;
}
}
rtem.stop();
}


switch / case语句等待输入; ‘x’将退出,’l’将在正常的重力补偿和连接在一起的关节之间切换。 注意WAM在关节锁定之前如何移动到其零位置。 这样可以防止WAM突然间有些不可预测地移动,同时使其关节在绑定时相互匹配。 它通过确保它们已经处于安全的位置来开始。

4 附加程序(手续、步骤)

4.1 怎样建立和运行你的程序

Libbarrett是使用Eclipse,一个免费的开源开发平台,可在eclipse.org上获得。 根据您的系统和软件版本,可能需要进行某些配置。 Dan Cody(Barrett Technology,dc@barrett.com)可以回答有关配置的问题。

4.2 WAMdiscover SSH和putty

有关如何SSH的基础知识,http://en.wikipedia.org/wiki/Secure_Shell提供了一个很好的介绍。

有关通过SSH连接到WAM PC有几件事情。 首先,Barrett有一个程序,WAM Discover,它定位连接到本地网络的WAM。 WAM Discover可在Windows和Linux机器上运行,并允许在正确配置时从其界面直接连接到WAM。 在Linux下,“正确配置”表示您只需从提供的列表中选择所需的WAM,然后点击“连接”。 在Windows下,WAM Discover必须与PuTTY(一个免费的开源SSH客户端)在同一个文件夹中。 如果是这样,“连接”按钮将在WAM PC和用户的PC之间建立一个安全壳。 WAM的默认用户名为“robot”,默认密码为“WAM”。

通过SSH连接到WAM与连接到任何其他Ubuntu计算机相同。 Linux终端窗口的命令是在与WAM PC的SSH会话中使用的命令。 要更改WAM的名称,请更改默认密码,或添加用户,请参阅第4.3节。

以下是Windows下的WAM Discover和PuTTY的GUI图片。 在PuTTY中,一旦知道要连接的WAM的IP,您只需要在“主机名”字段中输入它,然后点击“打开”。在WAM Discover中,“刷新列表”使程序查找WAM, 和“连接”通过PuTTY打开一个连接。

4.3 管理和设置

本节介绍如何修改WAM的名称和用户设置。

要更改机器人帐户的默认密码:

SSH进入机器人帐户下的WAM PC。

2.将“passwd”键入终端。

3.输入您当前的密码。

4.按照提示输入新密码两次。

5.你完成了!

要添加新的WAM用户(应替换为所需的帐户名称):

1.SSH进入WAM PC。

2.键入“adduser ”。

3.按照提示输入用户密码。

4.在终端中输入“usermod -G adm,cdrom,audio,video,plugdev,admin,xenomai ”。

5.你完成了!

要更改WAMDiscover中显示的WAM的名称:

SSH进入WAM PC。

2.使用cd命令获取到“/ etc / barrett”。

3.使用VI或其他编辑器编辑“串行”文件。 无论你放在这个文件是什么会显示在WAMDiscover。

4.你完成了!

4.4 附加文档

除了您的WAM附带的打印材料之外,还有Barrett Technology网站上提供的教学视频,更多文档,错误修复和示例代码。 以下互联网地址将引导您进入这些存储库。

The Barrett Technology Support Wiki -wiki.barrett.com/support

本网站包含Barrett硬件和软件的教程,设置说明和修复程序。 您可以找到描述如何校准WAM的视频以及从哪里下载新软件。

Barrett Technology Forum – web.barrett.com/forum

论坛是一个很好的地方,提出问题,并得到工程师和其他客户的回应。 如果你的问题在维基中没有回答,就在这里了。

Libbarrett Doxygen Documentation - web.barrett.com/libbarrett/

该网站包含使用doxygen创建的Libbarrett库的文档。 浏览此资源将使您更深入地了解库的结构和使用方法。

Barrett Technology Mailing List -web.barrett.com/mailman/listinfo/wam

您可以在这里注册WAM listserv,这样您可以通过电子邮件轻松与其他WAM用户进行通信。

Barrett Support Email Address – support@barrett.com

如果您对Barrett产品有其他疑问,可以在这里询问。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息