Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/alpine-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
run: apk add --no-cache build-base cmake linux-headers git
- uses: actions/checkout@v6
- name: configure
run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1
run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 -DCMAKE_COMPILE_WARNING_AS_ERROR=ON
- name: build
run: cmake --build build --config Debug
- name: test
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ jobs:
-DINTEGRATION_TESTS=1
-DWITH_ASAN=ON
-DPRIMARY_CLIENT_STRICT_PARSING=ON
-DCMAKE_COMPILE_WARNING_AS_ERROR=ON
env:
CXXFLAGS: -g -O2 -fprofile-arcs -ftest-coverage
CXXFLAGS: -g -O2 -fprofile-arcs -ftest-coverage
CFLAGS: -g -O2 -fprofile-arcs -ftest-coverage
LDFLAGS: -fprofile-arcs -ftest-coverage
- name: build
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/win-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- name: configure
run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1
#run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 -DINTEGRATION_TESTS=1
run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 -DCMAKE_COMPILE_WARNING_AS_ERROR=ON
- name: build
run: cmake --build build --config Debug
- name: test
Expand Down
24 changes: 23 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,20 @@ if(MSVC)
target_link_libraries(urcl ws2_32)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic")
target_compile_options(urcl PRIVATE -Wall -Wextra -Wno-unused-parameter)

# GCC 13-15 have a false positive -Wmaybe-uninitialized in <regex> headers
# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562).
# Bump the upper bound if the bug persists in newer GCC versions.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16)
set_source_files_properties(
src/control/script_reader.cpp
src/ur/dashboard_client.cpp
src/ur/dashboard_client_implementation_g5.cpp
src/ur/dashboard_client_implementation_x.cpp
PROPERTIES COMPILE_OPTIONS "-Wno-maybe-uninitialized")
endif()

if(WITH_ASAN)
target_compile_options(urcl PUBLIC -fsanitize=address)
Expand Down Expand Up @@ -101,6 +114,15 @@ if(CMAKE_THREAD_LIBS_INIT)
target_link_libraries(urcl PUBLIC "${CMAKE_THREAD_LIBS_INIT}")
endif()

# When warnings are treated as errors, also enable high warning level for all targets
if(CMAKE_COMPILE_WARNING_AS_ERROR)
Comment thread
urfeex marked this conversation as resolved.
if(MSVC)
add_compile_options(/W4)
else()
add_compile_options(-Wall -Wextra)
endif()
endif()

##
## Build testing if enabled by option
##
Expand Down
1 change: 0 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ project(ur_driver_examples)

# find_package(ur_client_library REQUIRED)


add_executable(driver_example
full_driver.cpp)
target_link_libraries(driver_example ur_client_library::urcl)
Expand Down
2 changes: 1 addition & 1 deletion examples/external_fts_through_rtde.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ char getChar()
{
if (_kbhit())
{
ch = _getch();
ch = static_cast<char>(_getch());
}
}
return ch;
Expand Down
10 changes: 5 additions & 5 deletions examples/spline_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,30 @@ void sendTrajectory(const std::vector<vector6d_t>& p_p, const std::vector<vector

URCL_LOG_INFO("Starting joint-based trajectory forward");
g_my_robot->getUrDriver()->writeTrajectoryControlMessage(urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
p_p.size());
static_cast<int>(p_p.size()));

for (size_t i = 0; i < p_p.size() && p_p.size() == time.size() && p_p[i].size() == 6; i++)
{
// MoveJ
if (!use_spline_interpolation_)
{
g_my_robot->getUrDriver()->writeTrajectoryPoint(p_p[i], false, time[i]);
g_my_robot->getUrDriver()->writeTrajectoryPoint(p_p[i], false, static_cast<float>(time[i]));
}
else // Use spline interpolation
{
// QUINTIC
if (p_v.size() == time.size() && p_a.size() == time.size() && p_v[i].size() == 6 && p_a[i].size() == 6)
{
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], p_v[i], p_a[i], time[i]);
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], p_v[i], p_a[i], static_cast<float>(time[i]));
}
// CUBIC
else if (p_v.size() == time.size() && p_v[i].size() == 6)
{
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], p_v[i], time[i]);
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], p_v[i], static_cast<float>(time[i]));
}
else
{
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], time[i]);
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(p_p[i], static_cast<float>(time[i]));
}
}
}
Expand Down
25 changes: 15 additions & 10 deletions examples/trajectory_point_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,20 @@ int main(int argc, char* argv[])

// Trajectory execution
g_my_robot->getUrDriver()->writeTrajectoryControlMessage(urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
points.size() * 2);
static_cast<int>(points.size() * 2));
for (size_t i = 0; i < points.size(); i++)
{
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], false, motion_durations[i], blend_radii[i]);
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], false, static_cast<float>(motion_durations[i]),
static_cast<float>(blend_radii[i]));
}

