Skip to content

Commit

Permalink
Add scripting feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mojocorp committed Nov 7, 2020
1 parent 0b129b1 commit 7bc331b
Show file tree
Hide file tree
Showing 12 changed files with 933 additions and 175 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ execute_process(
)
message(STATUS "VERSION: ${MAESTRO_VERSION}")

add_subdirectory(libmaestro)
add_subdirectory(src)

if(PYTHON_BINDING)
add_subdirectory(python)
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ The supported devices are:

### C++

#include <libmaestro.h>
#include <maestro/Device.h>

std::vector<MaestroDevice> devices = MaestroDevice::getConnectedDevices();
devices[0].setAcceleration(0, 4); // set servo 0 acceleration to 4
devices[0].setTarget(0, 6000); // set servo to move to center position
devices[0].setSpeed(1, 10); // set servo 1 speed to 10
std::vector<Maestro::Device> devices = Maestro::Device::getConnectedDevices();

devices[0].setAcceleration(0, 4); // set servo 0 acceleration to 4
devices[0].setTarget(0, 6000); // set servo to move to center position
devices[0].setSpeed(1, 10); // set servo 1 speed to 10

### Python

Expand All @@ -62,3 +62,11 @@ The supported devices are:
device.setAcceleration(0, 4) # set servo 0 acceleration to 4
device.setTarget(0, 6000) # set servo to move to center position
device.setSpeed(1, 10) # set servo 1 speed to 10

# compile and upload a script
with open('blink.txt', 'r') as content_file:
script = content_file.read()

program = maestro.Program(script=script, isMiniMaestro=False)

device.writeScript(program.getByteList())
17 changes: 0 additions & 17 deletions libmaestro/CMakeLists.txt

This file was deleted.

149 changes: 79 additions & 70 deletions python/maestro.cpp
Original file line number Diff line number Diff line change
@@ -1,94 +1,103 @@
#include <libmaestro.h>
#include <maestro/Device.h>
#include <maestro/Program.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;

using namespace Maestro;

