Merge mechanism code #1
@@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root BTCPP_format="4">
|
||||
<BehaviorTree ID="seq">
|
||||
<Sequence>
|
||||
<Seq1 service_name=""/>
|
||||
<Seq2 text="0101"
|
||||
service_name=""/>
|
||||
<Seq3 service_name=""/>
|
||||
</Sequence>
|
||||
</BehaviorTree>
|
||||
|
||||
<BehaviorTree ID="seq1">
|
||||
<Sequence>
|
||||
<ZeroOdom service_name=""/>
|
||||
@@ -70,6 +79,20 @@
|
||||
<input_port name="action_name"
|
||||
type="std::string">Action server name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq1">
|
||||
<input_port name="service_name"
|
||||
type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq2">
|
||||
<input_port name="text"
|
||||
type="std::string"/>
|
||||
<input_port name="service_name"
|
||||
type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq3">
|
||||
<input_port name="service_name"
|
||||
type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="TranslateX">
|
||||
<input_port name="x"
|
||||
type="double"/>
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
action_name=""/>
|
||||
</Sequence>
|
||||
<ForceSuccess>
|
||||
<Timeout msec="13000">
|
||||
<DetectStuck timeout="1.000000">
|
||||
<MovePointSimple x="-1.0"
|
||||
y="0"
|
||||
theta="0"
|
||||
max_speed="0.070000"
|
||||
backwards="true"
|
||||
action_name=""/>
|
||||
</Timeout>
|
||||
</DetectStuck>
|
||||
</ForceSuccess>
|
||||
<SetWidth width="{width}"
|
||||
count="1"
|
||||
@@ -72,14 +72,14 @@
|
||||
action_name=""/>
|
||||
</Sequence>
|
||||
<ForceSuccess>
|
||||
<Timeout msec="9000">
|
||||
<DetectStuck timeout="1.000000">
|
||||
<MovePointSimple x="-0.2"
|
||||
y="0"
|
||||
theta="0"
|
||||
max_speed="0.05"
|
||||
backwards="true"
|
||||
action_name=""/>
|
||||
</Timeout>
|
||||
</DetectStuck>
|
||||
</ForceSuccess>
|
||||
<Sleep msec="1000"/>
|
||||
<EndCalib service_name=""/>
|
||||
@@ -102,6 +102,11 @@
|
||||
|
||||
<!-- Description of Node Models (used by Groot) -->
|
||||
<TreeNodesModel>
|
||||
<Decorator ID="DetectStuck">
|
||||
<input_port name="timeout"
|
||||
default="1.000000"
|
||||
type="double"/>
|
||||
</Decorator>
|
||||
<Action ID="EndCalib">
|
||||
<input_port name="service_name"
|
||||
type="std::string">Service name</input_port>
|
||||
|
||||
@@ -5,45 +5,55 @@
|
||||
<!-- Description of Node Models (used by Groot) -->
|
||||
<TreeNodesModel>
|
||||
<Decorator ID="DetectStuck">
|
||||
<input_port name="timeout" type="double" default="1.000000"/>
|
||||
<input_port name="timeout" default="1.000000" type="double"/>
|
||||
</Decorator>
|
||||
<Action ID="EndCalib">
|
||||
<input_port name="service_name" type="std::string" default="">Service name</input_port>
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="MovePointSimple">
|
||||
<input_port name="x" type="double"/>
|
||||
<input_port name="y" type="double"/>
|
||||
<input_port name="theta" type="double"/>
|
||||
<input_port name="max_speed" type="double" default="0.000000"/>
|
||||
<input_port name="backwards" type="bool" default="false"/>
|
||||
<input_port name="action_name" type="std::string" default="">Action server name</input_port>
|
||||
<input_port name="max_speed" default="0.000000" type="double"/>
|
||||
<input_port name="backwards" default="false" type="bool"/>
|
||||
<input_port name="action_name" type="std::string">Action server name</input_port>
|
||||
</Action>
|
||||
<Action ID="RotateSimple">
|
||||
<input_port name="angle" type="double"/>
|
||||
<input_port name="max_speed" type="double" default="0.000000"/>
|
||||
<input_port name="min_angle" type="double" default="0.000000"/>
|
||||
<input_port name="action_name" type="std::string" default="">Action server name</input_port>
|
||||
<input_port name="max_speed" default="0.000000" type="double"/>
|
||||
<input_port name="min_angle" default="0.000000" type="double"/>
|
||||
<input_port name="action_name" type="std::string">Action server name</input_port>
|
||||
</Action>
|
||||
<Action ID="RotateTowards">
|
||||
<input_port name="x" type="double"/>
|
||||
<input_port name="y" type="double"/>
|
||||
<input_port name="max_speed" type="double" default="0.000000"/>
|
||||
<input_port name="min_angle" type="double" default="0.000000"/>
|
||||
<input_port name="action_name" type="std::string" default="">Action server name</input_port>
|
||||
<input_port name="max_speed" default="0.000000" type="double"/>
|
||||
<input_port name="min_angle" default="0.000000" type="double"/>
|
||||
<input_port name="action_name" type="std::string">Action server name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq1">
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq2">
|
||||
<input_port name="text" type="std::string"/>
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="Seq3">
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="SetWidth">
|
||||
<input_port name="width" type="double"/>
|
||||
<input_port name="count" type="int" default="1"/>
|
||||
<input_port name="count" default="1" type="int"/>
|
||||
<output_port name="new_width" type="double"/>
|
||||
<input_port name="service_name" type="std::string" default="">Service name</input_port>
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
<Action ID="TranslateX">
|
||||
<input_port name="x" type="double"/>
|
||||
<input_port name="max_speed" type="double" default="0.000000"/>
|
||||
<input_port name="action_name" type="std::string" default="">Action server name</input_port>
|
||||
<input_port name="max_speed" default="0.000000" type="double"/>
|
||||
<input_port name="action_name" type="std::string">Action server name</input_port>
|
||||
</Action>
|
||||
<Action ID="ZeroOdom">
|
||||
<input_port name="service_name" type="std::string" default="">Service name</input_port>
|
||||
<input_port name="service_name" type="std::string">Service name</input_port>
|
||||
</Action>
|
||||
</TreeNodesModel>
|
||||
</root>
|
||||
|
||||
43
toid_bt/include/toid_bt/plugins/send_text_action.hpp
Normal file
43
toid_bt/include/toid_bt/plugins/send_text_action.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "angles/angles.h"
|
||||
#include "behaviortree_ros2/bt_service_node.hpp"
|
||||
#include "tf2/utils.hpp"
|
||||
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
|
||||
#include "toid_bt/plugin.hpp"
|
||||
|
||||
#include "toid_msgs/srv/send_string.hpp"
|
||||
|
||||
namespace toid
|
||||
{
|
||||
|
||||
class SendTextNode : public BT::RosServiceNode<toid_msgs::srv::SendString>
|
||||
{
|
||||
public:
|
||||
SendTextNode(
|
||||
const std::string & name, const BT::NodeConfig & conf, const BT::RosNodeParams & params)
|
||||
: BT::RosServiceNode<toid_msgs::srv::SendString>(name, conf, params)
|
||||
{
|
||||
}
|
||||
|
||||
static BT::PortsList providedPorts()
|
||||
{
|
||||
return providedBasicPorts({
|
||||
BT::InputPort<std::string>("text"),
|
||||
});
|
||||
}
|
||||
|
||||
bool setRequest(typename Request::SharedPtr &req) override {
|
||||
std::string text = getInput<std::string>("text").value_or("");
|
||||
req->text = text;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BT::NodeStatus onResponseReceived(const typename Response::SharedPtr &) override
|
||||
{
|
||||
return BT::NodeStatus::SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace toid
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "toid_bt/plugins/move_coords_action.hpp"
|
||||
#include "toid_bt/plugins/rotate_action.hpp"
|
||||
#include "toid_bt/plugins/rotate_towards_action.hpp"
|
||||
#include "toid_bt/plugins/send_text_action.hpp"
|
||||
#include "toid_bt/plugins/stuck_detector_decorator.hpp"
|
||||
#include "toid_bt/plugins/translate_x_action.hpp"
|
||||
|
||||
@@ -61,6 +62,14 @@ void TreeExecutor::registerNodesIntoFactory(BT::BehaviorTreeFactory & factory)
|
||||
|
||||
factory.registerNodeType<toid::EmptySrvNode>("EndCalib", BT::RosNodeParams(nh, "/end_calib"));
|
||||
|
||||
factory.registerNodeType<toid::EmptySrvNode>("Seq1", BT::RosNodeParams(nh, "/sequence1"));
|
||||
|
||||
BT::RosNodeParams service_params(nh, "/sequence2");
|
||||
service_params.server_timeout = std::chrono::seconds(15);
|
||||
factory.registerNodeType<toid::SendTextNode>("Seq2", service_params);
|
||||
|
||||
factory.registerNodeType<toid::EmptySrvNode>("Seq3", BT::RosNodeParams(nh, "/sequence3"));
|
||||
|
||||
factory.registerNodeType<toid::StuckDetectorNode>("DetectStuck", get_pose);
|
||||
|
||||
std::cout << describeCustomNodes() << std::endl;
|
||||
|
||||
20
toid_interaction/package.xml
Normal file
20
toid_interaction/package.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>toid_interaction</name>
|
||||
<version>0.0.0</version>
|
||||
<description>TODO: Package description</description>
|
||||
<maintainer email="82343504+pimpest@users.noreply.github.com">pimpest</maintainer>
|
||||
<license>MIT</license>
|
||||
|
||||
<test_depend>ament_copyright</test_depend>
|
||||
<test_depend>ament_flake8</test_depend>
|
||||
<test_depend>ament_pep257</test_depend>
|
||||
<test_depend>python3-pytest</test_depend>
|
||||
|
||||
<depend>python3-serial</depend>
|
||||
|
||||
<export>
|
||||
<build_type>ament_python</build_type>
|
||||
</export>
|
||||
</package>
|
||||
0
toid_interaction/resource/toid_interaction
Normal file
0
toid_interaction/resource/toid_interaction
Normal file
4
toid_interaction/setup.cfg
Normal file
4
toid_interaction/setup.cfg
Normal file
@@ -0,0 +1,4 @@
|
||||
[develop]
|
||||
script_dir=$base/lib/toid_interaction
|
||||
[install]
|
||||
install_scripts=$base/lib/toid_interaction
|
||||
31
toid_interaction/setup.py
Normal file
31
toid_interaction/setup.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
package_name = 'toid_interaction'
|
||||
|
||||
setup(
|
||||
name=package_name,
|
||||
version='0.0.0',
|
||||
packages=find_packages(exclude=['test']),
|
||||
data_files=[
|
||||
('share/ament_index/resource_index/packages',
|
||||
['resource/' + package_name]),
|
||||
('share/' + package_name, ['package.xml']),
|
||||
],
|
||||
install_requires=['setuptools'],
|
||||
zip_safe=True,
|
||||
maintainer='pimpest',
|
||||
maintainer_email='82343504+pimpest@users.noreply.github.com',
|
||||
description='TODO: Package description',
|
||||
license='MIT',
|
||||
extras_require={
|
||||
'test': [
|
||||
'pytest',
|
||||
],
|
||||
},
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'sequence = toid_interaction.mechanism.sekvenca_2026:main',
|
||||
'node = toid_interaction.interaction_node:main'
|
||||
],
|
||||
},
|
||||
)
|
||||
25
toid_interaction/test/test_copyright.py
Normal file
25
toid_interaction/test/test_copyright.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2015 Open Source Robotics Foundation, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from ament_copyright.main import main
|
||||
import pytest
|
||||
|
||||
|
||||
# Remove the `skip` decorator once the source file(s) have a copyright header
|
||||
@pytest.mark.skip(reason='No copyright header has been placed in the generated source file.')
|
||||
@pytest.mark.copyright
|
||||
@pytest.mark.linter
|
||||
def test_copyright():
|
||||
rc = main(argv=['.', 'test'])
|
||||
assert rc == 0, 'Found errors'
|
||||
25
toid_interaction/test/test_flake8.py
Normal file
25
toid_interaction/test/test_flake8.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2017 Open Source Robotics Foundation, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from ament_flake8.main import main_with_errors
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.flake8
|
||||
@pytest.mark.linter
|
||||
def test_flake8():
|
||||
rc, errors = main_with_errors(argv=[])
|
||||
assert rc == 0, \
|
||||
'Found %d code style errors / warnings:\n' % len(errors) + \
|
||||
'\n'.join(errors)
|
||||
23
toid_interaction/test/test_pep257.py
Normal file
23
toid_interaction/test/test_pep257.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright 2015 Open Source Robotics Foundation, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from ament_pep257.main import main
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.linter
|
||||
@pytest.mark.pep257
|
||||
def test_pep257():
|
||||
rc = main(argv=['.', 'test'])
|
||||
assert rc == 0, 'Found code style errors / warnings'
|
||||
0
toid_interaction/toid_interaction/__init__.py
Normal file
0
toid_interaction/toid_interaction/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
97
toid_interaction/toid_interaction/interaction_node.py
Normal file
97
toid_interaction/toid_interaction/interaction_node.py
Normal file
@@ -0,0 +1,97 @@
|
||||
import rclpy
|
||||
from rclpy.node import Node
|
||||
from std_srvs.srv import Empty
|
||||
|
||||
from serial.tools import list_ports
|
||||
|
||||
from toid_interaction.mechanism.sekvenca_2026 import okreni, okreni_niz
|
||||
from toid_interaction.mechanism.zidovi_load import ZidoviAction
|
||||
from toid_interaction.mechanism.zupcanik import ZupcanikAction
|
||||
from toid_msgs.srv import SendString
|
||||
|
||||
class InteracitionNode(Node):
|
||||
step: int = 0
|
||||
def __init__(self):
|
||||
super().__init__('ToidInteractionNode')
|
||||
|
||||
self.find_sigma()
|
||||
|
||||
self.srv = self.create_service(
|
||||
Empty,
|
||||
'/sequence1',
|
||||
self.sequence1_cb
|
||||
)
|
||||
|
||||
self.srv = self.create_service(
|
||||
SendString,
|
||||
'/sequence2',
|
||||
self.sequence2_cb
|
||||
)
|
||||
|
||||
self.srv = self.create_service(
|
||||
Empty,
|
||||
'/sequence3',
|
||||
self.sequence3_cb
|
||||
)
|
||||
|
||||
|
||||
|
||||
self.get_logger().info("Service 'sequence1' ready.")
|
||||
|
||||
def find_sigma(self):
|
||||
for port_info in list_ports.comports():
|
||||
if port_info.vid == 0x18a6 and port_info.pid == 0x55d3:
|
||||
break
|
||||
|
||||
print(port_info.device)
|
||||
self.st_motor_device_name = port_info.device
|
||||
|
||||
def sequence1_cb(self, request, response):
|
||||
if(self.step != 0):
|
||||
return Empty.Response()
|
||||
okreni(5)
|
||||
zupcanik = ZupcanikAction(self.st_motor_device_name)
|
||||
zupcanik.zupcanik(1, -1010, 25)
|
||||
self.step = 1
|
||||
return response
|
||||
|
||||
def sequence2_cb(self, request : SendString.Request, response : SendString.Response):
|
||||
if(self.step != 1):
|
||||
return Empty.Response()
|
||||
zidovi = ZidoviAction(self.st_motor_device_name)
|
||||
zidovi.beli_zid(1)
|
||||
zidovi.plavi_zid(1)
|
||||
|
||||
okreni_niz(request.text)
|
||||
|
||||
zidovi.plavi_zid(0, TargetPos=150)
|
||||
zidovi.beli_zid(0, TargetPos=450)
|
||||
self.step = 2
|
||||
return response
|
||||
|
||||
def sequence3_cb(self, request, response):
|
||||
if(self.step != 2):
|
||||
return Empty.Response()
|
||||
|
||||
zupcanik = ZupcanikAction(self.st_motor_device_name)
|
||||
zidovi = ZidoviAction(self.st_motor_device_name)
|
||||
|
||||
zupcanik.zupcanik(1, 1010, 25)
|
||||
zidovi.plavi_zid(0, TargetPos=150)
|
||||
zidovi.beli_zid(0, TargetPos=150)
|
||||
okreni(5)
|
||||
self.step = 0
|
||||
return response
|
||||
|
||||
|
||||
def main(args=None):
|
||||
rclpy.init(args=args)
|
||||
|
||||
node = InteracitionNode()
|
||||
rclpy.spin(node)
|
||||
|
||||
rclpy.shutdown()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .port_handler import *
|
||||
from .protocol_packet_handler import *
|
||||
from .group_sync_write import *
|
||||
from .group_sync_read import *
|
||||
from .sts import *
|
||||
from .scscl import *
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .stservo_def import *
|
||||
|
||||
class GroupSyncRead:
|
||||
def __init__(self, ph, start_address, data_length):
|
||||
self.ph = ph
|
||||
self.start_address = start_address
|
||||
self.data_length = data_length
|
||||
|
||||
self.last_result = False
|
||||
self.is_param_changed = False
|
||||
self.param = []
|
||||
self.data_dict = {}
|
||||
|
||||
self.clearParam()
|
||||
|
||||
def makeParam(self):
|
||||
if not self.data_dict: # len(self.data_dict.keys()) == 0:
|
||||
return
|
||||
|
||||
self.param = []
|
||||
|
||||
for scs_id in self.data_dict:
|
||||
self.param.append(scs_id)
|
||||
|
||||
def addParam(self, sts_id):
|
||||
if sts_id in self.data_dict: # sts_id already exist
|
||||
return False
|
||||
|
||||
self.data_dict[sts_id] = [] # [0] * self.data_length
|
||||
|
||||
self.is_param_changed = True
|
||||
return True
|
||||
|
||||
def removeParam(self, sts_id):
|
||||
if sts_id not in self.data_dict: # NOT exist
|
||||
return
|
||||
|
||||
del self.data_dict[sts_id]
|
||||
|
||||
self.is_param_changed = True
|
||||
|
||||
def clearParam(self):
|
||||
self.data_dict.clear()
|
||||
|
||||
def txPacket(self):
|
||||
if len(self.data_dict.keys()) == 0:
|
||||
|
||||
return COMM_NOT_AVAILABLE
|
||||
|
||||
if self.is_param_changed is True or not self.param:
|
||||
self.makeParam()
|
||||
|
||||
return self.ph.syncReadTx(self.start_address, self.data_length, self.param, len(self.data_dict.keys()))
|
||||
|
||||
def rxPacket(self):
|
||||
self.last_result = True
|
||||
|
||||
result = COMM_RX_FAIL
|
||||
|
||||
if len(self.data_dict.keys()) == 0:
|
||||
return COMM_NOT_AVAILABLE
|
||||
|
||||
result, rxpacket = self.ph.syncReadRx(self.data_length, len(self.data_dict.keys()))
|
||||
# print(rxpacket)
|
||||
if len(rxpacket) >= (self.data_length+6):
|
||||
for sts_id in self.data_dict:
|
||||
self.data_dict[sts_id], result = self.readRx(rxpacket, sts_id, self.data_length)
|
||||
if result != COMM_SUCCESS:
|
||||
self.last_result = False
|
||||
# print(sts_id)
|
||||
else:
|
||||
self.last_result = False
|
||||
# print(self.last_result)
|
||||
return result
|
||||
|
||||
def txRxPacket(self):
|
||||
result = self.txPacket()
|
||||
if result != COMM_SUCCESS:
|
||||
return result
|
||||
|
||||
return self.rxPacket()
|
||||
|
||||
def readRx(self, rxpacket, sts_id, data_length):
|
||||
# print(sts_id)
|
||||
# print(rxpacket)
|
||||
data = []
|
||||
rx_length = len(rxpacket)
|
||||
# print(rx_length)
|
||||
rx_index = 0;
|
||||
while (rx_index+6+data_length) <= rx_length:
|
||||
headpacket = [0x00, 0x00, 0x00]
|
||||
while rx_index < rx_length:
|
||||
headpacket[2] = headpacket[1];
|
||||
headpacket[1] = headpacket[0];
|
||||
headpacket[0] = rxpacket[rx_index];
|
||||
rx_index += 1
|
||||
if (headpacket[2] == 0xFF) and (headpacket[1] == 0xFF) and headpacket[0] == sts_id:
|
||||
# print(rx_index)
|
||||
break
|
||||
# print(rx_index+3+data_length)
|
||||
if (rx_index+3+data_length) > rx_length:
|
||||
break;
|
||||
if rxpacket[rx_index] != (data_length+2):
|
||||
rx_index += 1
|
||||
# print(rx_index)
|
||||
continue
|
||||
rx_index += 1
|
||||
Error = rxpacket[rx_index]
|
||||
rx_index += 1
|
||||
calSum = sts_id + (data_length+2) + Error
|
||||
data = [Error]
|
||||
data.extend(rxpacket[rx_index : rx_index+data_length])
|
||||
for i in range(0, data_length):
|
||||
calSum += rxpacket[rx_index]
|
||||
rx_index += 1
|
||||
calSum = ~calSum & 0xFF
|
||||
# print(calSum)
|
||||
if calSum != rxpacket[rx_index]:
|
||||
return None, COMM_RX_CORRUPT
|
||||
return data, COMM_SUCCESS
|
||||
# print(rx_index)
|
||||
return None, COMM_RX_CORRUPT
|
||||
|
||||
def isAvailable(self, sts_id, address, data_length):
|
||||
#if self.last_result is False or sts_id not in self.data_dict:
|
||||
if sts_id not in self.data_dict:
|
||||
return False, 0
|
||||
|
||||
if (address < self.start_address) or (self.start_address + self.data_length - data_length < address):
|
||||
return False, 0
|
||||
if not self.data_dict[sts_id]:
|
||||
return False, 0
|
||||
if len(self.data_dict[sts_id])<(data_length+1):
|
||||
return False, 0
|
||||
return True, self.data_dict[sts_id][0]
|
||||
|
||||
def getData(self, sts_id, address, data_length):
|
||||
if data_length == 1:
|
||||
return self.data_dict[sts_id][address-self.start_address+1]
|
||||
elif data_length == 2:
|
||||
return self.ph.scs_makeword(self.data_dict[sts_id][address-self.start_address+1],
|
||||
self.data_dict[sts_id][address-self.start_address+2])
|
||||
elif data_length == 4:
|
||||
return self.ph.scs_makedword(self.ph.scs_makeword(self.data_dict[sts_id][address-self.start_address+1],
|
||||
self.data_dict[sts_id][address-self.start_address+2]),
|
||||
self.ph.scs_makeword(self.data_dict[sts_id][address-self.start_address+3],
|
||||
self.data_dict[sts_id][address-self.start_address+4]))
|
||||
else:
|
||||
return 0
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .stservo_def import *
|
||||
|
||||
class GroupSyncWrite:
|
||||
def __init__(self, ph, start_address, data_length):
|
||||
self.ph = ph
|
||||
self.start_address = start_address
|
||||
self.data_length = data_length
|
||||
|
||||
self.is_param_changed = False
|
||||
self.param = []
|
||||
self.data_dict = {}
|
||||
|
||||
self.clearParam()
|
||||
|
||||
def makeParam(self):
|
||||
if not self.data_dict:
|
||||
return
|
||||
|
||||
self.param = []
|
||||
|
||||
for sts_id in self.data_dict:
|
||||
if not self.data_dict[sts_id]:
|
||||
return
|
||||
|
||||
self.param.append(sts_id)
|
||||
self.param.extend(self.data_dict[sts_id])
|
||||
|
||||
def addParam(self, sts_id, data):
|
||||
if sts_id in self.data_dict: # sts_id already exist
|
||||
return False
|
||||
|
||||
if len(data) > self.data_length: # input data is longer than set
|
||||
return False
|
||||
|
||||
self.data_dict[sts_id] = data
|
||||
|
||||
self.is_param_changed = True
|
||||
return True
|
||||
|
||||
def removeParam(self, sts_id):
|
||||
if sts_id not in self.data_dict: # NOT exist
|
||||
return
|
||||
|
||||
del self.data_dict[sts_id]
|
||||
|
||||
self.is_param_changed = True
|
||||
|
||||
def changeParam(self, sts_id, data):
|
||||
if sts_id not in self.data_dict: # NOT exist
|
||||
return False
|
||||
|
||||
if len(data) > self.data_length: # input data is longer than set
|
||||
return False
|
||||
|
||||
self.data_dict[sts_id] = data
|
||||
|
||||
self.is_param_changed = True
|
||||
return True
|
||||
|
||||
def clearParam(self):
|
||||
self.data_dict.clear()
|
||||
|
||||
def txPacket(self):
|
||||
if len(self.data_dict.keys()) == 0:
|
||||
return COMM_NOT_AVAILABLE
|
||||
|
||||
if self.is_param_changed is True or not self.param:
|
||||
self.makeParam()
|
||||
|
||||
return self.ph.syncWriteTxOnly(self.start_address, self.data_length, self.param,
|
||||
len(self.data_dict.keys()) * (1 + self.data_length))
|
||||
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import time
|
||||
import serial
|
||||
import sys
|
||||
import platform
|
||||
|
||||
DEFAULT_BAUDRATE = 1000000
|
||||
LATENCY_TIMER = 50
|
||||
|
||||
class PortHandler(object):
|
||||
def __init__(self, port_name):
|
||||
self.is_open = False
|
||||
self.baudrate = DEFAULT_BAUDRATE
|
||||
self.packet_start_time = 0.0
|
||||
self.packet_timeout = 0.0
|
||||
self.tx_time_per_byte = 0.0
|
||||
|
||||
self.is_using = False
|
||||
self.port_name = port_name
|
||||
self.ser = None
|
||||
|
||||
def openPort(self):
|
||||
return self.setBaudRate(self.baudrate)
|
||||
|
||||
def closePort(self):
|
||||
self.ser.close()
|
||||
self.is_open = False
|
||||
|
||||
def clearPort(self):
|
||||
self.ser.flush()
|
||||
|
||||
def setPortName(self, port_name):
|
||||
self.port_name = port_name
|
||||
|
||||
def getPortName(self):
|
||||
return self.port_name
|
||||
|
||||
def setBaudRate(self, baudrate):
|
||||
baud = self.getCFlagBaud(baudrate)
|
||||
|
||||
if baud <= 0:
|
||||
# self.setupPort(38400)
|
||||
# self.baudrate = baudrate
|
||||
return False # TODO: setCustomBaudrate(baudrate)
|
||||
else:
|
||||
self.baudrate = baudrate
|
||||
return self.setupPort(baud)
|
||||
|
||||
def getBaudRate(self):
|
||||
return self.baudrate
|
||||
|
||||
def getBytesAvailable(self):
|
||||
return self.ser.in_waiting
|
||||
|
||||
def readPort(self, length):
|
||||
if (sys.version_info > (3, 0)):
|
||||
return self.ser.read(length)
|
||||
else:
|
||||
return [ord(ch) for ch in self.ser.read(length)]
|
||||
|
||||
def writePort(self, packet):
|
||||
return self.ser.write(packet)
|
||||
|
||||
def setPacketTimeout(self, packet_length):
|
||||
self.packet_start_time = self.getCurrentTime()
|
||||
self.packet_timeout = (self.tx_time_per_byte * packet_length) + (self.tx_time_per_byte * 3.0) + LATENCY_TIMER
|
||||
|
||||
def setPacketTimeoutMillis(self, msec):
|
||||
self.packet_start_time = self.getCurrentTime()
|
||||
self.packet_timeout = msec
|
||||
|
||||
def isPacketTimeout(self):
|
||||
if self.getTimeSinceStart() > self.packet_timeout:
|
||||
self.packet_timeout = 0
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def getCurrentTime(self):
|
||||
return round(time.time() * 1000000000) / 1000000.0
|
||||
|
||||
def getTimeSinceStart(self):
|
||||
time_since = self.getCurrentTime() - self.packet_start_time
|
||||
if time_since < 0.0:
|
||||
self.packet_start_time = self.getCurrentTime()
|
||||
|
||||
return time_since
|
||||
|
||||
def setupPort(self, cflag_baud):
|
||||
if self.is_open:
|
||||
self.closePort()
|
||||
|
||||
self.ser = serial.Serial(
|
||||
port=self.port_name,
|
||||
baudrate=self.baudrate,
|
||||
# parity = serial.PARITY_ODD,
|
||||
# stopbits = serial.STOPBITS_TWO,
|
||||
bytesize=serial.EIGHTBITS,
|
||||
timeout=0
|
||||
)
|
||||
|
||||
self.is_open = True
|
||||
|
||||
self.ser.reset_input_buffer()
|
||||
|
||||
self.tx_time_per_byte = (1000.0 / self.baudrate) * 10.0
|
||||
|
||||
return True
|
||||
|
||||
def getCFlagBaud(self, baudrate):
|
||||
if baudrate in [4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 250000, 500000, 1000000]:
|
||||
return baudrate
|
||||
else:
|
||||
return -1
|
||||
@@ -0,0 +1,530 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .stservo_def import *
|
||||
|
||||
TXPACKET_MAX_LEN = 250
|
||||
RXPACKET_MAX_LEN = 250
|
||||
|
||||
# for Protocol Packet
|
||||
PKT_HEADER0 = 0
|
||||
PKT_HEADER1 = 1
|
||||
PKT_ID = 2
|
||||
PKT_LENGTH = 3
|
||||
PKT_INSTRUCTION = 4
|
||||
PKT_ERROR = 4
|
||||
PKT_PARAMETER0 = 5
|
||||
|
||||
# Protocol Error bit
|
||||
ERRBIT_VOLTAGE = 1
|
||||
ERRBIT_ANGLE = 2
|
||||
ERRBIT_OVERHEAT = 4
|
||||
ERRBIT_OVERELE = 8
|
||||
ERRBIT_OVERLOAD = 32
|
||||
|
||||
|
||||
class protocol_packet_handler(object):
|
||||
def __init__(self, portHandler, protocol_end):
|
||||
#self.sts_setend(protocol_end)# STServo bit end(STS/SMS=0, SCS=1)
|
||||
self.portHandler = portHandler
|
||||
self.sts_end = protocol_end
|
||||
|
||||
def sts_getend(self):
|
||||
return self.sts_end
|
||||
|
||||
def sts_setend(self, e):
|
||||
self.sts_end = e
|
||||
|
||||
def sts_tohost(self, a, b):
|
||||
if (a & (1<<b)):
|
||||
return -(a & ~(1<<b))
|
||||
else:
|
||||
return a
|
||||
|
||||
def sts_toscs(self, a, b):
|
||||
if (a<0):
|
||||
return (-a | (1<<b))
|
||||
else:
|
||||
return a
|
||||
|
||||
def sts_makeword(self, a, b):
|
||||
if self.sts_end==0:
|
||||
return (a & 0xFF) | ((b & 0xFF) << 8)
|
||||
else:
|
||||
return (b & 0xFF) | ((a & 0xFF) << 8)
|
||||
|
||||
def sts_makedword(self, a, b):
|
||||
return (a & 0xFFFF) | (b & 0xFFFF) << 16
|
||||
|
||||
def sts_loword(self, l):
|
||||
return l & 0xFFFF
|
||||
|
||||
def sts_hiword(self, h):
|
||||
return (h >> 16) & 0xFFFF
|
||||
|
||||
def sts_lobyte(self, w):
|
||||
if self.sts_end==0:
|
||||
return w & 0xFF
|
||||
else:
|
||||
return (w >> 8) & 0xFF
|
||||
|
||||
def sts_hibyte(self, w):
|
||||
if self.sts_end==0:
|
||||
return (w >> 8) & 0xFF
|
||||
else:
|
||||
return w & 0xFF
|
||||
|
||||
def getProtocolVersion(self):
|
||||
return 1.0
|
||||
|
||||
def getTxRxResult(self, result):
|
||||
if result == COMM_SUCCESS:
|
||||
return "[TxRxResult] Communication success!"
|
||||
elif result == COMM_PORT_BUSY:
|
||||
return "[TxRxResult] Port is in use!"
|
||||
elif result == COMM_TX_FAIL:
|
||||
return "[TxRxResult] Failed transmit instruction packet!"
|
||||
elif result == COMM_RX_FAIL:
|
||||
return "[TxRxResult] Failed get status packet from device!"
|
||||
elif result == COMM_TX_ERROR:
|
||||
return "[TxRxResult] Incorrect instruction packet!"
|
||||
elif result == COMM_RX_WAITING:
|
||||
return "[TxRxResult] Now receiving status packet!"
|
||||
elif result == COMM_RX_TIMEOUT:
|
||||
return "[TxRxResult] There is no status packet!"
|
||||
elif result == COMM_RX_CORRUPT:
|
||||
return "[TxRxResult] Incorrect status packet!"
|
||||
elif result == COMM_NOT_AVAILABLE:
|
||||
return "[TxRxResult] Protocol does not support this function!"
|
||||
else:
|
||||
return ""
|
||||
|
||||
def getRxPacketError(self, error):
|
||||
if error & ERRBIT_VOLTAGE:
|
||||
return "[ServoStatus] Input voltage error!"
|
||||
|
||||
if error & ERRBIT_ANGLE:
|
||||
return "[ServoStatus] Angle sen error!"
|
||||
|
||||
if error & ERRBIT_OVERHEAT:
|
||||
return "[ServoStatus] Overheat error!"
|
||||
|
||||
if error & ERRBIT_OVERELE:
|
||||
return "[ServoStatus] OverEle error!"
|
||||
|
||||
if error & ERRBIT_OVERLOAD:
|
||||
return "[ServoStatus] Overload error!"
|
||||
|
||||
return ""
|
||||
|
||||
def txPacket(self, txpacket):
|
||||
checksum = 0
|
||||
total_packet_length = txpacket[PKT_LENGTH] + 4 # 4: HEADER0 HEADER1 ID LENGTH
|
||||
|
||||
if self.portHandler.is_using:
|
||||
return COMM_PORT_BUSY
|
||||
self.portHandler.is_using = True
|
||||
|
||||
# check max packet length
|
||||
if total_packet_length > TXPACKET_MAX_LEN:
|
||||
self.portHandler.is_using = False
|
||||
return COMM_TX_ERROR
|
||||
|
||||
# make packet header
|
||||
txpacket[PKT_HEADER0] = 0xFF
|
||||
txpacket[PKT_HEADER1] = 0xFF
|
||||
|
||||
# add a checksum to the packet
|
||||
for idx in range(2, total_packet_length - 1): # except header, checksum
|
||||
checksum += txpacket[idx]
|
||||
|
||||
txpacket[total_packet_length - 1] = ~checksum & 0xFF
|
||||
|
||||
#print "[TxPacket] %r" % txpacket
|
||||
|
||||
# tx packet
|
||||
self.portHandler.clearPort()
|
||||
written_packet_length = self.portHandler.writePort(txpacket)
|
||||
if total_packet_length != written_packet_length:
|
||||
self.portHandler.is_using = False
|
||||
return COMM_TX_FAIL
|
||||
|
||||
return COMM_SUCCESS
|
||||
|
||||
def rxPacket(self):
|
||||
rxpacket = []
|
||||
|
||||
result = COMM_TX_FAIL
|
||||
checksum = 0
|
||||
rx_length = 0
|
||||
wait_length = 6 # minimum length (HEADER0 HEADER1 ID LENGTH ERROR CHKSUM)
|
||||
|
||||
while True:
|
||||
rxpacket.extend(self.portHandler.readPort(wait_length - rx_length))
|
||||
rx_length = len(rxpacket)
|
||||
if rx_length >= wait_length:
|
||||
# find packet header
|
||||
for idx in range(0, (rx_length - 1)):
|
||||
if (rxpacket[idx] == 0xFF) and (rxpacket[idx + 1] == 0xFF):
|
||||
break
|
||||
|
||||
if idx == 0: # found at the beginning of the packet
|
||||
if (rxpacket[PKT_ID] > 0xFD) or (rxpacket[PKT_LENGTH] > RXPACKET_MAX_LEN) or (
|
||||
rxpacket[PKT_ERROR] > 0x7F):
|
||||
# unavailable ID or unavailable Length or unavailable Error
|
||||
# remove the first byte in the packet
|
||||
del rxpacket[0]
|
||||
rx_length -= 1
|
||||
continue
|
||||
|
||||
# re-calculate the exact length of the rx packet
|
||||
if wait_length != (rxpacket[PKT_LENGTH] + PKT_LENGTH + 1):
|
||||
wait_length = rxpacket[PKT_LENGTH] + PKT_LENGTH + 1
|
||||
continue
|
||||
|
||||
if rx_length < wait_length:
|
||||
# check timeout
|
||||
if self.portHandler.isPacketTimeout():
|
||||
if rx_length == 0:
|
||||
result = COMM_RX_TIMEOUT
|
||||
else:
|
||||
result = COMM_RX_CORRUPT
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
# calculate checksum
|
||||
for i in range(2, wait_length - 1): # except header, checksum
|
||||
checksum += rxpacket[i]
|
||||
checksum = ~checksum & 0xFF
|
||||
|
||||
# verify checksum
|
||||
if rxpacket[wait_length - 1] == checksum:
|
||||
result = COMM_SUCCESS
|
||||
else:
|
||||
result = COMM_RX_CORRUPT
|
||||
break
|
||||
|
||||
else:
|
||||
# remove unnecessary packets
|
||||
del rxpacket[0: idx]
|
||||
rx_length -= idx
|
||||
|
||||
else:
|
||||
# check timeout
|
||||
if self.portHandler.isPacketTimeout():
|
||||
if rx_length == 0:
|
||||
result = COMM_RX_TIMEOUT
|
||||
else:
|
||||
result = COMM_RX_CORRUPT
|
||||
break
|
||||
|
||||
self.portHandler.is_using = False
|
||||
return rxpacket, result
|
||||
|
||||
def txRxPacket(self, txpacket):
|
||||
rxpacket = None
|
||||
error = 0
|
||||
|
||||
# tx packet
|
||||
result = self.txPacket(txpacket)
|
||||
if result != COMM_SUCCESS:
|
||||
return rxpacket, result, error
|
||||
|
||||
# (ID == Broadcast ID) == no need to wait for status packet or not available
|
||||
if (txpacket[PKT_ID] == BROADCAST_ID):
|
||||
self.portHandler.is_using = False
|
||||
return rxpacket, result, error
|
||||
|
||||
# set packet timeout
|
||||
if txpacket[PKT_INSTRUCTION] == INST_READ:
|
||||
self.portHandler.setPacketTimeout(txpacket[PKT_PARAMETER0 + 1] + 6)
|
||||
else:
|
||||
self.portHandler.setPacketTimeout(6) # HEADER0 HEADER1 ID LENGTH ERROR CHECKSUM
|
||||
|
||||
# rx packet
|
||||
while True:
|
||||
rxpacket, result = self.rxPacket()
|
||||
if result != COMM_SUCCESS or txpacket[PKT_ID] == rxpacket[PKT_ID]:
|
||||
break
|
||||
|
||||
if result == COMM_SUCCESS and txpacket[PKT_ID] == rxpacket[PKT_ID]:
|
||||
error = rxpacket[PKT_ERROR]
|
||||
|
||||
return rxpacket, result, error
|
||||
|
||||
def ping(self, sts_id):
|
||||
model_number = 0
|
||||
error = 0
|
||||
|
||||
txpacket = [0] * 6
|
||||
|
||||
if sts_id >= BROADCAST_ID:
|
||||
return model_number, COMM_NOT_AVAILABLE, error
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = 2
|
||||
txpacket[PKT_INSTRUCTION] = INST_PING
|
||||
|
||||
rxpacket, result, error = self.txRxPacket(txpacket)
|
||||
|
||||
if result == COMM_SUCCESS:
|
||||
data_read, result, error = self.readTxRx(sts_id, 3, 2) # Address 3 : Model Number
|
||||
if result == COMM_SUCCESS:
|
||||
model_number = self.sts_makeword(data_read[0], data_read[1])
|
||||
|
||||
return model_number, result, error
|
||||
|
||||
def action(self, sts_id):
|
||||
txpacket = [0] * 6
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = 2
|
||||
txpacket[PKT_INSTRUCTION] = INST_ACTION
|
||||
|
||||
_, result, _ = self.txRxPacket(txpacket)
|
||||
|
||||
return result
|
||||
|
||||
def readTx(self, sts_id, address, length):
|
||||
|
||||
txpacket = [0] * 8
|
||||
|
||||
if sts_id >= BROADCAST_ID:
|
||||
return COMM_NOT_AVAILABLE
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = 4
|
||||
txpacket[PKT_INSTRUCTION] = INST_READ
|
||||
txpacket[PKT_PARAMETER0 + 0] = address
|
||||
txpacket[PKT_PARAMETER0 + 1] = length
|
||||
|
||||
result = self.txPacket(txpacket)
|
||||
|
||||
# set packet timeout
|
||||
if result == COMM_SUCCESS:
|
||||
self.portHandler.setPacketTimeout(length + 6)
|
||||
|
||||
return result
|
||||
|
||||
def readRx(self, sts_id, length):
|
||||
result = COMM_TX_FAIL
|
||||
error = 0
|
||||
|
||||
rxpacket = None
|
||||
data = []
|
||||
|
||||
while True:
|
||||
rxpacket, result = self.rxPacket()
|
||||
|
||||
if result != COMM_SUCCESS or rxpacket[PKT_ID] == sts_id:
|
||||
break
|
||||
|
||||
if result == COMM_SUCCESS and rxpacket[PKT_ID] == sts_id:
|
||||
error = rxpacket[PKT_ERROR]
|
||||
|
||||
data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length])
|
||||
|
||||
return data, result, error
|
||||
|
||||
def readTxRx(self, sts_id, address, length):
|
||||
txpacket = [0] * 8
|
||||
data = []
|
||||
|
||||
if sts_id >= BROADCAST_ID:
|
||||
return data, COMM_NOT_AVAILABLE, 0
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = 4
|
||||
txpacket[PKT_INSTRUCTION] = INST_READ
|
||||
txpacket[PKT_PARAMETER0 + 0] = address
|
||||
txpacket[PKT_PARAMETER0 + 1] = length
|
||||
|
||||
rxpacket, result, error = self.txRxPacket(txpacket)
|
||||
if result == COMM_SUCCESS:
|
||||
error = rxpacket[PKT_ERROR]
|
||||
|
||||
data.extend(rxpacket[PKT_PARAMETER0 : PKT_PARAMETER0+length])
|
||||
|
||||
return data, result, error
|
||||
|
||||
def read1ByteTx(self, sts_id, address):
|
||||
return self.readTx(sts_id, address, 1)
|
||||
|
||||
def read1ByteRx(self, sts_id):
|
||||
data, result, error = self.readRx(sts_id, 1)
|
||||
data_read = data[0] if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def read1ByteTxRx(self, sts_id, address):
|
||||
data, result, error = self.readTxRx(sts_id, address, 1)
|
||||
data_read = data[0] if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def read2ByteTx(self, sts_id, address):
|
||||
return self.readTx(sts_id, address, 2)
|
||||
|
||||
def read2ByteRx(self, sts_id):
|
||||
data, result, error = self.readRx(sts_id, 2)
|
||||
data_read = self.sts_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def read2ByteTxRx(self, sts_id, address):
|
||||
data, result, error = self.readTxRx(sts_id, address, 2)
|
||||
data_read = self.sts_makeword(data[0], data[1]) if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def read4ByteTx(self, sts_id, address):
|
||||
return self.readTx(sts_id, address, 4)
|
||||
|
||||
def read4ByteRx(self, sts_id):
|
||||
data, result, error = self.readRx(sts_id, 4)
|
||||
data_read = self.sts_makedword(self.sts_makeword(data[0], data[1]),
|
||||
self.sts_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def read4ByteTxRx(self, sts_id, address):
|
||||
data, result, error = self.readTxRx(sts_id, address, 4)
|
||||
data_read = self.sts_makedword(self.sts_makeword(data[0], data[1]),
|
||||
self.sts_makeword(data[2], data[3])) if (result == COMM_SUCCESS) else 0
|
||||
return data_read, result, error
|
||||
|
||||
def writeTxOnly(self, sts_id, address, length, data):
|
||||
txpacket = [0] * (length + 7)
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = length + 3
|
||||
txpacket[PKT_INSTRUCTION] = INST_WRITE
|
||||
txpacket[PKT_PARAMETER0] = address
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
|
||||
|
||||
result = self.txPacket(txpacket)
|
||||
self.portHandler.is_using = False
|
||||
|
||||
return result
|
||||
|
||||
def writeTxRx(self, sts_id, address, length, data):
|
||||
txpacket = [0] * (length + 7)
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = length + 3
|
||||
txpacket[PKT_INSTRUCTION] = INST_WRITE
|
||||
txpacket[PKT_PARAMETER0] = address
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
|
||||
rxpacket, result, error = self.txRxPacket(txpacket)
|
||||
|
||||
return result, error
|
||||
|
||||
def write1ByteTxOnly(self, sts_id, address, data):
|
||||
data_write = [data]
|
||||
return self.writeTxOnly(sts_id, address, 1, data_write)
|
||||
|
||||
def write1ByteTxRx(self, sts_id, address, data):
|
||||
data_write = [data]
|
||||
return self.writeTxRx(sts_id, address, 1, data_write)
|
||||
|
||||
def write2ByteTxOnly(self, sts_id, address, data):
|
||||
data_write = [self.sts_lobyte(data), self.sts_hibyte(data)]
|
||||
return self.writeTxOnly(sts_id, address, 2, data_write)
|
||||
|
||||
def write2ByteTxRx(self, sts_id, address, data):
|
||||
data_write = [self.sts_lobyte(data), self.sts_hibyte(data)]
|
||||
return self.writeTxRx(sts_id, address, 2, data_write)
|
||||
|
||||
def write4ByteTxOnly(self, sts_id, address, data):
|
||||
data_write = [self.sts_lobyte(self.sts_loword(data)),
|
||||
self.sts_hibyte(self.sts_loword(data)),
|
||||
self.sts_lobyte(self.sts_hiword(data)),
|
||||
self.sts_hibyte(self.sts_hiword(data))]
|
||||
return self.writeTxOnly(sts_id, address, 4, data_write)
|
||||
|
||||
def write4ByteTxRx(self, sts_id, address, data):
|
||||
data_write = [self.sts_lobyte(self.sts_loword(data)),
|
||||
self.sts_hibyte(self.sts_loword(data)),
|
||||
self.sts_lobyte(self.sts_hiword(data)),
|
||||
self.sts_hibyte(self.sts_hiword(data))]
|
||||
return self.writeTxRx(sts_id, address, 4, data_write)
|
||||
|
||||
def regWriteTxOnly(self, sts_id, address, length, data):
|
||||
txpacket = [0] * (length + 7)
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = length + 3
|
||||
txpacket[PKT_INSTRUCTION] = INST_REG_WRITE
|
||||
txpacket[PKT_PARAMETER0] = address
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
|
||||
|
||||
result = self.txPacket(txpacket)
|
||||
self.portHandler.is_using = False
|
||||
|
||||
return result
|
||||
|
||||
def regWriteTxRx(self, sts_id, address, length, data):
|
||||
txpacket = [0] * (length + 7)
|
||||
|
||||
txpacket[PKT_ID] = sts_id
|
||||
txpacket[PKT_LENGTH] = length + 3
|
||||
txpacket[PKT_INSTRUCTION] = INST_REG_WRITE
|
||||
txpacket[PKT_PARAMETER0] = address
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 1: PKT_PARAMETER0 + 1 + length] = data[0: length]
|
||||
|
||||
_, result, error = self.txRxPacket(txpacket)
|
||||
|
||||
return result, error
|
||||
|
||||
def syncReadTx(self, start_address, data_length, param, param_length):
|
||||
txpacket = [0] * (param_length + 8)
|
||||
# 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN CHKSUM
|
||||
|
||||
txpacket[PKT_ID] = BROADCAST_ID
|
||||
txpacket[PKT_LENGTH] = param_length + 4 # 7: INST START_ADDR DATA_LEN CHKSUM
|
||||
txpacket[PKT_INSTRUCTION] = INST_SYNC_READ
|
||||
txpacket[PKT_PARAMETER0 + 0] = start_address
|
||||
txpacket[PKT_PARAMETER0 + 1] = data_length
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length]
|
||||
|
||||
# print(txpacket)
|
||||
result = self.txPacket(txpacket)
|
||||
return result
|
||||
|
||||
def syncReadRx(self, data_length, param_length):
|
||||
wait_length = (6 + data_length) * param_length
|
||||
self.portHandler.setPacketTimeout(wait_length)
|
||||
rxpacket = []
|
||||
rx_length = 0
|
||||
while True:
|
||||
rxpacket.extend(self.portHandler.readPort(wait_length - rx_length))
|
||||
rx_length = len(rxpacket)
|
||||
if rx_length >= wait_length:
|
||||
result = COMM_SUCCESS
|
||||
break
|
||||
else:
|
||||
# check timeout
|
||||
if self.portHandler.isPacketTimeout():
|
||||
if rx_length == 0:
|
||||
result = COMM_RX_TIMEOUT
|
||||
else:
|
||||
result = COMM_RX_CORRUPT
|
||||
break
|
||||
self.portHandler.is_using = False
|
||||
return result, rxpacket
|
||||
|
||||
def syncWriteTxOnly(self, start_address, data_length, param, param_length):
|
||||
txpacket = [0] * (param_length + 8)
|
||||
# 8: HEADER0 HEADER1 ID LEN INST START_ADDR DATA_LEN ... CHKSUM
|
||||
|
||||
txpacket[PKT_ID] = BROADCAST_ID
|
||||
txpacket[PKT_LENGTH] = param_length + 4 # 4: INST START_ADDR DATA_LEN ... CHKSUM
|
||||
txpacket[PKT_INSTRUCTION] = INST_SYNC_WRITE
|
||||
txpacket[PKT_PARAMETER0 + 0] = start_address
|
||||
txpacket[PKT_PARAMETER0 + 1] = data_length
|
||||
|
||||
txpacket[PKT_PARAMETER0 + 2: PKT_PARAMETER0 + 2 + param_length] = param[0: param_length]
|
||||
|
||||
_, result, _ = self.txRxPacket(txpacket)
|
||||
|
||||
return result
|
||||
104
toid_interaction/toid_interaction/mechanism/STservo_sdk/scscl.py
Normal file
104
toid_interaction/toid_interaction/mechanism/STservo_sdk/scscl.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .stservo_def import *
|
||||
from .protocol_packet_handler import *
|
||||
from .group_sync_write import *
|
||||
|
||||
#波特率定义
|
||||
SCSCL_1M = 0
|
||||
SCSCL_0_5M = 1
|
||||
SCSCL_250K = 2
|
||||
SCSCL_128K = 3
|
||||
SCSCL_115200 = 4
|
||||
SCSCL_76800 = 5
|
||||
SCSCL_57600 = 6
|
||||
SCSCL_38400 = 7
|
||||
|
||||
#内存表定义
|
||||
#-------EPROM(只读)--------
|
||||
SCSCL_MODEL_L = 3
|
||||
SCSCL_MODEL_H = 4
|
||||
|
||||
#-------EPROM(读写)--------
|
||||
scs_id = 5
|
||||
SCSCL_BAUD_RATE = 6
|
||||
SCSCL_MIN_ANGLE_LIMIT_L = 9
|
||||
SCSCL_MIN_ANGLE_LIMIT_H = 10
|
||||
SCSCL_MAX_ANGLE_LIMIT_L = 11
|
||||
SCSCL_MAX_ANGLE_LIMIT_H = 12
|
||||
SCSCL_CW_DEAD = 26
|
||||
SCSCL_CCW_DEAD = 27
|
||||
|
||||
#-------SRAM(读写)--------
|
||||
SCSCL_TORQUE_ENABLE = 40
|
||||
SCSCL_GOAL_POSITION_L = 42
|
||||
SCSCL_GOAL_POSITION_H = 43
|
||||
SCSCL_GOAL_TIME_L = 44
|
||||
SCSCL_GOAL_TIME_H = 45
|
||||
SCSCL_GOAL_SPEED_L = 46
|
||||
SCSCL_GOAL_SPEED_H = 47
|
||||
SCSCL_LOCK = 48
|
||||
|
||||
#-------SRAM(只读)--------
|
||||
SCSCL_PRESENT_POSITION_L = 56
|
||||
SCSCL_PRESENT_POSITION_H = 57
|
||||
SCSCL_PRESENT_SPEED_L = 58
|
||||
SCSCL_PRESENT_SPEED_H = 59
|
||||
SCSCL_PRESENT_LOAD_L = 60
|
||||
SCSCL_PRESENT_LOAD_H = 61
|
||||
SCSCL_PRESENT_VOLTAGE = 62
|
||||
SCSCL_PRESENT_TEMPERATURE = 63
|
||||
SCSCL_MOVING = 66
|
||||
SCSCL_PRESENT_CURRENT_L = 69
|
||||
SCSCL_PRESENT_CURRENT_H = 70
|
||||
|
||||
class scscl(protocol_packet_handler):
|
||||
def __init__(self, portHandler):
|
||||
protocol_packet_handler.__init__(self, portHandler, 1)
|
||||
self.groupSyncWrite = GroupSyncWrite(self, SCSCL_GOAL_POSITION_L, 6)
|
||||
|
||||
def WritePos(self, scs_id, position, time, speed):
|
||||
txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
|
||||
return self.writeTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket)
|
||||
|
||||
def ReadPos(self, scs_id):
|
||||
scs_present_position, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L)
|
||||
return scs_present_position, scs_comm_result, scs_error
|
||||
|
||||
def ReadSpeed(self, scs_id):
|
||||
scs_present_speed, scs_comm_result, scs_error = self.read2ByteTxRx(scs_id, SCSCL_PRESENT_SPEED_L)
|
||||
return self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
|
||||
|
||||
def ReadPosSpeed(self, scs_id):
|
||||
scs_present_position_speed, scs_comm_result, scs_error = self.read4ByteTxRx(scs_id, SCSCL_PRESENT_POSITION_L)
|
||||
scs_present_position = self.scs_loword(scs_present_position_speed)
|
||||
scs_present_speed = self.scs_hiword(scs_present_position_speed)
|
||||
return scs_present_position, self.scs_tohost(scs_present_speed, 15), scs_comm_result, scs_error
|
||||
|
||||
def ReadMoving(self, scs_id):
|
||||
moving, scs_comm_result, scs_error = self.read1ByteTxRx(scs_id, SCSCL_MOVING)
|
||||
return moving, scs_comm_result, scs_error
|
||||
|
||||
def SyncWritePos(self, scs_id, position, time, speed):
|
||||
txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
|
||||
return self.groupSyncWrite.addParam(scs_id, txpacket)
|
||||
|
||||
def RegWritePos(self, scs_id, position, time, speed):
|
||||
txpacket = [self.scs_lobyte(position), self.scs_hibyte(position), self.scs_lobyte(time), self.scs_hibyte(time), self.scs_lobyte(speed), self.scs_hibyte(speed)]
|
||||
return self.regWriteTxRx(scs_id, SCSCL_GOAL_POSITION_L, len(txpacket), txpacket)
|
||||
|
||||
def RegAction(self):
|
||||
return self.action(BROADCAST_ID)
|
||||
|
||||
def PWMMode(self, scs_id):
|
||||
txpacket = [0, 0, 0, 0]
|
||||
return self.writeTxRx(scs_id, SCSCL_MIN_ANGLE_LIMIT_L, len(txpacket), txpacket)
|
||||
|
||||
def WritePWM(self, scs_id, time):
|
||||
return self.write2ByteTxRx(scs_id, SCSCL_GOAL_TIME_L, self.scs_toscs(time, 10))
|
||||
|
||||
def LockEprom(self, scs_id):
|
||||
return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 1)
|
||||
|
||||
def unLockEprom(self, scs_id):
|
||||
return self.write1ByteTxRx(scs_id, SCSCL_LOCK, 0)
|
||||
@@ -0,0 +1,7 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='STservo_sdk',
|
||||
version='0.1',
|
||||
packages=find_packages(),
|
||||
)
|
||||
140
toid_interaction/toid_interaction/mechanism/STservo_sdk/sts.py
Normal file
140
toid_interaction/toid_interaction/mechanism/STservo_sdk/sts.py
Normal file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from .stservo_def import *
|
||||
from .protocol_packet_handler import *
|
||||
from .group_sync_read import *
|
||||
from .group_sync_write import *
|
||||
|
||||
#波特率定义
|
||||
STS_1M = 0
|
||||
STS_0_5M = 1
|
||||
STS_250K = 2
|
||||
STS_128K = 3
|
||||
STS_115200 = 4
|
||||
STS_76800 = 5
|
||||
STS_57600 = 6
|
||||
STS_38400 = 7
|
||||
|
||||
#内存表定义
|
||||
#-------EPROM(只读)--------
|
||||
STS_MODEL_L = 3
|
||||
STS_MODEL_H = 4
|
||||
|
||||
#-------EPROM(读写)--------
|
||||
STS_ID = 5
|
||||
STS_BAUD_RATE = 6
|
||||
STS_MIN_ANGLE_LIMIT_L = 9
|
||||
STS_MIN_ANGLE_LIMIT_H = 10
|
||||
STS_MAX_ANGLE_LIMIT_L = 11
|
||||
STS_MAX_ANGLE_LIMIT_H = 12
|
||||
STS_CW_DEAD = 26
|
||||
STS_CCW_DEAD = 27
|
||||
STS_OFS_L = 31
|
||||
STS_OFS_H = 32
|
||||
STS_MODE = 33
|
||||
|
||||
#-------SRAM(读写)--------
|
||||
MAX_POSITION_L = 42
|
||||
STS_GOAL_POSITION_H = 43
|
||||
STS_GOAL_TIME_L = 44
|
||||
STS_GOAL_TIME_H = 45
|
||||
STS_LOAD_LIMIT = 36
|
||||
STS_TORQUE_ENABLE = 40
|
||||
STS_ACC = 41
|
||||
STS_GOAL_SPEED_L = 46
|
||||
STS_GOAL_SPEED_H = 47
|
||||
STS_MAX_LOAD = 0x30
|
||||
STS_LOCK = 55
|
||||
|
||||
#-------SRAM(只读)--------
|
||||
STS_PRESENT_POSITION_L = 56
|
||||
STS_PRESENT_POSITION_H = 57
|
||||
STS_PRESENT_SPEED_L = 58
|
||||
STS_PRESENT_SPEED_H = 59
|
||||
STS_PRESENT_LOAD_L = 60
|
||||
STS_PRESENT_LOAD_H = 61
|
||||
STS_PRESENT_VOLTAGE = 62
|
||||
STS_PRESENT_TEMPERATURE = 63
|
||||
STS_MOVING = 66
|
||||
STS_PRESENT_CURRENT_L = 69
|
||||
STS_PRESENT_CURRENT_H = 70
|
||||
|
||||
class sts(protocol_packet_handler):
|
||||
def __init__(self, portHandler):
|
||||
protocol_packet_handler.__init__(self, portHandler, 0)
|
||||
self.groupSyncWrite = GroupSyncWrite(self, 40, 7)
|
||||
|
||||
def WritePosEx(self, sts_id, position, speed, acc):
|
||||
txpacket = [acc, self.sts_lobyte(position), self.sts_hibyte(position), 0, 0, self.sts_lobyte(speed), self.sts_hibyte(speed)]
|
||||
return self.writeTxRx(sts_id, STS_ACC, len(txpacket), txpacket)
|
||||
|
||||
def ReadPos(self, sts_id):
|
||||
sts_present_position, sts_comm_result, sts_error = self.read2ByteTxRx(sts_id, 60)
|
||||
return self.sts_tohost(sts_present_position, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadLoad(self, sts_id):
|
||||
sts_present_load, sts_comm_result,sts_error = self.read2ByteTxRx(sts_id, STS_PRESENT_LOAD_L) # 60
|
||||
return self.sts_tohost(sts_present_load, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadMaxLoad(self, sts_id):
|
||||
sts_max_load, sts_comm_result,sts_error = self.read2ByteTxRx(sts_id, STS_LOAD_LIMIT) # 0x36
|
||||
return sts_max_load, sts_comm_result, sts_error
|
||||
|
||||
def ReadSpeed(self, sts_id):
|
||||
sts_present_speed, sts_comm_result, sts_error = self.read2ByteTxRx(sts_id, STS_PRESENT_SPEED_L)
|
||||
return self.sts_tohost(sts_present_speed, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadPosSpeed(self, sts_id):
|
||||
sts_present_position_speed, sts_comm_result, sts_error = self.read4ByteTxRx(sts_id, STS_PRESENT_POSITION_L)
|
||||
sts_present_position = self.sts_loword(sts_present_position_speed)
|
||||
sts_present_speed = self.sts_hiword(sts_present_position_speed)
|
||||
return self.sts_tohost(sts_present_position, 15), self.sts_tohost(sts_present_speed, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadPosLoad(self, sts_id):
|
||||
sts_present_position_speed, sts_comm_result, sts_error = self.read4ByteTxRx(sts_id, 60)
|
||||
sts_present_position = self.sts_loword(sts_present_position_speed)
|
||||
sts_present_speed = self.sts_hiword(sts_present_position_speed)
|
||||
return self.sts_tohost(sts_present_position, 15), self.sts_tohost(sts_present_speed, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadPosLoad1(self, sts_id):
|
||||
sts_present_position_speed, sts_comm_result, sts_error = self.read4ByteTxRx(sts_id, 61)
|
||||
sts_present_position = self.sts_loword(sts_present_position_speed)
|
||||
sts_present_speed = self.sts_hiword(sts_present_position_speed)
|
||||
return self.sts_tohost(sts_present_position, 15), self.sts_tohost(sts_present_speed, 15), sts_comm_result, sts_error
|
||||
|
||||
def ReadMoving(self, sts_id):
|
||||
moving, sts_comm_result, sts_error = self.read1ByteTxRx(sts_id, STS_MOVING)
|
||||
return moving, sts_comm_result, sts_error
|
||||
|
||||
def MaxLoad(self, sts_id):
|
||||
max_load, sts_comm_result, sts_error = self.read1ByteTxRx(sts_id, STS_LOAD_LIMIT)
|
||||
return max_load, sts_comm_result, sts_error
|
||||
|
||||
def SyncWritePosEx(self, sts_id, position, speed, acc):
|
||||
txpacket = [acc, self.sts_lobyte(position), self.sts_hibyte(position), 0, 0, self.sts_lobyte(speed), self.sts_hibyte(speed)]
|
||||
return self.groupSyncWrite.addParam(sts_id, txpacket)
|
||||
|
||||
def RegWritePosEx(self, sts_id, position, speed, acc):
|
||||
txpacket = [acc, self.sts_lobyte(position), self.sts_hibyte(position), 0, 0, self.sts_lobyte(speed), self.sts_hibyte(speed)]
|
||||
return self.regWriteTxRx(sts_id, STS_ACC, len(txpacket), txpacket)
|
||||
|
||||
def RegAction(self):
|
||||
return self.action(BROADCAST_ID)
|
||||
|
||||
def WheelMode(self, sts_id):
|
||||
return self.write1ByteTxRx(sts_id, STS_MODE, 1)
|
||||
|
||||
def SetMaxLoad(self, sts_id, load):
|
||||
return self.write2ByteTxRx(sts_id, STS_MAX_LOAD, int(load*10))
|
||||
|
||||
def WriteSpec(self, sts_id, speed, acc):
|
||||
speed = self.sts_toscs(speed, 15)
|
||||
txpacket = [acc, 0, 0, 0, 0, self.sts_lobyte(speed), self.sts_hibyte(speed)]
|
||||
return self.writeTxRx(sts_id, STS_ACC, len(txpacket), txpacket)
|
||||
|
||||
def LockEprom(self, sts_id):
|
||||
return self.write1ByteTxRx(sts_id, STS_LOCK, 1)
|
||||
|
||||
def unLockEprom(self, sts_id):
|
||||
return self.write1ByteTxRx(sts_id, STS_LOCK, 0)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
BROADCAST_ID = 0xFE # 254
|
||||
MAX_ID = 0xFC # 252
|
||||
STS_END = 0
|
||||
|
||||
# Instruction for STS Protocol
|
||||
INST_PING = 1
|
||||
INST_READ = 2
|
||||
INST_WRITE = 3
|
||||
INST_REG_WRITE = 4
|
||||
INST_ACTION = 5
|
||||
INST_SYNC_WRITE = 131 # 0x83
|
||||
INST_SYNC_READ = 130 # 0x82
|
||||
|
||||
# Communication Result
|
||||
COMM_SUCCESS = 0 # tx or rx packet communication success
|
||||
COMM_PORT_BUSY = -1 # Port is busy (in use)
|
||||
COMM_TX_FAIL = -2 # Failed transmit instruction packet
|
||||
COMM_RX_FAIL = -3 # Failed get status packet
|
||||
COMM_TX_ERROR = -4 # Incorrect instruction packet
|
||||
COMM_RX_WAITING = -5 # Now recieving status packet
|
||||
COMM_RX_TIMEOUT = -6 # There is no status packet
|
||||
COMM_RX_CORRUPT = -7 # Incorrect status packet
|
||||
COMM_NOT_AVAILABLE = -9 #
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
67
toid_interaction/toid_interaction/mechanism/sekvenca_2026.py
Normal file
67
toid_interaction/toid_interaction/mechanism/sekvenca_2026.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# u ovom fajlu sam napisala celu sekvencu koju obuhvata hvatanje zirova podizanje, okretanje, spustanje i odlaganje
|
||||
# dole cu napisaci koje funkicje su koja sekvenca ono sto smo pricali , nisam htela da pravim jos jedan fajl sa sekvencama da
|
||||
# ne bude da ima opet previse fajlova
|
||||
# sekvecncu 4 nije jos zavrsila poslacu ti to naknadno
|
||||
from .zidovi_load import ZidoviAction
|
||||
from .zupcanik import ZupcanikAction
|
||||
import time
|
||||
import serial
|
||||
import serial.tools.list_ports as list_ports
|
||||
|
||||
SERIAL_ID = "50443405C8C3B21C"
|
||||
|
||||
|
||||
def okreni(i):
|
||||
for port_info in list_ports.comports():
|
||||
if port_info.serial_number == SERIAL_ID:
|
||||
break
|
||||
|
||||
ser = serial.Serial(port_info.device, 115200, timeout=1)
|
||||
ser.write(str(i).encode())
|
||||
|
||||
|
||||
def okreni_niz(broj):
|
||||
"""
|
||||
Funkcija koja prima string od 4 karaktera (0 ili 1)
|
||||
"""
|
||||
if len(broj) != 4:
|
||||
raise ValueError("Binarni niz mora imati tačno 4 karaktera")
|
||||
|
||||
okreni(6)
|
||||
for i, char in enumerate(broj):
|
||||
if char == "1":
|
||||
okreni(i + 1)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
zidovi = ZidoviAction('/dev/ttyACM1')
|
||||
zupcanik = ZupcanikAction('/dev/ttyACM1')
|
||||
|
||||
|
||||
# sekvenca 1
|
||||
okreni(5)
|
||||
zupcanik.zupcanik(1, -1010, 25)
|
||||
|
||||
# sekvenca 2
|
||||
zidovi.beli_zid(1)
|
||||
zidovi.plavi_zid(1)
|
||||
|
||||
okreni_niz("1010")
|
||||
|
||||
zidovi.plavi_zid(0, TargetPos=150)
|
||||
zidovi.beli_zid(0, TargetPos=450)
|
||||
|
||||
|
||||
# sekvenca 3
|
||||
|
||||
zupcanik.zupcanik(1, 1010, 25)
|
||||
|
||||
zidovi.plavi_zid(0, TargetPos=150)
|
||||
zidovi.beli_zid(0, TargetPos=150)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
366
toid_interaction/toid_interaction/mechanism/zidovi_load.py
Normal file
366
toid_interaction/toid_interaction/mechanism/zidovi_load.py
Normal file
@@ -0,0 +1,366 @@
|
||||
from .STservo_sdk import PortHandler, sts, COMM_SUCCESS, STS_ID
|
||||
# da li ovo dole treba da importujem ako je nalazi u STservo_sdk?
|
||||
# from stservo_def import COMM_SUCCESS
|
||||
|
||||
# Default settings
|
||||
|
||||
|
||||
class ZidoviAction:
|
||||
BAUDRATE : int
|
||||
DEVICENAME : str
|
||||
STS_MOVING_ACC: int
|
||||
def __init__(
|
||||
self,
|
||||
devicename, # Check which port is being used on your controller
|
||||
baudrate=1000000, # STServo default baudrate
|
||||
sts_moving_acc=0, # STServo moving acceleration
|
||||
):
|
||||
self.BAUDRATE = baudrate
|
||||
self.DEVICENAME = devicename
|
||||
self.STS_MOVING_ACC = sts_moving_acc
|
||||
|
||||
|
||||
def plavi_zid(self, smer, brzina=1500, opterecenje_threshold=75, TargetPos=300):
|
||||
# TargetPos = 300 # Target position in degrees
|
||||
TargetPos = TargetPos * 4096 / 360 # Convert to motor ticks
|
||||
if smer == 1:
|
||||
Speed_ID2 = brzina # Speed for motor ID 2
|
||||
Speed_ID4 = -brzina # Speed for motor ID 4 (opposite sign)
|
||||
else:
|
||||
Speed_ID2 = -brzina # Speed for motor ID 2
|
||||
Speed_ID4 = brzina # Speed for motor ID 4 (opposite sign)
|
||||
|
||||
# Initialize PortHandler instance
|
||||
portHandler = PortHandler(self.DEVICENAME)
|
||||
|
||||
# Initialize PacketHandler instance
|
||||
packetHandler = sts(portHandler)
|
||||
|
||||
# Open port
|
||||
if portHandler.openPort():
|
||||
print("Succeeded to open the port")
|
||||
else:
|
||||
print("Failed to open the port")
|
||||
print("Press any key to terminate...")
|
||||
|
||||
quit()
|
||||
|
||||
# Set port baudrate
|
||||
if portHandler.setBaudRate(self.BAUDRATE):
|
||||
print("Succeeded to change the baudrate")
|
||||
else:
|
||||
print("Failed to change the baudrate")
|
||||
print("Press any key to terminate...")
|
||||
|
||||
quit()
|
||||
|
||||
# Set motors to Wheel Mode
|
||||
for motor_id in [2, 4]:
|
||||
sts_comm_result, sts_error = packetHandler.WheelMode(motor_id)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print(
|
||||
"[ID:%01d] %s"
|
||||
% (motor_id, packetHandler.getTxRxResult(sts_comm_result))
|
||||
)
|
||||
elif sts_error != 0:
|
||||
print(
|
||||
"[ID:%01d] %s"
|
||||
% (motor_id, packetHandler.getRxPacketError(sts_error))
|
||||
)
|
||||
|
||||
# Read initial positions for both motors
|
||||
sts_present_position_ID2, sts_present_speed_ID2, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(2)
|
||||
)
|
||||
sts_present_position_ID4, sts_present_speed_ID4, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(4)
|
||||
)
|
||||
|
||||
print("Initial positions:")
|
||||
print(
|
||||
"[ID:002] PresPos:%d PresSpd:%d"
|
||||
% (sts_present_position_ID2, sts_present_speed_ID2)
|
||||
)
|
||||
print(
|
||||
"[ID:004] PresPos:%d PresSpd:%d"
|
||||
% (sts_present_position_ID4, sts_present_speed_ID4)
|
||||
)
|
||||
|
||||
# Initialize variables for tracking movement
|
||||
TrenutnaPos_ID2 = sts_present_position_ID2
|
||||
ProslaPos_ID2 = sts_present_position_ID2
|
||||
PredjeniPut_ID2 = 0
|
||||
|
||||
TrenutnaPos_ID4 = sts_present_position_ID4
|
||||
ProslaPos_ID4 = sts_present_position_ID4
|
||||
PredjeniPut_ID4 = 0
|
||||
packetHandler.SetMaxLoad(STS_ID, 80)
|
||||
|
||||
while True:
|
||||
# Write goal position, speed, and acceleration for both motors
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(
|
||||
2, Speed_ID2, self.STS_MOVING_ACC
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:002] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:002] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(
|
||||
4, Speed_ID4, self.STS_MOVING_ACC
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:004] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:004] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
# Update positions for both motors
|
||||
ProslaPos_ID2 = TrenutnaPos_ID2
|
||||
ProslaPos_ID4 = TrenutnaPos_ID4
|
||||
|
||||
(
|
||||
sts_present_position_ID2,
|
||||
sts_present_speed_ID2,
|
||||
sts_comm_result,
|
||||
sts_error,
|
||||
) = packetHandler.ReadPosSpeed(2)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:002] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:002] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
(
|
||||
sts_present_position_ID4,
|
||||
sts_present_speed_ID4,
|
||||
sts_comm_result,
|
||||
sts_error,
|
||||
) = packetHandler.ReadPosSpeed(4)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:004] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:004] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
sts_present_load2, sts_comm_result, sts_error = packetHandler.ReadLoad(2)
|
||||
sts_present_load4, sts_comm_result, sts_error = packetHandler.ReadLoad(4)
|
||||
opterecenje2 = (sts_present_load2 & ((1 << 10) - 1)) * 0.1
|
||||
opterecenje4 = (sts_present_load4 & ((1 << 10) - 1)) * 0.1
|
||||
print("Current positions:")
|
||||
print(
|
||||
"[ID:002] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID2, sts_present_speed_ID2, opterecenje2)
|
||||
)
|
||||
print(
|
||||
"[ID:004] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID4, sts_present_speed_ID4, opterecenje4)
|
||||
)
|
||||
|
||||
TrenutnaPos_ID2 = sts_present_position_ID2
|
||||
TrenutnaPos_ID4 = sts_present_position_ID4
|
||||
|
||||
# Check if the positions have changed
|
||||
if (
|
||||
opterecenje2 > opterecenje_threshold
|
||||
or opterecenje4 > opterecenje_threshold
|
||||
):
|
||||
print(
|
||||
"High load detected: [ID:002] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID2, sts_present_speed_ID2, opterecenje2)
|
||||
)
|
||||
print(
|
||||
"High load detected: [ID:004] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID4, sts_present_speed_ID4, opterecenje4)
|
||||
)
|
||||
packetHandler.WriteSpec(2, 0, 0) # Stop motor ID 2
|
||||
packetHandler.WriteSpec(4, 0, 0) # Stop motor ID 4
|
||||
break
|
||||
if (
|
||||
abs(TrenutnaPos_ID2 - ProslaPos_ID2) > 3000
|
||||
or abs(TrenutnaPos_ID4 - ProslaPos_ID4) > 3000
|
||||
):
|
||||
PredjeniPut_ID2 = PredjeniPut_ID2
|
||||
PredjeniPut_ID4 = PredjeniPut_ID4
|
||||
else:
|
||||
PredjeniPut_ID2 += abs(TrenutnaPos_ID2 - ProslaPos_ID2)
|
||||
PredjeniPut_ID4 += abs(TrenutnaPos_ID4 - ProslaPos_ID4)
|
||||
|
||||
print("PredjeniPut ID2:%d deg " % (PredjeniPut_ID2 * 360 / 4096))
|
||||
print("PredjeniPut ID4:%d deg " % (PredjeniPut_ID4 * 360 / 4096))
|
||||
|
||||
# Stop if both motors reach their target positions
|
||||
if PredjeniPut_ID2 >= TargetPos and PredjeniPut_ID4 >= TargetPos + 10:
|
||||
print("Target positions reached.")
|
||||
packetHandler.WriteSpec(2, 0, 0) # Stop motor ID 2
|
||||
packetHandler.WriteSpec(4, 0, 0) # Stop motor ID 4
|
||||
break
|
||||
|
||||
# Close port
|
||||
portHandler.closePort()
|
||||
|
||||
def beli_zid(self, smer, brzina=1500, opterecenje_threshold=75, TargetPos=600):
|
||||
# TargetPos = 600 # Target position in degrees
|
||||
TargetPos = TargetPos * 4096 / 360 # Convert to motor ticks
|
||||
if smer == 1:
|
||||
Speed_ID3 = -brzina # Speed for motor ID 3
|
||||
Speed_ID5 = brzina # Speed for motor ID 5 (opposite sign)
|
||||
|
||||
else:
|
||||
Speed_ID3 = brzina # Speed for motor ID 3
|
||||
Speed_ID5 = -brzina # Speed for motor ID 5 (opposite sign)
|
||||
|
||||
# Initialize PortHandler instance
|
||||
portHandler = PortHandler(self.DEVICENAME)
|
||||
|
||||
# Initialize PacketHandler instance
|
||||
packetHandler = sts(portHandler)
|
||||
|
||||
# Open port
|
||||
if portHandler.openPort():
|
||||
print("Succeeded to open the port")
|
||||
else:
|
||||
print("Failed to open the port")
|
||||
print("Press any key to terminate...")
|
||||
|
||||
quit()
|
||||
|
||||
# Set port baudrate
|
||||
if portHandler.setBaudRate(self.BAUDRATE):
|
||||
print("Succeeded to change the baudrate")
|
||||
else:
|
||||
print("Failed to change the baudrate")
|
||||
print("Press any key to terminate...")
|
||||
|
||||
quit()
|
||||
|
||||
# Set motors to Wheel Mode
|
||||
for motor_id in [3, 5]:
|
||||
sts_comm_result, sts_error = packetHandler.WheelMode(motor_id)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print(
|
||||
"[ID:%01d] %s"
|
||||
% (motor_id, packetHandler.getTxRxResult(sts_comm_result))
|
||||
)
|
||||
elif sts_error != 0:
|
||||
print(
|
||||
"[ID:%01d] %s"
|
||||
% (motor_id, packetHandler.getRxPacketError(sts_error))
|
||||
)
|
||||
|
||||
# Read initial positions for both motors
|
||||
sts_present_position_ID3, sts_present_speed_ID3, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(3)
|
||||
)
|
||||
sts_present_position_ID5, sts_present_speed_ID5, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(5)
|
||||
)
|
||||
|
||||
print("Initial positions:")
|
||||
# print("[ID:003] PresPos:%d PresSpd:%d" % (sts_present_position_ID3, sts_present_speed_ID3))
|
||||
# print("[ID:005] PresPos:%d PresSpd:%d" % (sts_present_position_ID5, sts_present_speed_ID5))
|
||||
|
||||
# Initialize variables for tracking movement
|
||||
TrenutnaPos_ID3 = sts_present_position_ID3
|
||||
ProslaPos_ID3 = sts_present_position_ID3
|
||||
PredjeniPut_ID3 = 0
|
||||
|
||||
TrenutnaPos_ID5 = sts_present_position_ID5
|
||||
ProslaPos_ID5 = sts_present_position_ID5
|
||||
PredjeniPut_ID5 = 0
|
||||
packetHandler.SetMaxLoad(STS_ID, 80)
|
||||
|
||||
while True:
|
||||
# Write goal position, speed, and acceleration for both motors
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(
|
||||
3, Speed_ID3, self.STS_MOVING_ACC
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:003] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:003] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(
|
||||
5, Speed_ID5, self.STS_MOVING_ACC
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:005] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:005] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
# Update positions for both motors
|
||||
ProslaPos_ID3 = TrenutnaPos_ID3
|
||||
ProslaPos_ID5 = TrenutnaPos_ID5
|
||||
|
||||
(
|
||||
sts_present_position_ID3,
|
||||
sts_present_speed_ID3,
|
||||
sts_comm_result,
|
||||
sts_error,
|
||||
) = packetHandler.ReadPosSpeed(3)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:003] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:003] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
(
|
||||
sts_present_position_ID5,
|
||||
sts_present_speed_ID5,
|
||||
sts_comm_result,
|
||||
sts_error,
|
||||
) = packetHandler.ReadPosSpeed(5)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("[ID:005] %s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("[ID:005] %s" % packetHandler.getRxPacketError(sts_error))
|
||||
sts_present_load3, sts_comm_result, sts_error = packetHandler.ReadLoad(3)
|
||||
sts_present_load5, sts_comm_result, sts_error = packetHandler.ReadLoad(5)
|
||||
opterecenje3 = (sts_present_load3 & ((1 << 10) - 1)) * 0.1
|
||||
opterecenje5 = (sts_present_load5 & ((1 << 10) - 1)) * 0.1
|
||||
print("Current positions:")
|
||||
print(
|
||||
"[ID:003] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID3, sts_present_speed_ID3, opterecenje3)
|
||||
)
|
||||
print(
|
||||
"[ID:005] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID5, sts_present_speed_ID5, opterecenje5)
|
||||
)
|
||||
|
||||
TrenutnaPos_ID3 = sts_present_position_ID3
|
||||
TrenutnaPos_ID5 = sts_present_position_ID5
|
||||
|
||||
# Check if the positions have changed
|
||||
if (
|
||||
opterecenje3 > opterecenje_threshold
|
||||
or opterecenje5 > opterecenje_threshold
|
||||
):
|
||||
print(
|
||||
"High load detected: [ID:003] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID3, sts_present_speed_ID3, opterecenje3)
|
||||
)
|
||||
print(
|
||||
"High load detected: [ID:005] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (sts_present_position_ID5, sts_present_speed_ID5, opterecenje5)
|
||||
)
|
||||
packetHandler.WriteSpec(3, 0, 0) # Stop motor ID 3
|
||||
packetHandler.WriteSpec(5, 0, 0) # Stop motor ID 5
|
||||
break
|
||||
if (
|
||||
abs(TrenutnaPos_ID3 - ProslaPos_ID3) > 3000
|
||||
or abs(TrenutnaPos_ID5 - ProslaPos_ID5) > 3000
|
||||
):
|
||||
PredjeniPut_ID3 = PredjeniPut_ID3
|
||||
PredjeniPut_ID5 = PredjeniPut_ID5
|
||||
else:
|
||||
PredjeniPut_ID3 += abs(TrenutnaPos_ID3 - ProslaPos_ID3)
|
||||
PredjeniPut_ID5 += abs(TrenutnaPos_ID5 - ProslaPos_ID5)
|
||||
|
||||
print("PredjeniPut ID3:%d deg " % (PredjeniPut_ID3 * 360 / 4096))
|
||||
print("PredjeniPut ID5:%d deg " % (PredjeniPut_ID5 * 360 / 4096))
|
||||
|
||||
# Stop if both motors reach their target positions
|
||||
if PredjeniPut_ID3 >= TargetPos and PredjeniPut_ID5 >= TargetPos + 10:
|
||||
print("Target positions reached.")
|
||||
packetHandler.WriteSpec(3, 0, 0) # Stop motor ID 3
|
||||
packetHandler.WriteSpec(5, 0, 0) # Stop motor ID 5
|
||||
break
|
||||
|
||||
# Close port
|
||||
portHandler.closePort()
|
||||
130
toid_interaction/toid_interaction/mechanism/zupcanik.py
Normal file
130
toid_interaction/toid_interaction/mechanism/zupcanik.py
Normal file
@@ -0,0 +1,130 @@
|
||||
from .STservo_sdk import PortHandler, sts, COMM_SUCCESS
|
||||
|
||||
class ZupcanikAction:
|
||||
BAUDRATE: int
|
||||
DEVICENAME: str
|
||||
STS_MOVING_ACC: int
|
||||
|
||||
def __init__(self, devicename, baudrate=1000000, sts_moving_acc=50):
|
||||
self.BAUDRATE = baudrate
|
||||
self.DEVICENAME = devicename
|
||||
self.STS_MOVING_ACC = sts_moving_acc
|
||||
|
||||
def zupcanik(self, STS_ID, STS_MOVING_SPEED, TargetPos):
|
||||
|
||||
# Initialize PortHandler instance
|
||||
portHandler = PortHandler(self.DEVICENAME)
|
||||
|
||||
# Initialize PacketHandler instance
|
||||
packetHandler = sts(portHandler)
|
||||
|
||||
# Open port
|
||||
if not portHandler.openPort():
|
||||
print("Failed to open the port")
|
||||
return
|
||||
|
||||
# Set port baudrate
|
||||
if not portHandler.setBaudRate(self.BAUDRATE):
|
||||
print("Failed to change the baudrate")
|
||||
return
|
||||
|
||||
sts_comm_result, sts_error = packetHandler.WheelMode(STS_ID)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
return
|
||||
elif sts_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(sts_error))
|
||||
return
|
||||
# Read STServo present position
|
||||
sts_present_position, sts_present_speed, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(STS_ID)
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print(packetHandler.getTxRxResult(sts_comm_result))
|
||||
else:
|
||||
print(
|
||||
"[ID:%03d] PresPos:%d PresSpd:%d"
|
||||
% (STS_ID, sts_present_position, sts_present_speed)
|
||||
)
|
||||
if sts_error != 0:
|
||||
print(packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
TargetPos = TargetPos * 4096 / 360 # Convert to motor ticks
|
||||
sts_present_position, sts_present_speed, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(STS_ID)
|
||||
)
|
||||
|
||||
print(
|
||||
"Initial position: [ID:%03d] PresPos:%d PresSpd:%d"
|
||||
% (STS_ID, sts_present_position, sts_present_speed)
|
||||
)
|
||||
|
||||
TrenutnaPos = sts_present_position
|
||||
ProslaPos = sts_present_position
|
||||
PredjeniPut = TrenutnaPos - ProslaPos
|
||||
opterecenje = 0
|
||||
packetHandler.SetMaxLoad(STS_ID, 80)
|
||||
|
||||
while True:
|
||||
# Write STServo goal position/moving speed/moving acc
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(
|
||||
STS_ID, STS_MOVING_SPEED, self.STS_MOVING_ACC
|
||||
)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(sts_error))
|
||||
|
||||
ProslaPos = sts_present_position
|
||||
sts_present_position, sts_present_speed, sts_comm_result, sts_error = (
|
||||
packetHandler.ReadPosSpeed(STS_ID)
|
||||
)
|
||||
sts_present_load, sts_comm_result, sts_error = packetHandler.ReadLoad(
|
||||
STS_ID
|
||||
)
|
||||
sts_max_load, sts_comm_result, sts_error = packetHandler.MaxLoad(STS_ID)
|
||||
opterecenje = (sts_present_load & ((1 << 10) - 1)) * 0.1
|
||||
max_opterecenje = sts_max_load & 255
|
||||
print(
|
||||
"Current position: [ID:%03d] PresPos:%d PresSpd:%d Load:%d Max:%d"
|
||||
% (
|
||||
STS_ID,
|
||||
sts_present_position,
|
||||
sts_present_speed,
|
||||
opterecenje,
|
||||
max_opterecenje,
|
||||
)
|
||||
)
|
||||
|
||||
if opterecenje > 75:
|
||||
print(
|
||||
"High load detected: [ID:%03d] PresPos:%d PresSpd:%d Load:%d"
|
||||
% (STS_ID, sts_present_position, sts_present_speed, opterecenje)
|
||||
)
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(STS_ID, 0, 0)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(sts_error))
|
||||
break
|
||||
TrenutnaPos = sts_present_position
|
||||
if abs(TrenutnaPos - ProslaPos) > 3000:
|
||||
PredjeniPut = PredjeniPut
|
||||
else:
|
||||
PredjeniPut = PredjeniPut + abs(TrenutnaPos - ProslaPos)
|
||||
|
||||
print("Distance traveled: %d deg " % (PredjeniPut * 360 / 4096))
|
||||
if PredjeniPut >= TargetPos:
|
||||
print(
|
||||
"Target position reached: [ID:%03d] PresPos:%d PresSpd:%d"
|
||||
% (STS_ID, sts_present_position, sts_present_speed)
|
||||
)
|
||||
sts_comm_result, sts_error = packetHandler.WriteSpec(STS_ID, 0, 0)
|
||||
if sts_comm_result != COMM_SUCCESS:
|
||||
print("%s" % packetHandler.getTxRxResult(sts_comm_result))
|
||||
if sts_error != 0:
|
||||
print("%s" % packetHandler.getRxPacketError(sts_error))
|
||||
break
|
||||
|
||||
# Close port
|
||||
portHandler.closePort()
|
||||
@@ -19,7 +19,7 @@
|
||||
<depend>tf2_geometry_msgs</depend>
|
||||
<depend>toid_msgs</depend>
|
||||
<depend>visualization_msgs</depend>
|
||||
<depend>rplidar</depend>
|
||||
<depend>rplidar_ros</depend>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
|
||||
"msg/ActiveElements.msg"
|
||||
"msg/Rival.msg"
|
||||
"srv/SendDouble.srv"
|
||||
"srv/SendString.srv"
|
||||
"action/SimpleMoveCoords.action"
|
||||
"action/SimpleRotate.action"
|
||||
"action/SimpleTranslateX.action"
|
||||
|
||||
2
toid_msgs/srv/SendString.srv
Normal file
2
toid_msgs/srv/SendString.srv
Normal file
@@ -0,0 +1,2 @@
|
||||
string text
|
||||
---
|
||||
Reference in New Issue
Block a user