Skip to content

Commit 3743443

Browse files
Fix Raster and RasterOnly Tasks
1 parent b10217b commit 3743443

File tree

12 files changed

+396
-19
lines changed

12 files changed

+396
-19
lines changed

tesseract_task_composer/README.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,18 @@ The task that is called if you want to abort everything
478478
config:
479479
conditional: false
480480
481+
Sync Task
482+
^^^^^^^^^
483+
484+
The task is used to create a syncronization point within a task graph
485+
486+
.. code-block:: yaml
487+
488+
SyncTask:
489+
class: SyncTaskFactory
490+
config:
491+
conditional: false
492+
481493
Remap Task
482494
^^^^^^^^^^
483495

tesseract_task_composer/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ add_library(
4343
src/nodes/error_task.cpp
4444
src/nodes/remap_task.cpp
4545
src/nodes/start_task.cpp
46+
src/nodes/sync_task.cpp
4647
src/test_suite/test_task.cpp)
4748
target_link_libraries(
4849
${PROJECT_NAME}_nodes
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @file sync_task.h
3+
*
4+
* @author Levi Armstrong
5+
* @date August 13, 2023
6+
* @version TODO
7+
* @bug No known bugs
8+
*
9+
* @copyright Copyright (c) 2023, Plectix Robotics
10+
*
11+
* @par License
12+
* Software License Agreement (Apache License)
13+
* @par
14+
* Licensed under the Apache License, Version 2.0 (the "License");
15+
* you may not use this file except in compliance with the License.
16+
* You may obtain a copy of the License at
17+
* http://www.apache.org/licenses/LICENSE-2.0
18+
* @par
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*/
25+
#ifndef TESSERACT_TASK_COMPOSER_SYNC_TASK_H
26+
#define TESSERACT_TASK_COMPOSER_SYNC_TASK_H
27+
28+
#include <tesseract_common/macros.h>
29+
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
30+
#include <boost/serialization/access.hpp>
31+
TESSERACT_COMMON_IGNORE_WARNINGS_POP
32+
33+
#include <tesseract_task_composer/core/task_composer_task.h>
34+
35+
namespace tesseract_planning
36+
{
37+
class TaskComposerPluginFactory;
38+
39+
/**
40+
* @brief This is used as a synchronization point in your task graph
41+
*
42+
* The actual synchronization is something that the executor will inherently do based on the graph structure but it
43+
* needs a actual task so you can connect all parallel tasks to. This way when it gets to this task the executor will
44+
* not proceed until all preceding tasks are finished.
45+
*
46+
* @note This task has no inputs or output and is not conditional
47+
*/
48+
class SyncTask : public TaskComposerTask
49+
{
50+
public:
51+
using Ptr = std::shared_ptr<SyncTask>;
52+
using ConstPtr = std::shared_ptr<const SyncTask>;
53+
using UPtr = std::unique_ptr<SyncTask>;
54+
using ConstUPtr = std::unique_ptr<const SyncTask>;
55+
56+
explicit SyncTask(std::string name = "SyncTask");
57+
explicit SyncTask(std::string name, const YAML::Node& config, const TaskComposerPluginFactory& plugin_factory);
58+
~SyncTask() override = default;
59+
60+
bool operator==(const SyncTask& rhs) const;
61+
bool operator!=(const SyncTask& rhs) const;
62+
63+
protected:
64+
friend struct tesseract_common::Serialization;
65+
friend class boost::serialization::access;
66+
template <class Archive>
67+
void serialize(Archive& ar, const unsigned int version); // NOLINT
68+
69+
TaskComposerNodeInfo::UPtr runImpl(TaskComposerInput& input,
70+
OptionalTaskComposerExecutor executor = std::nullopt) const override final;
71+
};
72+
73+
} // namespace tesseract_planning
74+
75+
#include <boost/serialization/export.hpp>
76+
BOOST_CLASS_EXPORT_KEY2(tesseract_planning::SyncTask, "SyncTask")
77+
78+
#endif // TESSERACT_TASK_COMPOSER_SYNC_TASK_H
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @file sync_task.cpp
3+
*
4+
* @author Levi Armstrong
5+
* @date August 13, 2023
6+
* @version TODO
7+
* @bug No known bugs
8+
*
9+
* @copyright Copyright (c) 2023, Plectix Robotics
10+
*
11+
* @par License
12+
* Software License Agreement (Apache License)
13+
* @par
14+
* Licensed under the Apache License, Version 2.0 (the "License");
15+
* you may not use this file except in compliance with the License.
16+
* You may obtain a copy of the License at
17+
* http://www.apache.org/licenses/LICENSE-2.0
18+
* @par
19+
* Unless required by applicable law or agreed to in writing, software
20+
* distributed under the License is distributed on an "AS IS" BASIS,
21+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
* See the License for the specific language governing permissions and
23+
* limitations under the License.
24+
*/
25+
26+
#include <tesseract_common/macros.h>
27+
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
28+
#include <console_bridge/console.h>
29+
#include <boost/serialization/string.hpp>
30+
TESSERACT_COMMON_IGNORE_WARNINGS_POP
31+
32+
#include <tesseract_task_composer/core/nodes/sync_task.h>
33+
34+
namespace tesseract_planning
35+
{
36+
SyncTask::SyncTask(std::string name) : TaskComposerTask(std::move(name), false) {}
37+
SyncTask::SyncTask(std::string name, const YAML::Node& config, const TaskComposerPluginFactory& /*plugin_factory*/)
38+
: TaskComposerTask(std::move(name), config)
39+
{
40+
if (conditional_)
41+
throw std::runtime_error("SyncTask, config is_conditional should not be true");
42+
43+
if (!input_keys_.empty())
44+
throw std::runtime_error("SyncTask, config does not support 'inputs' entry");
45+
46+
if (!output_keys_.empty())
47+
throw std::runtime_error("SyncTask, config does not support 'outputs' entry");
48+
}
49+
TaskComposerNodeInfo::UPtr SyncTask::runImpl(TaskComposerInput& /*input*/,
50+
OptionalTaskComposerExecutor /*executor*/) const
51+
{
52+
auto info = std::make_unique<TaskComposerNodeInfo>(*this);
53+
info->color = "green";
54+
info->message = "Successful";
55+
info->return_value = 1;
56+
return info;
57+
}
58+
59+
bool SyncTask::operator==(const SyncTask& rhs) const { return (TaskComposerTask::operator==(rhs)); }
60+
bool SyncTask::operator!=(const SyncTask& rhs) const { return !operator==(rhs); }
61+
62+
template <class Archive>
63+
void SyncTask::serialize(Archive& ar, const unsigned int /*version*/)
64+
{
65+
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(TaskComposerTask);
66+
}
67+
68+
} // namespace tesseract_planning
69+
70+
#include <tesseract_common/serialization.h>
71+
TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_planning::SyncTask)
72+
BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_planning::SyncTask)

