Primary Pipeline Calibration example
This example is very similar to the Primary Pipeline example. However, it uses a
specialized consumer that will analyze the calibration data sent from the robot instead of the
ShellConsumer.
Consumer setup
This example uses a specialized type of consumer that stores data about the received robot calibration.
26class CalibrationConsumer : public urcl::comm::IConsumer<urcl::primary_interface::PrimaryPackage>
27{
28public:
29 CalibrationConsumer() : calibrated_(0), have_received_data_(false)
30 {
31 }
32 virtual ~CalibrationConsumer() = default;
33
34 // This will consume any primary package
35 virtual bool consume(std::shared_ptr<urcl::primary_interface::PrimaryPackage> product)
36 {
37 // Try to cast the product to a KinematicsInfo package. If that succeeds, we handle the
38 // calibration information.
39 auto kin_info = std::dynamic_pointer_cast<urcl::primary_interface::KinematicsInfo>(product);
40 if (kin_info != nullptr)
41 {
42 URCL_LOG_INFO("%s", product->toString().c_str());
43 calibrated_ = kin_info->calibration_status_;
44 have_received_data_ = true;
45 }
46 return true;
47 }
48
49 bool isCalibrated() const
50 {
51 const uint32_t linearized = 2;
52 return calibrated_ == linearized;
53 }
54
55 bool calibrationStatusReceived()
56 {
57 return have_received_data_;
58 }
59
60private:
61 uint32_t calibrated_;
62 bool have_received_data_;
63};
Since the producer is reading every package from the primary interface, the consumer has to be able to consume any primary package.
Assemble the pipeline
The rest of the pipeline setup is the same as in the other pipeline example, just that we create a
CalibrationConsumer instead of a ShellConsumer:
91 // The calibration consumer will print the package contents to the shell
92 CalibrationConsumer calib_consumer;
93
94 // The notifer will be called at some points during connection setup / loss. This isn't fully
95 // implemented atm.
96 comm::INotifier notifier;
97
98 // Now that we have all components, we can create and start the pipeline to run it all.
99 comm::Pipeline<primary_interface::PrimaryPackage> calib_pipeline(prod, &calib_consumer, "Pipeline", notifier);
100 calib_pipeline.run();
Again, product handling will be happening in the background, so in the rest of the program we wait until the calibration consumer received and processed data and then print information about that:
104 while (!calib_consumer.calibrationStatusReceived())
105 {
106 std::this_thread::sleep_for(std::chrono::seconds(1));
107 }
108
109 if (calib_consumer.isCalibrated())
110 {
111 printf("The robot on IP: %s is calibrated.\n", robot_ip.c_str());
112 }
113 else
114 {
115 printf("The robot controller on IP: %s does not have a valid calibration.\n", robot_ip.c_str());
116 printf("Remeber to turn on the robot to get calibration stored on the robot!\n");
117 }
118
119 return 0;