Skip to content

Commit

Permalink
🎉 Initial dump of content
Browse files Browse the repository at this point in the history
  • Loading branch information
kammce committed Aug 5, 2024
1 parent ff8098e commit 2ce36fd
Show file tree
Hide file tree
Showing 29 changed files with 2,605 additions and 95 deletions.
19 changes: 17 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@ libhal_test_and_make_library(
LIBRARY_NAME libhal-actuator

SOURCES
src/actuator.cpp
src/rc_servo.cpp
src/smart_servo/rmd/drc_adaptors.cpp
src/smart_servo/rmd/drc.cpp
src/smart_servo/rmd/mc_x_adaptors.cpp
src/smart_servo/rmd/mc_x.cpp

TEST_SOURCES
tests/actuator.test.cpp
tests/main.test.cpp
tests/rc_servo.test.cpp
tests/smart_servo/rmd/drc.test.cpp
tests/smart_servo/rmd/mc_x.test.cpp
tests/smart_servo/rmd/drc_adaptors.test.cpp

PACKAGES
libhal-canrouter
libhal-mock

LINK_LIBRARIES
libhal::canrouter
libhal::mock
)
1 change: 1 addition & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def requirements(self):
# consumers get the libhal and libhal-util headers downstream.
bootstrap = self.python_requires["libhal-bootstrap"]
bootstrap.module.add_library_requirements(self)
self.requires("libhal-canrouter/[^3.0.0]")

def package_info(self):
self.cpp_info.libs = ["libhal-actuator"]
Expand Down
7 changes: 6 additions & 1 deletion demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ project(demos LANGUAGES CXX)