// Same motion, but parametrized with acceleration and velocity
motion_durations = { 0.0, 0.0 };
for (size_t i = 0; i < points.size(); i++)
{
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], accelerations[i], velocities[i], false,
motion_durations[i], blend_radii[i]);
g_my_robot->getUrDriver()->writeTrajectoryPoint(
points[i], static_cast<float>(accelerations[i]), static_cast<float>(velocities[i]), false,
static_cast<float>(motion_durations[i]), static_cast<float>(blend_radii[i]));
}

while (!g_trajectory_done)
Expand All @@ -125,19 +127,21 @@ int main(int argc, char* argv[])

// Trajectory execution of the path that goes through the points twice.
g_my_robot->getUrDriver()->writeTrajectoryControlMessage(urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
points.size() * 2);
static_cast<int>(points.size() * 2));
for (size_t i = 0; i < points.size(); i++)
{
// setting the cartesian parameter makes it interpret the 6d vector as a pose and use movel
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], true, motion_durations[i], blend_radii[i]);
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], true, static_cast<float>(motion_durations[i]),
static_cast<float>(blend_radii[i]));
}

// Same motion, but parametrized with acceleration and velocity
motion_durations = { 0.0, 0.0 };
for (size_t i = 0; i < points.size(); i++)
{
g_my_robot->getUrDriver()->writeTrajectoryPoint(points[i], accelerations[i], velocities[i], true,
motion_durations[i], blend_radii[i]);
g_my_robot->getUrDriver()->writeTrajectoryPoint(
points[i], static_cast<float>(accelerations[i]), static_cast<float>(velocities[i]), true,
static_cast<float>(motion_durations[i]), static_cast<float>(blend_radii[i]));
}

while (!g_trajectory_done)
Expand Down Expand Up @@ -165,10 +169,11 @@ int main(int argc, char* argv[])

// Trajectory execution
g_my_robot->getUrDriver()->writeTrajectoryControlMessage(urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
positions.size());
static_cast<int>(positions.size()));
for (size_t i = 0; i < positions.size(); i++)
{
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(positions[i], velocities[i], motion_durations[i]);
g_my_robot->getUrDriver()->writeTrajectorySplinePoint(positions[i], velocities[i],
static_cast<float>(motion_durations[i]));
}

while (!g_trajectory_done)
Expand Down
9 changes: 5 additions & 4 deletions include/ur_client_library/comm/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,9 @@ class IProducer
* failed. Unlimited number of attempts when set to 0.
* \param reconnection_time time in between connection attempts to the server
*/
virtual void setupProducer(const size_t max_num_tries = 0,
const std::chrono::milliseconds reconnection_time = std::chrono::seconds(10))
virtual void
setupProducer([[maybe_unused]] const size_t max_num_tries = 0,
[[maybe_unused]] const std::chrono::milliseconds reconnection_time = std::chrono::seconds(10))
{
}
/*!
Expand Down Expand Up @@ -267,13 +268,13 @@ class INotifier
/*!
* \brief Start notification.
*/
virtual void started(std::string name)
virtual void started([[maybe_unused]] std::string name)
{
}
/*!
* \brief Stop notification.
*/
virtual void stopped(std::string name)
virtual void stopped([[maybe_unused]] std::string name)
{
}
};
Expand Down
6 changes: 3 additions & 3 deletions include/ur_client_library/control/reverse_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class ReverseInterface
* \returns A unique handler ID for the registered callback. This can be used to unregister the
* callback later.
*/
uint32_t registerDisconnectionCallback(std::function<void(const int)> disconnection_fun)
uint32_t registerDisconnectionCallback(std::function<void(const socket_t)> disconnection_fun)
{
disconnect_callbacks_.push_back({ next_disconnect_callback_id_, disconnection_fun });
return next_disconnect_callback_id_++;
Expand All @@ -180,7 +180,7 @@ class ReverseInterface
void unregisterDisconnectionCallback(const uint32_t handler_id)
{
disconnect_callbacks_.remove_if(
[handler_id](const HandlerFunction<void(const int)>& h) { return h.id == handler_id; });
[handler_id](const HandlerFunction<void(const socket_t)>& h) { return h.id == handler_id; });
}

/*!
Expand Down Expand Up @@ -213,7 +213,7 @@ class ReverseInterface

virtual void messageCallback(const socket_t filedescriptor, char* buffer, int nbytesrecv);

std::list<HandlerFunction<void(const int)>> disconnect_callbacks_;
std::list<HandlerFunction<void(const socket_t)>> disconnect_callbacks_;
uint32_t next_disconnect_callback_id_ = 0;
socket_t client_fd_;
comm::TCPServer server_;
Expand Down
17 changes: 17 additions & 0 deletions include/ur_client_library/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#pragma once
#include <inttypes.h>
#include <memory>
#include <string>
#include <system_error>

#define URCL_LOG_DEBUG(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::DEBUG, __VA_ARGS__)
#define URCL_LOG_WARN(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::WARN, __VA_ARGS__)
Expand Down Expand Up @@ -88,4 +90,19 @@ void setLogLevel(LogLevel level);
* \param fmt Format string
*/
void log(const char* file, int line, LogLevel level, const char* fmt, ...);

