Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 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
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <boost/format.hpp>
#include <boost/optional.hpp>
#include <boost/program_options.hpp>
#include <boost/variant/get.hpp>

#include <viam/sdk/robot/client.hpp>
#include <viam/sdk/services/mlmodel.hpp>
Expand Down
31 changes: 16 additions & 15 deletions src/viam/examples/modules/complex/base/impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,23 @@ using namespace viam::sdk;

std::string find_motor(ResourceConfig cfg, std::string motor_name) {
auto base_name = cfg.name();
auto motor = cfg.attributes()->find(motor_name);
if (motor == cfg.attributes()->end()) {
auto motor = cfg.attributes().find(motor_name);
if (motor == cfg.attributes().end()) {
std::ostringstream buffer;
buffer << base_name << ": Required parameter `" << motor_name
<< "` not found in configuration";
throw std::invalid_argument(buffer.str());
}
const auto* const motor_string = motor->second->get<std::string>();
if (!motor_string || motor_string->empty()) {
std::ostringstream buffer;
buffer << base_name << ": Required non-empty string parameter `" << motor_name
<< "` is either not a string "
"or is an empty string";
throw std::invalid_argument(buffer.str());
const ProtoValue& motor_val = motor->second;
if (motor_val.is_a<std::string>() && !motor_val.get_unchecked<std::string>().empty()) {
return motor_val.get_unchecked<std::string>();
}
return *motor_string;

std::ostringstream buffer;
buffer << base_name << ": Required non-empty string parameter `" << motor_name
<< "` is either not a string "
"or is an empty string";
throw std::invalid_argument(buffer.str());
}

void MyBase::reconfigure(const Dependencies& deps, const ResourceConfig& cfg) {
Expand Down Expand Up @@ -64,7 +65,7 @@ bool MyBase::is_moving() {
return left_->is_moving() || right_->is_moving();
}

void MyBase::stop(const AttributeMap& extra) {
void MyBase::stop(const ProtoStruct& extra) {
std::string err_message;
bool throw_err = false;

Expand All @@ -89,7 +90,7 @@ void MyBase::stop(const AttributeMap& extra) {
}
}

void MyBase::set_power(const Vector3& linear, const Vector3& angular, const AttributeMap& extra) {
void MyBase::set_power(const Vector3& linear, const Vector3& angular, const ProtoStruct& extra) {
// Stop the base if absolute value of linear and angular velocity is less
// than 0.01.
if (abs(linear.y()) < 0.01 && abs(angular.z()) < 0.01) {
Expand All @@ -104,20 +105,20 @@ void MyBase::set_power(const Vector3& linear, const Vector3& angular, const Attr
right_->set_power(((linear.y() + angular.z()) / sum), extra);
}

AttributeMap MyBase::do_command(const AttributeMap& command) {
ProtoStruct MyBase::do_command(const ProtoStruct& command) {
std::cout << "Received DoCommand request for MyBase " << Resource::name() << std::endl;
return command;
}

std::vector<GeometryConfig> MyBase::get_geometries(const AttributeMap& extra) {
std::vector<GeometryConfig> MyBase::get_geometries(const ProtoStruct& extra) {
auto left_geometries = left_->get_geometries(extra);
auto right_geometries = right_->get_geometries(extra);
std::vector<GeometryConfig> geometries(left_geometries);
geometries.insert(geometries.end(), right_geometries.begin(), right_geometries.end());
return geometries;
}

Base::properties MyBase::get_properties(const AttributeMap& extra) {
Base::properties MyBase::get_properties(const ProtoStruct& extra) {
// Return fake properties.
return {2, 4, 8};
}
16 changes: 8 additions & 8 deletions src/viam/examples/modules/complex/base/impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ class MyBase : public Base, public Reconfigurable {
static std::vector<std::string> validate(ResourceConfig cfg);

bool is_moving() override;
void stop(const AttributeMap& extra) override;
void stop(const ProtoStruct& extra) override;
void set_power(const Vector3& linear,
const Vector3& angular,
const AttributeMap& extra) override;
const ProtoStruct& extra) override;

AttributeMap do_command(const AttributeMap& command) override;
std::vector<GeometryConfig> get_geometries(const AttributeMap& extra) override;
Base::properties get_properties(const AttributeMap& extra) override;
ProtoStruct do_command(const ProtoStruct& command) override;
std::vector<GeometryConfig> get_geometries(const ProtoStruct& extra) override;
Base::properties get_properties(const ProtoStruct& extra) override;

void move_straight(int64_t distance_mm, double mm_per_sec, const AttributeMap& extra) override {
void move_straight(int64_t distance_mm, double mm_per_sec, const ProtoStruct& extra) override {
throw std::runtime_error("move_straight unimplemented");
}
void spin(double angle_deg, double degs_per_sec, const AttributeMap& extra) override {
void spin(double angle_deg, double degs_per_sec, const ProtoStruct& extra) override {
throw std::runtime_error("spin unimplemented");
}
void set_velocity(const Vector3& linear,
const Vector3& angular,
const AttributeMap& extra) override {
const ProtoStruct& extra) override {
throw std::runtime_error("set_velocity unimplemented");
}

Expand Down
19 changes: 10 additions & 9 deletions src/viam/examples/modules/complex/gizmo/impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,21 @@ using namespace viam::sdk;

std::string find_arg1(ResourceConfig cfg) {
auto gizmo_name = cfg.name();
auto arg1 = cfg.attributes()->find("arg1");
if (arg1 == cfg.attributes()->end()) {
auto arg1 = cfg.attributes().find("arg1");
if (arg1 == cfg.attributes().end()) {
std::ostringstream buffer;
buffer << gizmo_name << ": Required parameter `arg1` not found in configuration";
throw std::invalid_argument(buffer.str());
}
const auto* const arg1_string = arg1->second->get<std::string>();
if (!arg1_string || arg1_string->empty()) {
std::ostringstream buffer;
buffer << gizmo_name << ": Required non-empty string parameter `arg1`"
<< "` is either not a string or is an empty string";
throw std::invalid_argument(buffer.str());

const ProtoValue& arg1_val = arg1->second;
if (arg1_val.is_a<std::string>() && !arg1_val.get_unchecked<std::string>().empty()) {
return arg1_val.get_unchecked<std::string>();
Comment on lines +25 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is aw this patern in base/impl.cpp above too, and sort of shrugged it off, but, it now that I see it twice it feels a little chatty. Is ProtoValue missing some affordance for this sort of pattern? Would std::optional (or a polyfill for it) simplify things? Should ProtoValue have some monadic APIs (and_then, transform, or_else), etc?

This, btw, is what motivated my slack ping about polyfills / C++17 since I feel like optional probably plays a role in such an API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it was bugging me as well that this kept coming up, being that it's the one scenario where we end up more verbose than the previous code.

I personally am a big fan of optionals and monadic operations but in this case we might be better off with a pointer API. For example Boost.JSON has these, and we could spell them as try_get<T> or similar, since if_bool strikes me as a bit idiosyncratic

In any case definitely in agreement that this would be nice to simplify, will create a ticket.

}
return *arg1_string;
std::ostringstream buffer;
buffer << gizmo_name << ": Required non-empty string parameter `arg1`"
<< "` is either not a string or is an empty string";
throw std::invalid_argument(buffer.str());
}

void MyGizmo::reconfigure(const Dependencies& deps, const ResourceConfig& cfg) {
Expand Down
2 changes: 1 addition & 1 deletion src/viam/examples/modules/complex/gizmo/impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <vector>

#include <viam/sdk/common/proto_type.hpp>
#include <viam/sdk/common/proto_value.hpp>
#include <viam/sdk/resource/reconfigurable.hpp>

#include "api.hpp"
Expand Down
11 changes: 4 additions & 7 deletions src/viam/examples/modules/complex/summation/impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@ using namespace viam::sdk;
// Returns value of "subtract" in cfg.attributes() or `false` if subtract is not
// in attributes or is not a boolean value.
bool find_subtract(ResourceConfig cfg) {
auto subtract = cfg.attributes()->find("subtract");
if (subtract == cfg.attributes()->end()) {
auto subtract = cfg.attributes().find("subtract");
if (subtract == cfg.attributes().end()) {
return false;
}
const bool* const subtract_bool = subtract->second->get<bool>();
if (!subtract_bool) {
return false;
}
return *subtract_bool;

return subtract->second.is_a<bool>() && subtract->second.get_unchecked<bool>();
}

void MySummation::reconfigure(const Dependencies& deps, const ResourceConfig& cfg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <viam/api/common/v1/common.pb.h>

#include <viam/sdk/common/proto_type.hpp>
#include <viam/sdk/common/proto_value.hpp>
#include <viam/sdk/tests/test_utils.hpp>

#include "gizmo.grpc.pb.h"
Expand Down
20 changes: 4 additions & 16 deletions src/viam/examples/modules/simple/client.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <memory>
#include <string>

#include <viam/sdk/common/proto_type.hpp>
#include <viam/sdk/common/proto_value.hpp>
#include <viam/sdk/robot/client.hpp>
#include <viam/sdk/rpc/dial.hpp>
#include <viam/sdk/services/generic.hpp>
Expand Down Expand Up @@ -39,22 +39,10 @@ int main() {
return EXIT_FAILURE;
}

auto proto_ptr = std::make_shared<ProtoType>(std::string("world"));
AttributeMap command =
std::make_shared<std::unordered_map<std::string, std::shared_ptr<ProtoType>>>();
command->insert({{std::string("hello"), proto_ptr}});
ProtoStruct command{{"hello", "world"}};
ProtoStruct resp = printer->do_command(command);

auto resp = printer->do_command(command);

if (!resp) {
std::cerr << "Failed to get a response from 'printer1'\n";
return EXIT_FAILURE;
}

std::shared_ptr<ProtoType> expected = command->at(std::string("hello"));
std::shared_ptr<ProtoType> result = resp->at(std::string("hello"));

if (!(*expected == *result)) {
if (command != resp) {
std::cerr << "Got unexpected result from 'printer1'\n";
return EXIT_FAILURE;
}
Expand Down
25 changes: 14 additions & 11 deletions src/viam/examples/modules/simple/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <viam/api/service/generic/v1/generic.grpc.pb.h>

#include <viam/sdk/common/exception.hpp>
#include <viam/sdk/common/proto_value.hpp>
#include <viam/sdk/config/resource.hpp>
#include <viam/sdk/module/module.hpp>
#include <viam/sdk/module/service.hpp>
Expand Down Expand Up @@ -44,29 +45,31 @@ class Printer : public GenericService, public Reconfigurable {
std::cout << "Printer " << Resource::name() << " will print " << to_print_ << std::endl;
}

AttributeMap do_command(const AttributeMap& command) {
ProtoStruct do_command(const ProtoStruct& command) {
std::cout << "Received DoCommand request for Printer " << Resource::name() << std::endl;
std::cout << "Printer " << Resource::name() << " has printed " << to_print_ << std::endl;
return command;
}

static std::string find_to_print(ResourceConfig cfg) {
auto& printer_name = cfg.name();
auto to_print = cfg.attributes()->find("to_print");
if (to_print == cfg.attributes()->end()) {
auto to_print = cfg.attributes().find("to_print");
if (to_print == cfg.attributes().end()) {
std::ostringstream buffer;
buffer << printer_name << ": Required parameter `to_print` not found in configuration";
throw std::invalid_argument(buffer.str());
}
const auto* const to_print_string = to_print->second->get<std::string>();
if (!to_print_string || to_print_string->empty()) {
std::ostringstream buffer;
buffer << printer_name
<< ": Required non-empty string parameter `to_print` is either not a string "
"or is an empty string";
throw std::invalid_argument(buffer.str());
const ProtoValue& to_print_val = to_print->second;
if (to_print_val.is_a<std::string>() &&
!to_print_val.get_unchecked<std::string>().empty()) {
return to_print_val.get_unchecked<std::string>();
}
return *to_print_string;

std::ostringstream buffer;
buffer << printer_name
<< ": Required non-empty string parameter `to_print` is either not a string "
"or is an empty string";
throw std::invalid_argument(buffer.str());
}

private:
Expand Down
Loading