Compare commits

...

30 commits

Author SHA1 Message Date
Jacob Perron
d1071443ff
Update Autonomy Lab link
All checks were successful
Build and test / test (push) Successful in 1m59s
Package / package (map[dpkg:arm64 runs-on:debian-12-arm64]) (push) Successful in 5m44s
(cherry picked from commit 116be443e7970de1574b5dc5f91e414828854c08)
2025-06-06 23:03:42 +02:00
ac3968e055
ci: package: fix whitespace errors
Signed-off-by: Christoph Heiss <christoph.heiss@robo4you.at>
2025-06-06 23:01:25 +02:00
661fa82f6e
ci: also include Botball repo
All checks were successful
Build and test / test (push) Successful in 2m2s
Build and test / test (pull_request) Successful in 1m56s
2025-06-06 20:39:07 +02:00
6c8a7b3acc
ci: switch to forgejo actions
All checks were successful
Build and test / test (push) Successful in 2m2s
Package / package (map[dpkg:arm64 runs-on:debian-12-arm64]) (push) Successful in 5m41s
Signed-off-by: Christoph Heiss <christoph@c8h4.io>
2025-06-06 20:15:42 +02:00
f07973e426
Revert "ci: switch workflows to Default runner group"
This reverts commit 8df56b61ba.
2024-10-08 11:48:52 +02:00
8df56b61ba
ci: switch workflows to Default runner group
Signed-off-by: Christoph Heiss <christoph.heiss@robo4you.at>
2024-10-07 11:55:33 +02:00
f49a76c7e4
gitignore: add cmake/cpack output directories
Signed-off-by: Christoph Heiss <christoph.heiss@robo4you.at>
2024-09-26 09:21:10 +02:00
d07add7a91
chore: delete empty file
Signed-off-by: Christoph Heiss <christoph.heiss@robo4you.at>
2024-09-26 09:20:57 +02:00
d5885d4d39
Merge pull request #2 from F-WuTS/feature/ci-packing 2024-09-26 09:18:37 +02:00
Konstantin Lampalzer
5a591cfbba ci: remove Werror from entrypoint 2024-09-25 21:58:36 +02:00
Konstantin Lampalzer
e51895fa18 cmake: add default Werror, extract version only from GITHUB_REF if tag 2024-09-25 21:54:46 +02:00
Konstantin Lampalzer
3ac90c382e ci: change target-dir in comprep to debs/libcreate 2024-09-23 22:46:52 +02:00
Konstantin Lampalzer
78424d187c cmake: do not install to opt
Some checks failed
Package / package (linux/arm64/v8) (push) Failing after 46s
2024-09-23 21:13:21 +02:00
Konstantin Lampalzer
f3cafc241d ci: change from ubuntu base to debian base 2024-09-23 17:12:41 +02:00
Konstantin Lampalzer
52201a3932 ci: fix SSH_DEPLOY_KEY env var 2024-09-23 15:51:44 +02:00
Konstantin Lampalzer
1979a5d405 ci: add push to compREP 2024-09-23 14:31:09 +02:00
Konstantin Lampalzer
f8b977336a ci: change tag filter 2024-09-23 14:09:47 +02:00
Konstantin Lampalzer
efd9cf02c9 ci: add tag extraction from github_ref var 2024-09-23 14:06:29 +02:00
Konstantin Lampalzer
3836d1480b ci: add packing job 2024-09-23 13:34:34 +02:00
Konstantin Lampalzer
1791063fa8 cmake: add versioning module 2024-09-23 13:34:10 +02:00
Konstantin Lampalzer
7ae7155f25 ci: add Packing cmake and dockerfile to run packing 2024-09-22 18:29:51 +02:00
Konstantin Lampalzer
8b5167b319 fix tests for new cliff packets, add string to packet.h 2024-09-22 18:13:22 +02:00
Bernhard Klauninger
aaa7b5076e Implemented Create reset method 2024-09-22 17:32:37 +02:00
Joel Klimont
d3a714cc51 changed install dir 2024-09-22 17:32:37 +02:00
DuSack1220
7ade48545e fixed cliff signal documentation 2024-09-22 17:32:37 +02:00
Bernhard Klauninger
2c58777e45 Actually fixed wrap around 2024-09-22 17:32:37 +02:00
DuSack1220
1bc2d768f7 fixed encoder overflow 2024-09-22 17:32:37 +02:00
DuSack1220
fd2638114a added cliff sensor signals 2024-09-22 17:32:37 +02:00
Jacob Perron
a8e274be15 Update README
Fix/remove broken or outdated links.