/*!
* \brief Cross-platform replacement for strerror.
*
* On MSVC, strerror triggers C4996 (deprecated). This function uses std::error_code instead,
* which is portable and thread-safe.
*
* \param errnum Error number (typically errno)
* \returns Human-readable error message
*/
inline std::string strerror_portable(int errnum)
{
return std::error_code(errnum, std::generic_category()).message();
}

} // namespace urcl
4 changes: 2 additions & 2 deletions include/ur_client_library/primary/primary_consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class PrimaryConsumer : public AbstractPrimaryConsumer
*
* \returns True
*/
virtual bool consume(RobotMessage& msg) override
virtual bool consume([[maybe_unused]] RobotMessage& msg) override
{
return true;
}
Expand All @@ -74,7 +74,7 @@ class PrimaryConsumer : public AbstractPrimaryConsumer
*
* \returns True
*/
virtual bool consume(RobotState& msg) override
virtual bool consume([[maybe_unused]] RobotState& msg) override
{
return true;
}
Expand Down
12 changes: 6 additions & 6 deletions include/ur_client_library/primary/primary_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ class PrimaryParser : public comm::Parser<PrimaryPackage>
// deconstruction of a sub parser will increment the position of the parent parser
comm::BinParser sbp(bp, sub_size);
sbp.consume(sizeof(sub_size));
RobotStateType type;
sbp.parse(type);
RobotStateType sub_type;
sbp.parse(sub_type);

std::unique_ptr<PrimaryPackage> packet(stateFromType(type));
std::unique_ptr<PrimaryPackage> packet(stateFromType(sub_type));

if (packet == nullptr)
{
Expand All @@ -117,7 +117,7 @@ class PrimaryParser : public comm::Parser<PrimaryPackage>

if (!packet->parseWith(sbp))
{
URCL_LOG_ERROR("Sub-package parsing of type %d failed!", static_cast<int>(type));
URCL_LOG_ERROR("Sub-package parsing of type %d failed!", static_cast<int>(sub_type));
return false;
}

Expand All @@ -128,10 +128,10 @@ class PrimaryParser : public comm::Parser<PrimaryPackage>
sbp.debug();
if (strict_mode_)
{
throw UrException("Sub-package of type " + std::string(robotStateString(type)) +
throw UrException("Sub-package of type " + std::string(robotStateString(sub_type)) +
" was not parsed completely, and strict mode is enabled, so aborting parsing!");
}
URCL_LOG_WARN("Sub-package of type %s was not parsed completely!", robotStateString(type));
URCL_LOG_WARN("Sub-package of type %s was not parsed completely!", robotStateString(sub_type));
sbp.consume();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class DashboardClientImpl
*
* \param timeout The timeout to be set
*/
virtual void setReceiveTimeout(const timeval& timeout) {};
virtual void setReceiveTimeout([[maybe_unused]] const timeval& timeout) {};

/*!
* \brief Sends command and verifies that a valid answer is received.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class DashboardClientImplX : public DashboardClientImpl
DashboardResponse commandUpdateProgram(const std::string& file_path) override;
DashboardResponse commandDownloadProgram(const std::string& filename, const std::string& save_path) override;

void setReceiveTimeout(const timeval& timeout) override
void setReceiveTimeout([[maybe_unused]] const timeval& timeout) override
{
}

Expand Down
2 changes: 1 addition & 1 deletion include/ur_client_library/ur/instruction_executor.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class InstructionExecutor

protected:
void trajDoneCallback(const urcl::control::TrajectoryResult& result);
void trajDisconnectCallback(const int filedescriptor);
void trajDisconnectCallback(const socket_t filedescriptor);

uint32_t traj_done_callback_handler_id_;
uint32_t disconnected_handler_id_;
Expand Down
4 changes: 2 additions & 2 deletions include/ur_client_library/ur/ur_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ class UrDriver

uint32_t getControlFrequency() const
{
return rtde_client_->getTargetFrequency();
return static_cast<uint32_t>(rtde_client_->getTargetFrequency());
Comment thread
urrsk marked this conversation as resolved.
}

/*!
Expand Down Expand Up @@ -1000,7 +1000,7 @@ class UrDriver
*
* \returns The ID of the callback that can be used to unregister the callback later.
*/
uint32_t registerTrajectoryInterfaceDisconnectedCallback(std::function<void(const int)> fun)
uint32_t registerTrajectoryInterfaceDisconnectedCallback(std::function<void(const socket_t)> fun)
{
return trajectory_interface_->registerDisconnectionCallback(fun);
}
Expand Down
4 changes: 2 additions & 2 deletions src/comm/tcp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void TCPServer::shutdown()
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = htons(port_);
address.sin_port = htons(static_cast<uint16_t>(port_));

::connect(shutdown_socket, reinterpret_cast<const sockaddr*>(&address), sizeof(address));

Expand Down Expand Up @@ -152,7 +152,7 @@ void TCPServer::bind(const size_t max_num_tries, const std::chrono::milliseconds

// INADDR_ANY is a special constant that signalizes "ANY IFACE",
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(port_);
server_addr.sin_port = htons(static_cast<uint16_t>(port_));
int err = -1;
size_t connection_counter = 0;
do
Expand Down
Loading
Loading