2: 2021-04-27 (火) 09:48:10 takaboo | 3: 2021-05-04 (火) 22:03:01 takaboo | ||
---|---|---|---|
Line 46: | Line 46: | ||
| | [[USB2RS485 dongle>BTE079C]] | [[USB2TTL dongle>BTE080C]] | [[USB2DXIF dongle>BTE096]] | [[DXHUB>DXHUB2]] | [[U2D2>https://emanual.robotis.com/docs/en/parts/interface/u2d2/]] | | | | [[USB2RS485 dongle>BTE079C]] | [[USB2TTL dongle>BTE080C]] | [[USB2DXIF dongle>BTE096]] | [[DXHUB>DXHUB2]] | [[U2D2>https://emanual.robotis.com/docs/en/parts/interface/u2d2/]] | | ||
- | |~| #ref(http://www.besttechnology.co.jp/uploads/onlineshop/photos/e00267e5f30aeb4b7bdf.png,15%) | #ref(http://www.besttechnology.co.jp/uploads/onlineshop/photos/p00268p5f30af2505632.png,15%) | #ref(http://www.besttechnology.co.jp/uploads/onlineshop/photos/n00269n5f30af0648685.png,15%) | #ref(http://www.besttechnology.co.jp/uploads/onlineshop/photos/a00255a5dcac2c8eed34.png,15%) | #ref(http://www.besttechnology.co.jp/uploads/onlineshop/middles/k00208k5a9cf31f42b33.png,15%)| | + | |~| #ref(https://www.besttechnology.co.jp/uploads/onlineshop/photos/e00267e5f30aeb4b7bdf.png,15%) | #ref(https://www.besttechnology.co.jp/uploads/onlineshop/photos/p00268p5f30af2505632.png,15%) | #ref(https://www.besttechnology.co.jp/uploads/onlineshop/photos/n00269n5f30af0648685.png,15%) | #ref(https://www.besttechnology.co.jp/uploads/onlineshop/photos/a00255a5dcac2c8eed34.png,15%) | #ref(https://www.besttechnology.co.jp/uploads/onlineshop/middles/k00208k5a9cf31f42b33.png,15%)| |
|Manufacture | BestTechnology | < | < | < | ROBOTIS | | |Manufacture | BestTechnology | < | < | < | ROBOTIS | | ||
|USB | USB2.0 FS&br;USB Type-A | < | < | USB2.0 HS&br;USB Type-C | USB2.0 HS&br;micro USB Type-B | | |USB | USB2.0 FS&br;USB Type-A | < | < | USB2.0 HS&br;USB Type-C | USB2.0 HS&br;micro USB Type-B | | ||
Line 71: | Line 71: | ||
--XL330~ | --XL330~ | ||
5V・TTL・JST社コネクタ・コアドモータ・電流センサ搭載。現行モデル。 | 5V・TTL・JST社コネクタ・コアドモータ・電流センサ搭載。現行モデル。 | ||
+ | --XC330~ | ||
+ | 5V/12V・TTL・JST社コネクタ・コアレスモータ・電流センサ搭載。現行モデル。 | ||
--XL430~ | --XL430~ | ||
12V・TTL・JST社コネクタ・コアドモータ・電流センサ非搭載で廉価モデルという位置付け。2軸を内蔵した2XLもある。現行モデル。 | 12V・TTL・JST社コネクタ・コアドモータ・電流センサ非搭載で廉価モデルという位置付け。2軸を内蔵した2XLもある。現行モデル。 | ||
Line 79: | Line 81: | ||
--XH430/XH540~ | --XH430/XH540~ | ||
12/24V・TTL/RS-485・JST社コネクタ・maxon社コアレスモータ・電流センサ搭載で、トルクによって2種類の形状(430/540)がある。現行モデル。 | 12/24V・TTL/RS-485・JST社コネクタ・maxon社コアレスモータ・電流センサ搭載で、トルクによって2種類の形状(430/540)がある。現行モデル。 | ||
- | --XW~ | + | --XD430/XD540~ |
+ | 12V・RS-485・JST社コネクタ・maxon社コアレスモータ・高耐久・電流センサ搭載で、トルクによって2種類の形状(430/540)がある。現行モデル。 | ||
+ | --XW540~ | ||
12V・RS-485・防水コネクタ・maxon社コアレスモータ・電流センサ搭載。形状は1種類(540)。IP68に対応。現行モデル。 | 12V・RS-485・防水コネクタ・maxon社コアレスモータ・電流センサ搭載。形状は1種類(540)。IP68に対応。現行モデル。 | ||
-Pシリーズ~ | -Pシリーズ~ | ||
Line 414: | Line 418: | ||
-[[GCC Developer Liteをインストール>#gcd418f7]]し[[コンパイルオプションを設定>#l2754b74]] | -[[GCC Developer Liteをインストール>#gcd418f7]]し[[コンパイルオプションを設定>#l2754b74]] | ||
-ソースコード中のCOMポート番号を自身の環境に合わせて修正 | -ソースコード中のCOMポート番号を自身の環境に合わせて修正 | ||
- | -ソースコードファイルは拡張子が「.c」になるようにDX2LIBの4つのファイルを抽出した場所に保存 | + | -ソースコードファイルの拡張子は「.c」となるようにし、先のDX2LIBの4つのファイルを抽出した場所に保存 |
である。 | である。 | ||
Line 994: | Line 998: | ||
またあえて諸々の通信速度を9600bpsに変更した場合も、最終的な動作にどの程度影響するかを試しても面白い。~ | またあえて諸々の通信速度を9600bpsに変更した場合も、最終的な動作にどの程度影響するかを試しても面白い。~ | ||
その結果、Windows上でいわゆるリアルタイム性を担保するのは一筋縄ではいかない事が分かってもらえれば良いかと。 | その結果、Windows上でいわゆるリアルタイム性を担保するのは一筋縄ではいかない事が分かってもらえれば良いかと。 | ||
+ | |||
***他の言語 [#d5eca280] | ***他の言語 [#d5eca280] | ||
- | 既に[[DX2LIBのページ>DX2LIB#u3ff03d9]]に紹介されている通りだが、基本的にC言語上で動作させることが前提となっているために扱いづらい事が多々ある。それでも使えない事も無いので、やけに流行っている[[Python>https://www.python.jp/]]で遊んでみても面白いかと思う。~ | + | [[DX2LIBのページ>DX2LIB#u3ff03d9]]に紹介されている通りだが、その中でも流行の[[Python>https://www.python.jp/]]で遊んでみても面白いかと思う。~ |
- | 紹介したGCC Developer LiteにはPython3が含まれているので、コンパイルオプションで「Python(32bit)」を選べばライブラリに同梱されるPythonのサンプルソースコードが実行できる。 | + | GCC Developer LiteにはPythonが含まれており、コンパイルオプションで「Python(32bit)」や「Python(64bit)」を選ぶ事でライブラリに同梱されるPythonのサンプルソースコードが利用できる。しかし追加APIを利用したものばかりで、コントロールテーブルを読み書きする基本的なAPIは使われていない。 |
- | なおC言語で作成されたライブラリをPythonで利用するためにctypesを用いているため、正直言ってかなり面倒な面がある。 | + | |
+ | ここでは基本的なAPIのみを使った例を紹介するが、dx2lib.pyはC言語で作成されたライブラリをPythonで利用するためだけの記述がなされているため、Pythonならではの柔軟なコードがctypesによって変に厳格化されて使い勝手が悪い。~ | ||
+ | ひとまずDynamixel Xシリーズを前提とし、主要なアイテムのアドレスとコントロールテーブルを宣言してみた。 | ||
+ | #html{{ | ||
+ | <pre class="brush: python;"> | ||
+ | from ctypes import * | ||
+ | |||
+ | ADDRESS_X_MODEL_NUMBER = 0 #W | ||
+ | ADDRESS_X_MODEL_INFORMATION = 4 #L | ||
+ | ADDRESS_X_VERSION_FW = 6 #B | ||
+ | ADDRESS_X_ID = 7 #B | ||
+ | ADDRESS_X_BAUDRATE = 8 #B | ||
+ | ADDRESS_X_RETURN_DELAY_TIME = 9 #B | ||
+ | ADDRESS_X_DRIVE_MODE = 10 #B | ||
+ | ADDRESS_X_OPERATIING_MODE = 11 #B | ||
+ | ADDRESS_X_HOMING_OFFSET = 20 #L | ||
+ | ADDRESS_X_MAX_POSITION_LIMIT = 48 #L | ||
+ | ADDRESS_X_MIN_POSITION_LIMIT = 52 #L | ||
+ | ADDRESS_X_TORQUE_ENABLE = 64 #B | ||
+ | ADDRESS_X_LED_RED = 65 #B | ||
+ | ADDRESS_X_STATUS_RETURN_LEVEL = 69 #B | ||
+ | ADDRESS_X_HARDWARE_ERROR_STATUS = 70 #B | ||
+ | ADDRESS_X_VELOCITY_IGAIN = 76 #W | ||
+ | ADDRESS_X_VELOCITY_PGAIN = 78 #W | ||
+ | ADDRESS_X_POSITION_DGAIN = 80 #W | ||
+ | ADDRESS_X_POSITION_IGAIN = 82 #W | ||
+ | ADDRESS_X_POSITION_PGAIN = 84 #W | ||
+ | ADDRESS_X_GOAL_PWM = 100 #W | ||
+ | ADDRESS_X_GOAL_CURRENT = 102 #W | ||
+ | ADDRESS_X_GOAL_VELOCITY = 104 #L | ||
+ | ADDRESS_X_PROF_ACCELERATION = 108 #L | ||
+ | ADDRESS_X_PROF_VELOCITY = 112 #L | ||
+ | ADDRESS_X_GOAL_POSITION = 116 #L | ||
+ | ADDRESS_X_MOVING = 122 #B | ||
+ | ADDRESS_X_MOVING_STATUS = 123 #B | ||
+ | ADDRESS_X_PRESENT_PWM = 124 #W | ||
+ | ADDRESS_X_PRESENT_CURRENT = 126 #W | ||
+ | ADDRESS_X_PRESENT_VELOCITY = 128 #L | ||
+ | ADDRESS_X_PRESENT_POSITION = 132 #L | ||
+ | ADDRESS_X_VELOCITY_TRAJECTORY = 136 #L | ||
+ | ADDRESS_X_POSITION_TRAJECTORY = 140 #L | ||
+ | ADDRESS_X_PRESENT_VOLTAGE = 144 #W | ||
+ | ADDRESS_X_PRESENT_TEMP = 146 #B | ||
+ | |||
+ | class XCtrlTable(Structure): | ||
+ | _pack_ = 1 | ||
+ | _fields_ = [ | ||
+ | ('ModelNumber', c_uint16), | ||
+ | ('ModelInformation', c_uint32), | ||
+ | ('VersionofFirmware', c_uint8), | ||
+ | ('ID', c_uint8), | ||
+ | ('Baudrate', c_uint8), | ||
+ | ('ReturnDelayTime', c_uint8), | ||
+ | ('DriveMode', c_uint8), | ||
+ | ('OperatingMode', c_uint8), | ||
+ | ('SecondaryID', c_uint8), | ||
+ | ('ProtocolVersion', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('HomingOffset', c_int32), | ||
+ | ('MovingThreshold', c_uint32), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('TemperatureLimit', c_uint8), | ||
+ | ('MaxVoltageLimit', c_uint16), | ||
+ | ('MinVoltageLimit', c_uint16), | ||
+ | ('PWMLimit', c_uint16), | ||
+ | ('CurrentLimit', c_uint16), | ||
+ | ('AccelerationLimit', c_uint32), | ||
+ | ('VelocityLimit', c_uint32), | ||
+ | ('MaxPositionLimit', c_uint32), | ||
+ | ('MinPositionLimit', c_uint32), | ||
+ | ('ExternalPortMode1', c_uint8), | ||
+ | ('ExternalPortMode2', c_uint8), | ||
+ | ('ExternalPortMode3', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('Shutdown', c_uint8), | ||
+ | ('TorqueEnable', c_uint8), | ||
+ | ('LED', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('StatusReturnLevel', c_uint8), | ||
+ | ('RegisteredInstruction', c_uint8), | ||
+ | ('HardwareErrorStatus', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('VelocityIGain', c_uint16), | ||
+ | ('VelocityPGain', c_uint16), | ||
+ | ('PositionDGain', c_uint16), | ||
+ | ('PositionIGain', c_uint16), | ||
+ | ('PositionPGain', c_uint16), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('FeedforwardAccelerationGain', c_uint16), | ||
+ | ('FeedforwardVelocityGain, ', c_uint16), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('BusWatchdog', c_int8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('GoalPWM', c_int16), | ||
+ | ('GoalCurrent', c_int16), | ||
+ | ('GoalVelocity', c_int32), | ||
+ | ('ProfileAcceleration', c_uint32), | ||
+ | ('ProfileVelocity', c_uint32), | ||
+ | ('GoalPosition', c_int32), | ||
+ | ('RealtimeTick', c_uint16), | ||
+ | ('Moving', c_uint8), | ||
+ | ('MovingStatus', c_uint8), | ||
+ | ('PresentPWM', c_int16), | ||
+ | ('PresentCurrent', c_int16), | ||
+ | ('PresentVelocity', c_int32), | ||
+ | ('PresentPosition', c_int32), | ||
+ | ('VelocityTrajectory', c_uint32), | ||
+ | ('PositionTrajectory', c_uint32), | ||
+ | ('PresentInputVoltage', c_uint16), | ||
+ | ('PresentTemperature', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('reserve', c_uint8), | ||
+ | ('ExternalPortData1', c_uint16), | ||
+ | ('ExternalPortData2', c_uint16), | ||
+ | ('ExternalPortData3', c_uint16)] | ||
+ | |||
+ | class VelocityGain(Structure): | ||
+ | _pack_ = 1 | ||
+ | _fields_ = [ | ||
+ | ('VelocityIGain', c_uint16), | ||
+ | ('VelocityPGain', c_uint16)] | ||
+ | |||
+ | class PositionGain(Structure): | ||
+ | _pack_ = 1 | ||
+ | _fields_ = [ | ||
+ | ('PositionDGain', c_uint16), | ||
+ | ('PositionIGain', c_uint16), | ||
+ | ('PositionPGain', c_uint16)] | ||
+ | </pre> | ||
+ | }} | ||
+ | 例えばPresent PositionをID=1のDynamixelのコントロールテーブルから読み出すには、以下のコードで対応できる。 | ||
+ | #html{{ | ||
+ | <pre class="brush: python;"> | ||
+ | from dx2lib import * | ||
+ | |||
+ | dev = DX2_OpenPort (b'\\\\.\\COM3', 57600) | ||
+ | if dev != None: | ||
+ | ppos = c_int32() | ||
+ | err = c_uint16() | ||
+ | DX2_ReadLongData (dev, 1, ADDRESS_X_PRESENT_POSITION, cast(byref(ppos), POINTER(c_uint32)), err) | ||
+ | DX2_ClosePort (dev) | ||
+ | </pre> | ||
+ | }} | ||
+ | 更にXCtrlTable構造体を用いて変数を定義し、その変数へID=1のDynamixelのコントロールテーブルから一括読み出した値を保存する場合はDX2_ReadBlockDataを用いる。 | ||
+ | #html{{ | ||
+ | <pre class="brush: python;"> | ||
+ | from dx2lib import * | ||
+ | |||
+ | dev = DX2_OpenPort (b'\\\\.\\COM3', 57600) | ||
+ | if dev != None: | ||
+ | tbl = XCtrlTable() | ||
+ | err = c_uint16() | ||
+ | if DX2_ReadBlockData (dev, 1, ADDRESS_X_MODEL_NUMBER, cast(byref(tbl), POINTER(c_uint8)), sizeof(tbl), err): | ||
+ | for field in tbl._fields_: | ||
+ | if field[0] != 'reserve': | ||
+ | print (tbl.__class__.__dict__[field[0]].offset, field[0], '=', getattr(tbl, field[0])) | ||
+ | DX2_ClosePort (dev) | ||
+ | </pre> | ||
+ | }} | ||
+ | 位置決め制御時のPIDゲインを設定する等の連続したアドレスに割り当てられた複数のアイテムを同時に書き換える場合はDX2_WriteBlockDataを用いる。 | ||
+ | #html{{ | ||
+ | <pre class="brush: python;"> | ||
+ | from dx2lib import * | ||
+ | |||
+ | dev = DX2_OpenPort (b'\\\\.\\COM3', 57600) | ||
+ | if dev != None: | ||
+ | gain = PositionGain(0, 0, 400) | ||
+ | DX2_WriteBlockData (dev, 1, ADDRESS_X_POSITION_DGAIN, cast(byref(gain), POINTER(c_uint8)), sizeof (gain), None) | ||
+ | DX2_ClosePort (dev) | ||
+ | </pre> | ||
+ | }} | ||
+ | 追加APIに無い機能は基本APIを使ってコントロールテーブルへ直接アクセスするしかないため、参考にしてもらえればと思う。 |