Signed-off-by: Jacob Perron <jacobmperron@gmail.com>
2023-05-21 16:59:38 -07:00
Jacob Perron
05e01c85a4 Update CI workflow
Remove 18.04 since it is no longer supported by GitHub actions.
Add 22.04.

Signed-off-by: Jacob Perron <jacobmperron@gmail.com>
2023-05-21 16:54:35 -07:00
14 changed files with 320 additions and 62 deletions

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
.github
ci/Dockerfile

View file

@ -0,0 +1,76 @@
---
name: Package
on:
push:
tags:
- "*"
jobs:
package:
strategy:
matrix:
platform:
- dpkg: arm64
runs-on: debian-12-arm64
runs-on: debian-12-arm64
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Install dependencies
run: |
apt update
apt install -y \
build-essential cmake git libboost-system-dev libboost-thread-dev file libgtest-dev googletest
- uses: actions/checkout@v4
- name: configure
run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCPACK_DEBIAN_PACKAGE_RELEASE=compair1
- name: build
run: cmake --build build --config Release -j2
- name: test
working-directory: build
run: ctest -C Release
- name: build deb
working-directory: build
run: cpack --build . -G DEB
- name: get tag
run: |
echo "TAG=$(git describe --abbrev=0 --tags)-compair1" >>$GITHUB_ENV
# https://forgejo.org/docs/latest/user/packages/debian/#publish-a-package
- name: push deb to apt repository
env:
REPO: ${{ github.repository }}
run: |
url="${GITHUB_SERVER_URL}/api/packages/${{ github.repository_owner }}/debian/pool/bookworm/compair/upload"
urlBotball="${GITHUB_SERVER_URL}/api/packages/Botball/debian/pool/bookworm/wombatos/upload"
echo "api url: $url"
debfile="_packages/libcreate_${TAG}_${{ matrix.platform.dpkg }}.deb"
echo "uploading file: $debfile"
curl --fail-with-body \
-X PUT \
--user "oauth2:${{ secrets.PACKAGE_REGISTRY_TOKEN }}" \
--upload-file "$debfile" \
"$url"
echo "uploading file for WombatOs: $debfile"
curl --fail-with-body \
-X PUT \
--user "oauth2:${{ secrets.PACKAGE_REGISTRY_TOKEN }}" \
--upload-file "$debfile" \
"$urlBotball"
echo "final url: ${GITHUB_SERVER_URL}/${{ github.repository_owner }}/-/packages/debian/libcreate/${TAG}"
echo "final url for Botball: ${GITHUB_SERVER_URL}/Botball/-/packages/debian/libcreate/${TAG}"

View file

@ -0,0 +1,34 @@
---
name: Build and test
on:
push:
branches:
- master
pull_request:
env:
BUILD_TYPE: Release
jobs:
test:
runs-on: debian-12
steps:
- name: Install dependencies
run: |
apt update
apt install -y \
build-essential cmake git libboost-system-dev libboost-thread-dev file libgtest-dev googletest
- uses: actions/checkout@v4
- name: Configure CMake
run: cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
- name: Build
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }}
- name: Test
working-directory: ${{ github.workspace }}/build
run: ctest -C ${{ env.BUILD_TYPE }}

View file

@ -1,38 +0,0 @@
name: Build and test
on:
push:
branches: ['master']
pull_request:
env:
BUILD_TYPE: Release
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
steps:
- name: Install dependencies
run: |
sudo apt install build-essential cmake git libboost-system-dev libboost-thread-dev
git clone https://github.com/google/googletest.git
cd googletest
cmake CMakeLists.txt
make
sudo make install
- uses: actions/checkout@v2
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_FLAGS="-Werror"
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}/build
run: ctest -C ${{env.BUILD_TYPE}}

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# CMake/CPack
build/
_packages/

View file