libhal_build_demos(
DEMOS
actuator
drc
mc_x
rc_servo

INCLUDES
.

PACKAGES
libhal-actuator
Expand Down
111 changes: 111 additions & 0 deletions demos/applications/drc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <libhal-actuator/smart_servo/rmd/drc.hpp>
#include <libhal-util/can.hpp>
#include <libhal-util/serial.hpp>
#include <libhal-util/steady_clock.hpp>

#include <resource_list.hpp>

void application(resource_list& p_map)
{
using namespace std::chrono_literals;
using namespace hal::literals;

auto& clock = *p_map.clock.value();
auto& console = *p_map.console.value();
auto& can = *p_map.can.value();

hal::print(console, "RMD DRC Smart Servo Application Starting...\n\n");

hal::can_router router(can);
hal::actuator::rmd_drc drc(router, clock, 6.0f, 0x141);

auto print_feedback = [&drc, &console]() {
drc.feedback_request(hal::actuator::rmd_drc::read::status_2);
drc.feedback_request(hal::actuator::rmd_drc::read::multi_turns_angle);
drc.feedback_request(
hal::actuator::rmd_drc::read::status_1_and_error_flags);

hal::print<2048>(console,
"[%u] =================================\n"
"raw_multi_turn_angle = %f\n"
"raw_current = %d\n"
"raw_speed = %d\n"
"raw_volts = %d\n"
"encoder = %d\n"
"raw_motor_temperature = %d"
"\n"
"over_voltage_protection_tripped = %d\n"
"over_temperature_protection_tripped = %d\n"
"-------\n"
"angle() = %f °deg\n"
"current() = %f A\n"
"speed() = %f rpm\n"
"volts() = %f V\n"
"temperature() = %f °C\n\n",

drc.feedback().message_number,
static_cast<float>(drc.feedback().raw_multi_turn_angle),
drc.feedback().raw_current,
drc.feedback().raw_speed,
drc.feedback().raw_volts,
drc.feedback().encoder,
drc.feedback().raw_motor_temperature,
drc.feedback().over_voltage_protection_tripped(),
drc.feedback().over_temperature_protection_tripped(),
drc.feedback().angle(),
drc.feedback().current(),
drc.feedback().speed(),
drc.feedback().volts(),
drc.feedback().temperature());
};

hal::delay(clock, 500ms);

while (true) {
drc.velocity_control(10.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.velocity_control(-10.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(0.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(-45.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(90.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(180.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(-360.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

drc.position_control(0.0_deg, 50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();
}
}
143 changes: 143 additions & 0 deletions demos/applications/mc_x.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <libhal-actuator/smart_servo/rmd/mc_x.hpp>
#include <libhal-util/can.hpp>
#include <libhal-util/serial.hpp>
#include <libhal-util/steady_clock.hpp>

#include <resource_list.hpp>

void application(resource_list& p_map)
{
using namespace std::chrono_literals;
using namespace hal::literals;

auto& clock = *p_map.clock.value();
auto& console = *p_map.console.value();
auto& can = *p_map.can.value();

hal::print(console, "RMD MC-X Smart Servo Application Starting...\n\n");

hal::can_router router(can);
hal::actuator::rmd_mc_x mc_x(router, clock, 36.0f, 0x141);

auto print_feedback = [&mc_x, &console]() {
mc_x.feedback_request(hal::actuator::rmd_mc_x::read::status_2);
mc_x.feedback_request(hal::actuator::rmd_mc_x::read::multi_turns_angle);
mc_x.feedback_request(
hal::actuator::rmd_mc_x::read::status_1_and_error_flags);

hal::print<2048>(console,
"[%u] =================================\n"
"raw_multi_turn_angle = %f\n"
"raw_current = %d\n"
"raw_speed = %d\n"
"raw_volts = %d\n"
"encoder = %d\n"
"raw_motor_temperature = %d"
"\n"
"-------\n"
"angle() = %f °deg\n"
"current() = %f A\n"
"speed() = %f rpm\n"
"volts() = %f V\n"
"temperature() = %f °C\n"
"motor_stall() = %d\n"
"low_pressure() = %d\n"
"over_voltage() = %d\n"
"over_current() = %d\n"
"power_overrun() = %d\n"
"speeding() = %d\n"
"over_temperature() = %d\n"
"encoder_calibration_error() = %d\n"
"\n",

mc_x.feedback().message_number,
static_cast<float>(mc_x.feedback().raw_multi_turn_angle),
mc_x.feedback().raw_current,
mc_x.feedback().raw_speed,
mc_x.feedback().raw_volts,
mc_x.feedback().encoder,
mc_x.feedback().raw_motor_temperature,
mc_x.feedback().angle(),
mc_x.feedback().current(),
mc_x.feedback().speed(),
mc_x.feedback().volts(),
mc_x.feedback().temperature(),
mc_x.feedback().motor_stall(),
mc_x.feedback().low_pressure(),
mc_x.feedback().over_voltage(),
mc_x.feedback().over_current(),
mc_x.feedback().power_overrun(),
mc_x.feedback().speeding(),
mc_x.feedback().over_temperature(),
mc_x.feedback().encoder_calibration_error());
};

while (true) {
mc_x.velocity_control(50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

mc_x.velocity_control(0.0_rpm);
hal::delay(clock, 2000ms);
print_feedback();

mc_x.velocity_control(-50.0_rpm);
hal::delay(clock, 5000ms);
print_feedback();

mc_x.velocity_control(0.0_rpm);
hal::delay(clock, 2000ms);
print_feedback();

// Position control above 40 RPM seems to cause issues with position control
mc_x.position_control(0.0_deg, 30.0_rpm);
hal::delay(clock, 1s);
print_feedback();

mc_x.position_control(90.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(180.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(90.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(0.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(-45.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(-90.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(-45.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();

mc_x.position_control(0.0_deg, 30.0_rpm);
hal::delay(clock, 2s);
print_feedback();
}
}
73 changes: 73 additions & 0 deletions demos/applications/rc_servo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2024 Khalil Estell
//
// 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.

#include <libhal-actuator/rc_servo.hpp>
#include <libhal-util/serial.hpp>
#include <libhal-util/steady_clock.hpp>

#include <resource_list.hpp>

void application(resource_list& p_map)
{
using namespace std::chrono_literals;
using namespace hal::literals;

auto& clock = *p_map.clock.value();
auto& console = *p_map.console.value();
auto& pwm = *p_map.pwm.value();

hal::print(console, "RC Servo Application Starting...\n\n");

hal::actuator::rc_servo::settings rc_servo_settings{
.frequency = 50,
// Total 180 deg, change for your use case.
.min_angle = -90,
.max_angle = 90,
// Change to 500us and 2500us if your rc servo
// supports those pulse widths.
.min_microseconds = 1000,
.max_microseconds = 2000,
};
hal::actuator::rc_servo servo(pwm, rc_servo_settings);

hal::print(console, "In 5 seconds...\n");
hal::delay(clock, 2000ms);

// Oscillate from the servo horn back and forth
while (true) {
hal::print(console, "0 deg\n");
servo.position(0.0_deg);
hal::delay(clock, 5000ms);

hal::print(console, "45 deg\n");
servo.position(45.0_deg);
hal::delay(clock, 5000ms);

hal::print(console, "90 deg\n");
servo.position(90.0_deg);
hal::delay(clock, 5000ms);

hal::print(console, "45 deg\n");
servo.position(45.0_deg);
hal::delay(clock, 5000ms);

hal::print(console, "0 deg\n");
servo.position(0.0_deg);
hal::delay(clock, 5000ms);

hal::print(console, "-45 deg\n");
servo.position(-45.0_deg);
hal::delay(clock, 5000ms);
}
}
Loading

0 comments on commit 2ce36fd

Please sign in to comment.