Skip to content

Commit e688988

Browse files
author
Felix Exner (fexner)
authored
Analog domain (#211)
This adds the possibility to specify the output domain when setting an analog output.
1 parent 0f0321a commit e688988

File tree

4 files changed

+102
-9
lines changed

4 files changed

+102
-9
lines changed

include/ur_client_library/rtde/rtde_writer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "ur_client_library/rtde/data_package.h"
3535
#include "ur_client_library/comm/stream.h"
3636
#include "ur_client_library/queue/readerwriterqueue.h"
37+
#include "ur_client_library/ur/datatypes.h"
3738
#include <thread>
3839
#include <mutex>
3940

@@ -118,10 +119,14 @@ class RTDEWriter
118119
*
119120
* \param output_pin The pin to change
120121
* \param value The new value, it should be between 0 and 1, where 0 is 4mA and 1 is 20mA.
122+
* \param type The domain for the output can be eitherAnalogOutputType::CURRENT or AnalogOutputType::VOLTAGE or
123+
* AnalogOutputType::SET_ON_TEACH_PENDANT. In the latter case the domain is left untouched and the domain configured
124+
* on the teach pendant will be used.
121125
*
122126
* \returns Success of the package creation
123127
*/
124-
bool sendStandardAnalogOutput(uint8_t output_pin, double value);
128+
bool sendStandardAnalogOutput(uint8_t output_pin, double value,
129+
const AnalogOutputType type = AnalogOutputType::SET_ON_TEACH_PENDANT);
125130

126131
/*!
127132
* \brief Creates a package to request setting a new value for an input_bit_register

include/ur_client_library/ur/datatypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ enum class SafetyStatus : int8_t // Only available on 3.10/5.4
7979
SYSTEM_THREE_POSITION_ENABLING_STOP = 13
8080
};
8181

82+
enum class AnalogOutputType : int8_t
83+
{
84+
SET_ON_TEACH_PENDANT = -1,
85+
CURRENT = 0,
86+
VOLTAGE = 1
87+
};
88+
8289
inline std::string robotModeString(const RobotMode& mode)
8390
{
8491
switch (mode)

src/rtde/rtde_writer.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ bool RTDEWriter::sendToolDigitalOutput(uint8_t output_pin, bool value)
204204
return success;
205205
}
206206

207-
bool RTDEWriter::sendStandardAnalogOutput(uint8_t output_pin, double value)
207+
bool RTDEWriter::sendStandardAnalogOutput(uint8_t output_pin, double value, const AnalogOutputType type)
208208
{
209209
if (output_pin > 1)
210210
{
@@ -216,18 +216,22 @@ bool RTDEWriter::sendStandardAnalogOutput(uint8_t output_pin, double value)
216216
if (value > 1.0 || value < 0.0)
217217
{
218218
std::stringstream ss;
219-
ss << "Analog output value should be between 0 and 1. The value is " << static_cast<int>(value);
219+
ss << "Analog output value should be between 0 and 1. The value is " << static_cast<double>(value);
220220
URCL_LOG_ERROR(ss.str().c_str());
221221
return false;
222222
}
223223

224224
std::lock_guard<std::mutex> guard(package_mutex_);
225225
uint8_t mask = pinToMask(output_pin);
226-
// default to current for now, as no functionality to choose included in set io service
227-
uint8_t output_type = 0;
226+
228227
bool success = true;
229228
success = package_.setData("standard_analog_output_mask", mask);
230-
success = success && package_.setData("standard_analog_output_type", output_type);
229+
if (type != AnalogOutputType::SET_ON_TEACH_PENDANT)
230+
{
231+
auto output_type_bits = [](const uint8_t pin, const uint8_t type) { return type << pin; };
232+
uint8_t output_type = output_type_bits(output_pin, toUnderlying(type));
233+
success = success && package_.setData("standard_analog_output_type", output_type);
234+
}
231235
success = success && package_.setData("standard_analog_output_0", value);
232236
success = success && package_.setData("standard_analog_output_1", value);
233237

tests/test_rtde_writer.cpp

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,12 @@ TEST_F(RTDEWriterTest, send_tool_digital_output)
260260
EXPECT_FALSE(writer_->sendToolDigitalOutput(pin, send_pin_value));
261261
}
262262

263-
TEST_F(RTDEWriterTest, send_standard_analog_output)
263+
TEST_F(RTDEWriterTest, send_standard_analog_output_unknown_domain)
264264
{
265+
waitForMessageCallback(1000);
266+
265267
uint8_t expected_standard_analog_output_mask = 1;
268+
266269
uint8_t pin = 0;
267270
double send_analog_output = 1;
268271
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output));
@@ -272,26 +275,100 @@ TEST_F(RTDEWriterTest, send_standard_analog_output)
272275
ASSERT_TRUE(dataFieldExist("standard_analog_output_0"));
273276
ASSERT_TRUE(dataFieldExist("standard_analog_output_1"));
274277
ASSERT_TRUE(dataFieldExist("standard_analog_output_mask"));
278+
ASSERT_TRUE(dataFieldExist("standard_analog_output_type"));
279+
280+
double received_analog_output = std::get<double>(parsed_data_["standard_analog_output_0"]);
281+
uint8_t received_standard_analog_output_mask = std::get<uint8_t>(parsed_data_["standard_analog_output_mask"]);
282+
uint8_t received_standard_analog_output_type = std::get<uint8_t>(parsed_data_["standard_analog_output_type"]);
283+
284+
EXPECT_EQ(send_analog_output, received_analog_output);
285+
EXPECT_EQ(expected_standard_analog_output_mask, received_standard_analog_output_mask);
286+
// The test server sets this to 0 if not given
287+
EXPECT_EQ(0, received_standard_analog_output_type);
288+
}
289+
290+
TEST_F(RTDEWriterTest, send_standard_analog_output_voltage)
291+
{
292+
uint8_t pin = 0;
293+
AnalogOutputType type = AnalogOutputType::VOLTAGE;
294+
double send_analog_output = 1;
295+
296+
uint8_t expected_standard_analog_output_mask = 1;
297+
uint8_t expected_standard_analog_output_type = 1;
298+
299+
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output, type));
300+
301+
waitForMessageCallback(1000);
275302

276303
double received_analog_output = std::get<double>(parsed_data_["standard_analog_output_0"]);
277304
uint8_t received_standard_analog_output_mask = std::get<uint8_t>(parsed_data_["standard_analog_output_mask"]);
305+
uint8_t received_standard_analog_output_type = std::get<uint8_t>(parsed_data_["standard_analog_output_type"]);
278306

279307
EXPECT_EQ(send_analog_output, received_analog_output);
280308
EXPECT_EQ(expected_standard_analog_output_mask, received_standard_analog_output_mask);
309+
EXPECT_EQ(expected_standard_analog_output_type, received_standard_analog_output_type);
281310

282311
pin = 1;
283312
expected_standard_analog_output_mask = 2;
284-
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output));
313+
expected_standard_analog_output_type = 2;
314+
315+
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output, type));
285316

286317
waitForMessageCallback(1000);
287318

288319
received_analog_output = std::get<double>(parsed_data_["standard_analog_output_1"]);
289320
received_standard_analog_output_mask = std::get<uint8_t>(parsed_data_["standard_analog_output_mask"]);
321+
received_standard_analog_output_type = std::get<uint8_t>(parsed_data_["standard_analog_output_type"]);
290322

291323
EXPECT_EQ(send_analog_output, received_analog_output);
292324
EXPECT_EQ(expected_standard_analog_output_mask, received_standard_analog_output_mask);
325+
EXPECT_EQ(expected_standard_analog_output_type, received_standard_analog_output_type);
326+
}
293327

294-
// Changing pins above 1, should return false.
328+
TEST_F(RTDEWriterTest, send_standard_analog_output_current)
329+
{
330+
uint8_t pin = 0;
331+
AnalogOutputType type = AnalogOutputType::CURRENT;
332+
double send_analog_output = 1;
333+
334+
uint8_t expected_standard_analog_output_mask = 1;
335+
uint8_t expected_standard_analog_output_type = 0;
336+
337+
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output, type));
338+
339+
waitForMessageCallback(1000);
340+
341+
double received_analog_output = std::get<double>(parsed_data_["standard_analog_output_0"]);
342+
uint8_t received_standard_analog_output_mask = std::get<uint8_t>(parsed_data_["standard_analog_output_mask"]);
343+
uint8_t received_standard_analog_output_type = std::get<uint8_t>(parsed_data_["standard_analog_output_type"]);
344+
345+
EXPECT_EQ(send_analog_output, received_analog_output);
346+
EXPECT_EQ(expected_standard_analog_output_mask, received_standard_analog_output_mask);
347+
EXPECT_EQ(expected_standard_analog_output_type, received_standard_analog_output_type);
348+
349+
pin = 1;
350+
expected_standard_analog_output_mask = 2;
351+
expected_standard_analog_output_type = 0;
352+
353+
EXPECT_TRUE(writer_->sendStandardAnalogOutput(pin, send_analog_output, type));
354+
355+
waitForMessageCallback(1000);
356+
357+
received_analog_output = std::get<double>(parsed_data_["standard_analog_output_1"]);
358+
received_standard_analog_output_mask = std::get<uint8_t>(parsed_data_["standard_analog_output_mask"]);
359+
received_standard_analog_output_type = std::get<uint8_t>(parsed_data_["standard_analog_output_type"]);
360+
361+
EXPECT_EQ(send_analog_output, received_analog_output);
362+
EXPECT_EQ(expected_standard_analog_output_mask, received_standard_analog_output_mask);
363+
EXPECT_EQ(expected_standard_analog_output_type, received_standard_analog_output_type);
364+
}
365+
366+
TEST_F(RTDEWriterTest, send_standard_analog_output_illegal_input_fails)
367+
{
368+
uint8_t pin = 0;
369+
double send_analog_output = 1;
370+
371+
// Pin should be either 0 or 1
295372
pin = 2;
296373
EXPECT_FALSE(writer_->sendStandardAnalogOutput(pin, send_analog_output));
297374

0 commit comments

Comments
 (0)