@ -1,3 +1,17 @@
#########
# Setup #
#########
cmake_minimum_required(VERSION 3.25)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Versioning)
########
# Main #
########
# After installation this project can be found by 'find_package' command:
#
# find_package(libcreate REQUIRED)
@ -5,12 +19,14 @@
# target_link_libraries(... ${libcreate_LIBRARIES})
#
cmake_minimum_required(VERSION 2.8.12)
project(libcreate)
project(
libcreate
VERSION ${TAG_VERSION_MAJOR}.${TAG_VERSION_MINOR}.${TAG_VERSION_PATCH}
)
add_compile_options(-Wall -Wextra -Wpedantic)
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
set(PACKAGE_VERSION 3.0.0)
set(PACKAGE_VERSION ${TAG_VERSION_MAJOR}.${TAG_VERSION_MINOR}.${TAG_VERSION_PATCH})
option(LIBCREATE_BUILD_TESTS "Enable the build of tests." ON)
@ -84,6 +100,8 @@ endforeach()
# Configuration #
#################
# set(CMAKE_INSTALL_PREFIX "/usr/") // complib needs this, riplib doesn't
# Install directories layout:
# * <prefix>/lib/
# * <prefix>/bin/
@ -201,3 +219,9 @@ if(LIBCREATE_BUILD_TESTS AND ${GTEST_FOUND})
else()
message("No GTest installation found. Skipping tests.")
endif()
#############
# Packaging #
#############
include(Packing)

View file