tesseract_task_composer/core/src/task_composer_pipeline.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ int TaskComposerPipeline::run(TaskComposerInput& input, OptionalTaskComposerExec
5353
if (input.isAborted())
5454
{
5555
auto info = std::make_unique<TaskComposerNodeInfo>(*this);
56+
info->input_keys = input_keys_;
57+
info->output_keys = output_keys_;
5658
info->return_value = 0;
5759
info->color = "white";
5860
info->message = "Aborted";
@@ -76,6 +78,8 @@ int TaskComposerPipeline::run(TaskComposerInput& input, OptionalTaskComposerExec
7678
results->return_value = 0;
7779
}
7880
timer.stop();
81+
results->input_keys = input_keys_;
82+
results->output_keys = output_keys_;
7983
results->elapsed_time = timer.elapsedSeconds();
8084

8185
int value = results->return_value;
@@ -114,6 +118,8 @@ TaskComposerNodeInfo::UPtr TaskComposerPipeline::runImpl(TaskComposerInput& inpu
114118
{
115119
timer.stop();
116120
auto info = std::make_unique<TaskComposerNodeInfo>(*this);
121+
info->input_keys = input_keys_;
122+
info->output_keys = output_keys_;
117123
info->return_value = static_cast<int>(i);
118124
info->color = node_info->color;
119125
info->message = node_info->message;

tesseract_task_composer/core/src/task_composer_task.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ int TaskComposerTask::run(TaskComposerInput& input, OptionalTaskComposerExecutor
5151
if (input.isAborted())
5252
{
5353
auto info = std::make_unique<TaskComposerNodeInfo>(*this);
54+
info->input_keys = input_keys_;
55+
info->output_keys = output_keys_;
5456
info->return_value = 0;
5557
info->color = "white";
5658
info->message = "Aborted";
@@ -74,6 +76,8 @@ int TaskComposerTask::run(TaskComposerInput& input, OptionalTaskComposerExecutor
7476
results->return_value = 0;
7577
}
7678
timer.stop();
79+
results->input_keys = input_keys_;
80+
results->output_keys = output_keys_;
7781
results->elapsed_time = timer.elapsedSeconds();
7882

7983
int value = results->return_value;

tesseract_task_composer/core/src/task_composer_task_plugin_factory.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <tesseract_task_composer/core/nodes/error_task.h>
3535
#include <tesseract_task_composer/core/nodes/remap_task.h>
3636
#include <tesseract_task_composer/core/nodes/start_task.h>
37+
#include <tesseract_task_composer/core/nodes/sync_task.h>
3738
#include <tesseract_task_composer/core/test_suite/test_task.h>
3839

3940
namespace tesseract_planning
@@ -43,6 +44,7 @@ using DoneTaskFactory = TaskComposerTaskFactory<DoneTask>;
4344
using ErrorTaskFactory = TaskComposerTaskFactory<ErrorTask>;
4445
using RemapTaskFactory = TaskComposerTaskFactory<RemapTask>;
4546
using StartTaskFactory = TaskComposerTaskFactory<StartTask>;
47+
using SyncTaskFactory = TaskComposerTaskFactory<SyncTask>;
4648
using GraphTaskFactory = TaskComposerTaskFactory<TaskComposerGraph>;
4749
using PipelineTaskFactory = TaskComposerTaskFactory<TaskComposerPipeline>;
4850

@@ -68,6 +70,8 @@ TESSERACT_ADD_TASK_COMPOSER_NODE_PLUGIN(tesseract_planning::RemapTaskFactory, Re
6870
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
6971
TESSERACT_ADD_TASK_COMPOSER_NODE_PLUGIN(tesseract_planning::StartTaskFactory, StartTaskFactory)
7072
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
73+
TESSERACT_ADD_TASK_COMPOSER_NODE_PLUGIN(tesseract_planning::SyncTaskFactory, SyncTaskFactory)
74+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
7175
TESSERACT_ADD_TASK_COMPOSER_NODE_PLUGIN(tesseract_planning::GraphTaskFactory, GraphTaskFactory)
7276
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
7377
TESSERACT_ADD_TASK_COMPOSER_NODE_PLUGIN(tesseract_planning::PipelineTaskFactory, PipelineTaskFactory)

tesseract_task_composer/planning/src/nodes/raster_motion_task.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ TaskComposerNodeInfo::UPtr RasterMotionTask::runImpl(TaskComposerInput& input,
326326

327327
tesseract_common::ManipulatorInfo program_manip_info = program.getManipulatorInfo().getCombined(problem.manip_info);
328328

329+
// Start Task
329330
auto start_task = std::make_unique<StartTask>();
330331
auto start_uuid = task_graph.addNode(std::move(start_task));
331332

@@ -352,6 +353,7 @@ TaskComposerNodeInfo::UPtr RasterMotionTask::runImpl(TaskComposerInput& input,
352353

353354
const std::string task_name = "Raster #" + std::to_string(raster_idx + 1) + ": " + raster_input.getDescription();
354355
auto raster_results = raster_task_factory_(task_name, raster_idx + 1);
356+
raster_results.node->setConditional(false);
355357
auto raster_uuid = task_graph.addNode(std::move(raster_results.node));
356358
raster_tasks.emplace_back(raster_uuid, std::make_pair(raster_results.input_key, raster_results.output_key));
357359
input.data_storage.setData(raster_results.input_key, raster_input);
@@ -384,19 +386,23 @@ TaskComposerNodeInfo::UPtr RasterMotionTask::runImpl(TaskComposerInput& input,
384386
const std::string task_name =
385387
"Transition #" + std::to_string(transition_idx + 1) + ": " + transition_input.getDescription();
386388
auto transition_results = transition_task_factory_(task_name, transition_idx + 1);
389+
transition_results.node->setConditional(false);
387390
auto transition_uuid = task_graph.addNode(std::move(transition_results.node));
388391
transition_keys.emplace_back(std::make_pair(transition_results.input_key, transition_results.output_key));
389392

390393
const auto& prev = raster_tasks[transition_idx];
391394
const auto& next = raster_tasks[transition_idx + 1];
392395
const auto& prev_output = prev.second.second;
393396
const auto& next_output = next.second.second;
394-
auto transition_mux_task = std::make_unique<UpdateStartAndEndStateTask>(
395-
"UpdateStartAndEndStateTask", prev_output, next_output, transition_results.input_key, false);
396-
std::string transition_mux_key = transition_mux_task->getUUIDString();
397+
auto transition_mux_task = std::make_unique<UpdateStartAndEndStateTask>("UpdateStartAndEndStateTask",
398+
transition_results.input_key,
399+
prev_output,
400+
next_output,
401+
transition_results.output_key,
402+
false);
397403
auto transition_mux_uuid = task_graph.addNode(std::move(transition_mux_task));
398404

399-
input.data_storage.setData(transition_mux_key, transition_input);
405+
input.data_storage.setData(transition_results.input_key, transition_input);
400406

401407
task_graph.addEdges(transition_mux_uuid, { transition_uuid });
402408
task_graph.addEdges(prev.first, { transition_mux_uuid });
@@ -409,23 +415,24 @@ TaskComposerNodeInfo::UPtr RasterMotionTask::runImpl(TaskComposerInput& input,
409415
auto from_start_input = program[0].template as<CompositeInstruction>();
410416
from_start_input.setManipulatorInfo(from_start_input.getManipulatorInfo().getCombined(program_manip_info));
411417

412-
auto from_start_results = freespace_task_factory_("From Start: " + from_start_input.getDescription(), 1);
418+
auto from_start_results = freespace_task_factory_("From Start: " + from_start_input.getDescription(), 0);
413419
auto from_start_pipeline_uuid = task_graph.addNode(std::move(from_start_results.node));
414420

415421
const auto& first_raster_output_key = raster_tasks[0].second.second;
416-
auto update_end_state_task = std::make_unique<UpdateEndStateTask>(
417-
"UpdateEndStateTask", first_raster_output_key, from_start_results.input_key, false);
418-
std::string update_end_state_key = update_end_state_task->getUUIDString();
422+
auto update_end_state_task = std::make_unique<UpdateEndStateTask>("UpdateEndStateTask",
423+
from_start_results.input_key,
424+
first_raster_output_key,
425+
from_start_results.output_key,
426+
false);
419427
auto update_end_state_uuid = task_graph.addNode(std::move(update_end_state_task));
420428

421-
input.data_storage.setData(update_end_state_key, from_start_input);
429+
input.data_storage.setData(from_start_results.input_key, from_start_input);
422430

423431
task_graph.addEdges(update_end_state_uuid, { from_start_pipeline_uuid });
424432
task_graph.addEdges(raster_tasks[0].first, { update_end_state_uuid });
425433

426434
// Plan to_end - preceded by the last raster
427435
auto to_end_input = program.back().template as<CompositeInstruction>();
428-
429436
to_end_input.setManipulatorInfo(to_end_input.getManipulatorInfo().getCombined(program_manip_info));
430437

431438
// Get Start Plan Instruction
@@ -436,16 +443,15 @@ TaskComposerNodeInfo::UPtr RasterMotionTask::runImpl(TaskComposerInput& input,
436443
assert(li != nullptr);
437444
to_end_input.insertMoveInstruction(to_end_input.begin(), *li);
438445

439-
auto to_end_results = freespace_task_factory_("To End: " + to_end_input.getDescription(), 2);
446+
auto to_end_results = freespace_task_factory_("To End: " + to_end_input.getDescription(), program.size());
440447
auto to_end_pipeline_uuid = task_graph.addNode(std::move(to_end_results.node));
441448

442449
const auto& last_raster_output_key = raster_tasks.back().second.second;
443450
auto update_start_state_task = std::make_unique<UpdateStartStateTask>(
444-
"UpdateStartStateTask", last_raster_output_key, to_end_results.input_key, false);
445-
std::string update_start_state_key = update_start_state_task->getUUIDString();
451+
"UpdateStartStateTask", to_end_results.input_key, last_raster_output_key, to_end_results.output_key, false);
446452
auto update_start_state_uuid = task_graph.addNode(std::move(update_start_state_task));
447453

448-
input.data_storage.setData(update_start_state_key, to_end_input);
454+
input.data_storage.setData(to_end_results.input_key, to_end_input);
449455

450456
task_graph.addEdges(update_start_state_uuid, { to_end_pipeline_uuid });
451457
task_graph.addEdges(raster_tasks.back().first, { update_start_state_uuid });

tesseract_task_composer/planning/src/nodes/raster_only_motion_task.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ TaskComposerNodeInfo::UPtr RasterOnlyMotionTask::runImpl(TaskComposerInput& inpu
276276

277277
tesseract_common::ManipulatorInfo program_manip_info = program.getManipulatorInfo().getCombined(problem.manip_info);
278278

279+
// Start Task
279280
auto start_task = std::make_unique<StartTask>();
280281
auto start_uuid = task_graph.addNode(std::move(start_task));
281282

@@ -305,6 +306,7 @@ TaskComposerNodeInfo::UPtr RasterOnlyMotionTask::runImpl(TaskComposerInput& inpu
305306

306307
const std::string task_name = "Raster #" + std::to_string(raster_idx + 1) + ": " + raster_input.getDescription();
307308
auto raster_results = raster_task_factory_(task_name, raster_idx + 1);
309+
raster_results.node->setConditional(false);
308310
auto raster_uuid = task_graph.addNode(std::move(raster_results.node));
309311
raster_tasks.emplace_back(raster_uuid, std::make_pair(raster_results.input_key, raster_results.output_key));
310312
input.data_storage.setData(raster_results.input_key, raster_input);
@@ -336,19 +338,23 @@ TaskComposerNodeInfo::UPtr RasterOnlyMotionTask::runImpl(TaskComposerInput& inpu
336338
const std::string task_name =
337339
"Transition #" + std::to_string(transition_idx + 1) + ": " + transition_input.getDescription();
338340
auto transition_results = transition_task_factory_(task_name, transition_idx + 1);
341+
transition_results.node->setConditional(false);
339342
auto transition_uuid = task_graph.addNode(std::move(transition_results.node));
340343
transition_keys.emplace_back(std::make_pair(transition_results.input_key, transition_results.output_key));
341344

342345
const auto& prev = raster_tasks[transition_idx];
343346
const auto& next = raster_tasks[transition_idx + 1];
344347
const auto& prev_output = prev.second.second;
345348
const auto& next_output = next.second.second;
346-
auto transition_mux_task = std::make_unique<UpdateStartAndEndStateTask>(
347-
"UpdateStartAndEndStateTask", prev_output, next_output, transition_results.input_key, false);
348-
std::string transition_mux_key = transition_mux_task->getUUIDString();
349+
auto transition_mux_task = std::make_unique<UpdateStartAndEndStateTask>("UpdateStartAndEndStateTask",
350+
transition_results.input_key,
351+
prev_output,
352+
next_output,
353+
transition_results.output_key,
354+
false);
349355
auto transition_mux_uuid = task_graph.addNode(std::move(transition_mux_task));
350356

351-
input.data_storage.setData(transition_mux_key, transition_input);
357+
input.data_storage.setData(transition_results.input_key, transition_input);
352358

353359
task_graph.addEdges(transition_mux_uuid, { transition_uuid });
354360
task_graph.addEdges(prev.first, { transition_mux_uuid });

tesseract_task_composer/taskflow/src/taskflow_task_composer_executor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ TaskflowTaskComposerExecutor::convertToTaskflow(const TaskComposerGraph& task_gr
139139
// Must add a Node Info object for the graph
140140
auto info = std::make_unique<TaskComposerNodeInfo>(task_graph);
141141
info->color = "green";
142+
info->input_keys = task_graph.getInputKeys();
143+
info->output_keys = task_graph.getOutputKeys();
142144
task_input.task_infos.addInfo(std::move(info));
143145

144146
// Generate process tasks for each node

0 commit comments

Comments
 (0)