// clang-format off
PYBIND11_MODULE(maestro, m)
{
m.attr("__version__") = "1.0.0";
m.def("getConnectedDevices", &MaestroDevice::getConnectedDevices);
m.attr("__version__") = "0.1.0";
m.def("getConnectedDevices", &Device::getConnectedDevices);

py::class_<MaestroDevice> device(m, "Device");
py::class_<Device> device(m, "Device");

py::enum_<MaestroDevice::SerialMode>(device, "SerialMode")
.value("SERIAL_MODE_USB_DUAL_PORT", MaestroDevice::SerialMode::SERIAL_MODE_USB_DUAL_PORT)
.value("SERIAL_MODE_USB_CHAINED", MaestroDevice::SerialMode::SERIAL_MODE_USB_CHAINED)
.value("SERIAL_MODE_UART_DETECT_BAUD_RATE", MaestroDevice::SerialMode::SERIAL_MODE_UART_DETECT_BAUD_RATE)
.value("SERIAL_MODE_UART_FIXED_BAUD_RATE", MaestroDevice::SerialMode::SERIAL_MODE_UART_FIXED_BAUD_RATE)
py::enum_<Device::SerialMode>(device, "SerialMode")
.value("SERIAL_MODE_USB_DUAL_PORT", Device::SerialMode::SERIAL_MODE_USB_DUAL_PORT)
.value("SERIAL_MODE_USB_CHAINED", Device::SerialMode::SERIAL_MODE_USB_CHAINED)
.value("SERIAL_MODE_UART_DETECT_BAUD_RATE", Device::SerialMode::SERIAL_MODE_UART_DETECT_BAUD_RATE)
.value("SERIAL_MODE_UART_FIXED_BAUD_RATE", Device::SerialMode::SERIAL_MODE_UART_FIXED_BAUD_RATE)
.export_values();

py::class_<MaestroDevice::DeviceSettings>(device, "DeviceSettings")
.def_readwrite("firmwareVersionMinor", &MaestroDevice::DeviceSettings::firmwareVersionMinor)
.def_readwrite("firmwareVersionMajor", &MaestroDevice::DeviceSettings::firmwareVersionMajor)
.def_readwrite("servosAvailable", &MaestroDevice::DeviceSettings::servosAvailable)
.def_readwrite("servoPeriod", &MaestroDevice::DeviceSettings::servoPeriod)
.def_readwrite("miniMaestroServoPeriod", &MaestroDevice::DeviceSettings::miniMaestroServoPeriod)
.def_readwrite("servoMultiplier", &MaestroDevice::DeviceSettings::servoMultiplier)
.def_readwrite("fixedBaudRate", &MaestroDevice::DeviceSettings::fixedBaudRate)
.def_readwrite("enableCrc", &MaestroDevice::DeviceSettings::enableCrc)
.def_readwrite("neverSuspend", &MaestroDevice::DeviceSettings::neverSuspend)
.def_readwrite("serialDeviceNumber", &MaestroDevice::DeviceSettings::serialDeviceNumber)
.def_readwrite("miniSscOffset", &MaestroDevice::DeviceSettings::miniSscOffset)
.def_readwrite("serialTimeout", &MaestroDevice::DeviceSettings::serialTimeout)
.def_readwrite("scriptDone", &MaestroDevice::DeviceSettings::scriptDone)
.def_readwrite("enablePullups", &MaestroDevice::DeviceSettings::enablePullups)
py::class_<Device::DeviceSettings>(device, "DeviceSettings")
.def_readwrite("firmwareVersionMinor", &Device::DeviceSettings::firmwareVersionMinor)
.def_readwrite("firmwareVersionMajor", &Device::DeviceSettings::firmwareVersionMajor)
.def_readwrite("servosAvailable", &Device::DeviceSettings::servosAvailable)
.def_readwrite("servoPeriod", &Device::DeviceSettings::servoPeriod)
.def_readwrite("miniMaestroServoPeriod", &Device::DeviceSettings::miniMaestroServoPeriod)
.def_readwrite("servoMultiplier", &Device::DeviceSettings::servoMultiplier)
.def_readwrite("fixedBaudRate", &Device::DeviceSettings::fixedBaudRate)
.def_readwrite("enableCrc", &Device::DeviceSettings::enableCrc)
.def_readwrite("neverSuspend", &Device::DeviceSettings::neverSuspend)
.def_readwrite("serialDeviceNumber", &Device::DeviceSettings::serialDeviceNumber)
.def_readwrite("miniSscOffset", &Device::DeviceSettings::miniSscOffset)
.def_readwrite("serialTimeout", &Device::DeviceSettings::serialTimeout)
.def_readwrite("scriptDone", &Device::DeviceSettings::scriptDone)
.def_readwrite("enablePullups", &Device::DeviceSettings::enablePullups)
;

py::enum_<MaestroDevice::ChannelMode>(device, "ChannelMode")
.value("SERVO", MaestroDevice::ChannelMode::SERVO)
.value("SERVO_MULTIPLIED", MaestroDevice::ChannelMode::SERVO_MULTIPLIED)
.value("OUTPUT", MaestroDevice::ChannelMode::OUTPUT)
.value("INPUT", MaestroDevice::ChannelMode::INPUT)
py::enum_<Device::ChannelMode>(device, "ChannelMode")
.value("SERVO", Device::ChannelMode::SERVO)
.value("SERVO_MULTIPLIED", Device::ChannelMode::SERVO_MULTIPLIED)
.value("OUTPUT", Device::ChannelMode::OUTPUT)
.value("INPUT", Device::ChannelMode::INPUT)
.export_values();

py::enum_<MaestroDevice::HomeMode>(device, "HomeMode")
.value("OFF", MaestroDevice::HomeMode::OFF)
.value("IGNORE", MaestroDevice::HomeMode::IGNORE)
.value("GOTO", MaestroDevice::HomeMode::GOTO)
py::enum_<Device::HomeMode>(device, "HomeMode")
.value("OFF", Device::HomeMode::OFF)
.value("IGNORE", Device::HomeMode::IGNORE)
.value("GOTO", Device::HomeMode::GOTO)
.export_values();

py::class_<MaestroDevice::ChannelSettings>(device, "ChannelSettings")
.def_readwrite("mode", &MaestroDevice::ChannelSettings::mode)
.def_readwrite("homeMode", &MaestroDevice::ChannelSettings::homeMode)
.def_readwrite("home", &MaestroDevice::ChannelSettings::home)
.def_readwrite("minimum", &MaestroDevice::ChannelSettings::minimum)
.def_readwrite("maximum", &MaestroDevice::ChannelSettings::maximum)
.def_readwrite("neutral", &MaestroDevice::ChannelSettings::neutral)
.def_readwrite("range", &MaestroDevice::ChannelSettings::range)
.def_readwrite("speed", &MaestroDevice::ChannelSettings::speed)
.def_readwrite("acceleration", &MaestroDevice::ChannelSettings::acceleration)
py::class_<Device::ChannelSettings>(device, "ChannelSettings")
.def_readwrite("mode", &Device::ChannelSettings::mode)
.def_readwrite("homeMode", &Device::ChannelSettings::homeMode)
.def_readwrite("home", &Device::ChannelSettings::home)
.def_readwrite("minimum", &Device::ChannelSettings::minimum)
.def_readwrite("maximum", &Device::ChannelSettings::maximum)
.def_readwrite("neutral", &Device::ChannelSettings::neutral)
.def_readwrite("range", &Device::ChannelSettings::range)
.def_readwrite("speed", &Device::ChannelSettings::speed)
.def_readwrite("acceleration", &Device::ChannelSettings::acceleration)
;

py::class_<MaestroDevice::ServoStatus>(device, "ServoStatus")
.def_readonly("position", &MaestroDevice::ServoStatus::position)
.def_readonly("target", &MaestroDevice::ServoStatus::target)
.def_readonly("speed", &MaestroDevice::ServoStatus::speed)
.def_readonly("acceleration", &MaestroDevice::ServoStatus::acceleration)
py::class_<Device::ServoStatus>(device, "ServoStatus")
.def_readonly("position", &Device::ServoStatus::position)
.def_readonly("target", &Device::ServoStatus::target)
.def_readonly("speed", &Device::ServoStatus::speed)
.def_readonly("acceleration", &Device::ServoStatus::acceleration)
;

device.def("getName", &MaestroDevice::getName)
.def("getNumChannels", &MaestroDevice::getNumChannels)
.def("setTarget", &MaestroDevice::setTarget)
.def("setSpeed", &MaestroDevice::setSpeed)
.def("setAcceleration", &MaestroDevice::setAcceleration)
.def("getServoStatus", &MaestroDevice::getServoStatus)
.def("restoreDefaultConfiguration", &MaestroDevice::restoreDefaultConfiguration)
.def("getDeviceSettings", &MaestroDevice::getDeviceSettings)
.def("setDeviceSettings", &MaestroDevice::setDeviceSettings)
.def("getChannelSettings", &MaestroDevice::getChannelSettings)
.def("setChannelSettings", &MaestroDevice::setChannelSettings)
.def("eraseScript", &MaestroDevice::eraseScript)
.def("restartScriptAtSubroutine", &MaestroDevice::restartScriptAtSubroutine)
.def("restartScriptAtSubroutineWithParameter", &MaestroDevice::restartScriptAtSubroutineWithParameter)
.def("restartScript", &MaestroDevice::restartScript)
.def("setScriptDone", &MaestroDevice::setScriptDone)
.def("startBootloader", &MaestroDevice::startBootloader)
.def("reinitialize", &MaestroDevice::reinitialize)
.def("clearErrors", &MaestroDevice::clearErrors)
.def("writeScript", &MaestroDevice::writeScript)
.def("setPWM", &MaestroDevice::setPWM)
.def("disablePWM", &MaestroDevice::disablePWM)
device.def("getName", &Device::getName)
.def("getNumChannels", &Device::getNumChannels)
.def("setTarget", &Device::setTarget, py::arg("channelNumber"), py::arg("target"))
.def("setSpeed", &Device::setSpeed, py::arg("channelNumber"), py::arg("target"))
.def("setAcceleration", &Device::setAcceleration, py::arg("channelNumber"), py::arg("target"))
.def("getServoStatus", &Device::getServoStatus)
.def("restoreDefaultConfiguration", &Device::restoreDefaultConfiguration)
.def("getDeviceSettings", &Device::getDeviceSettings)
.def("setDeviceSettings", &Device::setDeviceSettings, py::arg("settings"))
.def("getChannelSettings", &Device::getChannelSettings)
.def("setChannelSettings", &Device::setChannelSettings, py::arg("channelNumber"), py::arg("settings"))
.def("eraseScript", &Device::eraseScript)
.def("restartScriptAtSubroutine", &Device::restartScriptAtSubroutine, py::arg("subroutineNumber"))
.def("restartScriptAtSubroutineWithParameter", &Device::restartScriptAtSubroutineWithParameter, py::arg("subroutineNumber"), py::arg("parameter"))
.def("restartScript", &Device::restartScript)
.def("setScriptDone", &Device::setScriptDone, py::arg("value"))
.def("startBootloader", &Device::startBootloader)
.def("reinitialize", &Device::reinitialize)
.def("clearErrors", &Device::clearErrors)
.def("writeScript", &Device::writeScript, py::arg("bytecode"))
.def("setPWM", &Device::setPWM, py::arg("dutyCycle"), py::arg("period"))
.def("disablePWM", &Device::disablePWM)
;

py::class_<Program>(m, "Program")
.def(py::init<const std::string &, bool>(), py::arg("script"), py::arg("isMiniMaestro"))
.def("getByteList", &Program::getByteList)
.def("getCRC", &Program::getCRC)
.def("toString", &Program::toString);
}
25 changes: 25 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
cmake_minimum_required(VERSION 3.11.4)

project(Maestro)

add_library(maestro STATIC
maestro/Device.h
maestro/Device.cpp
maestro/Instruction.cpp
maestro/Instruction.h
maestro/Program.cpp
maestro/Program.h
maestro/Opcode.h
)
target_link_libraries(maestro PRIVATE usb-1.0)
set_target_properties(maestro PROPERTIES CXX_STANDARD 11)
set_target_properties(maestro PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(maestro PROPERTIES PUBLIC_HEADER "maestro/Device.h;maestro/Program.h")
set_target_properties(maestro PROPERTIES FOLDER "Maestro")
target_include_directories(maestro PUBLIC .)

install(TARGETS maestro
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include)

Loading

0 comments on commit 7bc331b

Please sign in to comment.