@ -1,13 +1,13 @@
# libcreate #
C++ library for interfacing with iRobot's [Create 1 and 2](http://www.irobot.com/About-iRobot/STEM/Create-2.aspx) as well as most models of Roomba. [create_autonomy](http://wiki.ros.org/create_autonomy) is a [ROS](http://www.ros.org/) wrapper for this library.
C++ library for interfacing with iRobot's Create 1 and 2 as well as most models of Roomba. [create_robot](http://wiki.ros.org/create_robot) is a [ROS](http://www.ros.org/) wrapper for this library.
* [Code API](http://docs.ros.org/kinetic/api/libcreate/html/index.html)
* [Code API](http://docs.ros.org/noetic/api/libcreate/html/index.html)
* Protocol documentation:
- [`V_1`](https://drive.google.com/file/d/0B9O4b91VYXMdUHlqNklDU09NU0k) (Roomba 400 series )
- [`V_2`](https://drive.google.com/file/d/0B9O4b91VYXMdMmFPMVNDUEZ6d0U) (Create 1, Roomba 500 series)
- [`V_3`](https://drive.google.com/file/d/0B9O4b91VYXMdSVk4amw1N09mQ3c) (Create 2, Roomba 600-800 series)
* Author: [Jacob Perron](http://jacobperron.ca) ([Autonomy Lab](http://autonomylab.org), [Simon Fraser University](http://www.sfu.ca))
- [`V_1`](https://drive.google.com/file/d/0B9O4b91VYXMdUHlqNklDU09NU0k/view?usp=sharing&resourcekey=0-KxMpRPBMsGAj7eSYC_9ewA) (Roomba 400 series )
- [`V_2`](https://drive.google.com/file/d/0B9O4b91VYXMdMmFPMVNDUEZ6d0U/view?usp=sharing&resourcekey=0-bqKH8xhtWdYtTik_LLWo9Q) (Create 1, Roomba 500 series)
- [`V_3`](https://drive.google.com/file/d/0B9O4b91VYXMdSVk4amw1N09mQ3c/view?usp=sharing&resourcekey=0-rKvug2IzC7nj4zV31EJtww) (Create 2, Roomba 600-800 series)
* Author: [Jacob Perron](http://jacobperron.ca) ([Autonomy Lab](https://autonomy.cs.sfu.ca), [Simon Fraser University](http://www.sfu.ca))
* Contributors: [Mani Monajjemi](http:mani.im), [Ben Wolsieffer](https://github.com/lopsided98), [Josh Gadeken](https://github.com/process1183)
## Build Status ##

41
cmake/Packing.cmake Normal file
View file

@ -0,0 +1,41 @@
# these are cache variables, so they could be overwritten with -D,
set(CPACK_PACKAGE_NAME ${PROJECT_NAME}
CACHE STRING "The resulting package name"
)
# which is useful in case of packing only selected components instead of the whole thing
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "C++ library for interfacing with iRobot's Create 1 and 2"
CACHE STRING "Package description for the package metadata"
)
set(CPACK_PACKAGE_VENDOR "Verein zur Förderung von Jugendlichen durch Robotikwettbewerbe")
set(CPACK_VERBATIM_VARIABLES YES)
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
SET(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/_packages")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_CONTACT "kontakt@comp-air.at")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "comp-air dev team")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
# Discover and set dependencies correcly
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS YES)
# The installation path directory should have 0755 permissions
set(
CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
)
# package name for deb. If set, then instead of some-application-0.9.2-Linux.deb
# you'll get some-application_0.9.2_amd64.deb (note the underscores too)
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
include(CPack)

31
cmake/Versioning.cmake Normal file
View file

@ -0,0 +1,31 @@
find_package(Git)
if(GIT_EXECUTABLE)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags
OUTPUT_VARIABLE TAG_VERSION
RESULT_VARIABLE ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(DEFINED ENV{GITHUB_REF} AND ENV{GITHUB_REF_TYPE} EQUAL "tag")
set(TAG_VERSION $ENV{GITHUB_REF})
message(STATUS "Extracted version from GITHUB_REF")
endif()
if(TAG_VERSION STREQUAL "")
set(TAG_VERSION 0.0.0)
message(WARNING "Failed to determine version from Git tags. Using default version \"${TAG_VERSION}\".")
endif()
message(STATUS "Project version: ${TAG_VERSION}")
# Split into major, minor, patch
string(
REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)"
TAG_VERSION_MATCH ${TAG_VERSION}
)
set(TAG_VERSION_MAJOR ${CMAKE_MATCH_1})
set(TAG_VERSION_MINOR ${CMAKE_MATCH_2})
set(TAG_VERSION_PATCH ${CMAKE_MATCH_3})
endif()

View file

@ -135,6 +135,11 @@ namespace create {
*/
~Create();
/**
* \brief Resets the create as if the battery was removed and reinserted.
*/
void reset();
/**
* \brief Make a serial connection to Create.
*
@ -406,6 +411,26 @@ namespace create {
*/
bool isCliffFrontRight() const;
/**
* \return the IR value of the left cliff sensor.
*/
uint16_t getCliffSignalLeft() const;
/**
* \return the IR value of the front left cliff sensor.
*/
uint16_t getCliffSignalFrontLeft() const;
/**
* \return the IR value of the right cliff sensor.
*/
uint16_t getCliffSignalRight() const;
/**
* \return the IR value of the front right cliff sensor.
*/
uint16_t getCliffSignalFrontRight() const;
/**
* \return true if there is a virtual wall signal is being received.
*/

View file

@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define CREATE_PACKET_H
#include <mutex>
#include <string>
namespace create {
class Packet {

View file

@ -67,6 +67,15 @@ namespace create {
disconnect();
}
void Create::reset() {
if (!connected()) {
CERR("[create::Serial] ", "send failed, not connected.");
return;
}
serial->sendOpcode(OC_START);
serial->sendOpcode(OC_RESET);
}
Create::Matrix Create::addMatrices(const Matrix &A, const Matrix &B) const {
size_t rows = A.size1();
size_t cols = A.size2();
@ -156,17 +165,23 @@ namespace create {
// Compute ticks since last update
int ticksLeft = totalTicksLeft - prevTicksLeft;
int ticksRight = totalTicksRight - prevTicksRight;
prevTicksLeft = totalTicksLeft;
prevTicksRight = totalTicksRight;
// Handle wrap around
if (std::abs(ticksLeft) > 0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksLeft = (ticksLeft % util::V_3_MAX_ENCODER_TICKS) + 1;
if (ticksLeft > 0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksLeft -= util::V_3_MAX_ENCODER_TICKS;
} else if (ticksLeft < -0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksLeft += util::V_3_MAX_ENCODER_TICKS;
}
if (std::abs(ticksRight) > 0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksRight = (ticksRight % util::V_3_MAX_ENCODER_TICKS) + 1;
if (ticksRight > 0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksRight -= util::V_3_MAX_ENCODER_TICKS;
} else if (ticksRight < -0.9 * util::V_3_MAX_ENCODER_TICKS) {
ticksRight += util::V_3_MAX_ENCODER_TICKS;
}
prevTicksLeft = totalTicksLeft;
prevTicksRight = totalTicksRight;
// Compute distance travelled by each wheel
leftWheelDist = (ticksLeft / util::V_3_TICKS_PER_REV)
* model.getWheelDiameter() * util::PI;
@ -738,6 +753,46 @@ namespace create {
}
}
uint16_t Create::getCliffSignalLeft() const {
if (data->isValidPacketID(ID_CLIFF_LEFT)) {
return GET_DATA(ID_CLIFF_LEFT_SIGNAL);
}
else {
CERR("[create::Create] ", "Left cliff sensor signals not supported!");
return false;
}
}
uint16_t Create::getCliffSignalFrontLeft() const {
if (data->isValidPacketID(ID_CLIFF_FRONT_LEFT)) {
return GET_DATA(ID_CLIFF_FRONT_LEFT_SIGNAL);
}
else {
CERR("[create::Create] ", "Front left cliff sensor signals not supported!");
return false;
}
}
uint16_t Create::getCliffSignalRight() const {
if (data->isValidPacketID(ID_CLIFF_RIGHT)) {
return GET_DATA(ID_CLIFF_RIGHT_SIGNAL);
}
else {
CERR("[create::Create] ", "Rightt cliff sensor signals not supported!");
return false;
}
}
uint16_t Create::getCliffSignalFrontRight() const {
if (data->isValidPacketID(ID_CLIFF_FRONT_RIGHT)) {
return GET_DATA(ID_CLIFF_FRONT_RIGHT_SIGNAL);
}
else {
CERR("[create::Create] ", "Front right cliff sensor signals not supported!");
return false;
}
}
bool Create::isVirtualWall() const {
if (data->isValidPacketID(ID_VIRTUAL_WALL)) {
return GET_DATA(ID_VIRTUAL_WALL);

View file

@ -16,6 +16,10 @@ namespace create {
ADD_PACKET(ID_CLIFF_FRONT_LEFT, 1, "cliff_front_left", V_ALL);
ADD_PACKET(ID_CLIFF_FRONT_RIGHT, 1, "cliff_front_right", V_ALL);
ADD_PACKET(ID_CLIFF_RIGHT, 1, "cliff_right", V_ALL);
ADD_PACKET(ID_CLIFF_LEFT_SIGNAL, 2, "cliff_left_signal", V_3);
ADD_PACKET(ID_CLIFF_FRONT_LEFT_SIGNAL, 2, "cliff_front_left_signal", V_3);
ADD_PACKET(ID_CLIFF_FRONT_RIGHT_SIGNAL, 2, "cliff_front_right_signal", V_3);
ADD_PACKET(ID_CLIFF_RIGHT_SIGNAL, 2, "cliff_right_signal", V_3);
ADD_PACKET(ID_VIRTUAL_WALL, 1, "virtual_wall", V_ALL);
ADD_PACKET(ID_OVERCURRENTS, 1, "overcurrents", V_ALL);
ADD_PACKET(ID_DIRT_DETECT_LEFT, 1, "dirt_detect_left", V_ALL);

View file

@ -65,11 +65,11 @@ TEST(DataTest, GetNumPackets)
create::Data data_v_3(create::V_3);
// Number exclusive to V_3 = 13
// 17 + 13 = 30
EXPECT_EQ(static_cast<int>(data_v_3.getNumPackets()), 30);
// 17 + 17 = 34
EXPECT_EQ(static_cast<int>(data_v_3.getNumPackets()), 34);
create::Data data_v_all(create::V_ALL);
EXPECT_EQ(static_cast<int>(data_v_all.getNumPackets()), 33);
EXPECT_EQ(static_cast<int>(data_v_all.getNumPackets()), 37);
}
TEST(DataTest, GetPacket)
@ -108,7 +108,7 @@ TEST(DataTest, GetPacketIDs)
create::Data data_v_3(create::V_3);
const std::vector<uint8_t> packet_ids = data_v_3.getPacketIDs();
// Vector should have same length as reported by getNumPackets()
ASSERT_EQ(static_cast<int>(packet_ids.size()), 30);
ASSERT_EQ(static_cast<int>(packet_ids.size()), 34);
// Vector should contain ID_LEFT_ENC
bool found = false;
@ -133,9 +133,9 @@ TEST(DataTest, GetTotalDataBytes)
create::Data data_v_2(create::V_2);
EXPECT_EQ(static_cast<int>(data_v_2.getTotalDataBytes()), 26);
// V_3 has an additional 21 bytes
// V_3 has an additional 29 bytes
create::Data data_v_3(create::V_3);
EXPECT_EQ(static_cast<int>(data_v_3.getTotalDataBytes()), 42);
EXPECT_EQ(static_cast<int>(data_v_3.getTotalDataBytes()), 50);
}
TEST(DataTest, IsValidPacketID)