coordinator.cpp 9.79 KB
Newer Older
beuchatp's avatar
beuchatp committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//    Copyright (C) 2019, ETH Zurich, D-ITET, Paul Beuchat
//
//    This file is part of D-FaLL-System.
//
//    D-FaLL-System is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    D-FaLL-System is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with D-FaLL-System.  If not, see <http://www.gnu.org/licenses/>.
//
//
//    ----------------------------------------------------------------------------------
//    DDDD        FFFFF        L     L           SSSS  Y   Y   SSSS  TTTTT  EEEEE  M   M
//    D   D       F      aaa   L     L          S       Y Y   S        T    E      MM MM
//    D   D  ---  FFFF  a   a  L     L     ---   SSS     Y     SSS     T    EEE    M M M
//    D   D       F     a  aa  L     L              S    Y        S    T    E      M   M
//    DDDD        F      aa a  LLLL  LLLL       SSSS     Y    SSSS     T    EEEEE  M   M
//
//
//    DESCRIPTION:
//    The coordinator part of the Flying Agent GUI that allows multiple
//    flying agents to be controller from one place, and keeps track
//    of which subset of flying agents to control.
//
//    ----------------------------------------------------------------------------------





38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "coordinator.h"
#include "ui_coordinator.h"

Coordinator::Coordinator(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Coordinator)
{
    ui->setupUi(this);

    ui->verticalLayout_for_coordinatedAgentsScrollArea->setAlignment(Qt::AlignTop);
}

Coordinator::~Coordinator()
{
    delete ui;
}

void Coordinator::on_refresh_button_clicked()
{
57
58
    // DELETE ALL EXISTING ROWS
    remove_all_entries_from_vector_of_coordinatorRows();
59

60
61
62
    // Get the state of the "coordinate all" is check box
    bool shouldCoordinateAll = ui->coordinate_all_checkBox->isChecked();

63

64
65
#ifdef CATKIN_MAKE
    // USE A REGULAR EXPRESSION TO IDENTIFY NODES THAT EXIST
66
    // > The regular expression we use is: \/agent(\d\d\d)\/FlyingAgentClient
67
68
69
70
71
72
73
74
75
76
77
78
    //   with the different that the escaped character is \\ instead of \ only

    // GET A "V_string" OF ALL THE NODES CURRENTLY IN EXISTENCE
    ros::V_string v_str;
    ros::master::getNodes(v_str);

    // ITERATE THROUGH THIS "V_string" OF ALL NODE IN EXISTENCE
    for(int i = 0; i < v_str.size(); i++)
    {
        // TEST THE NAME OF THIS NODE AGAINST THE REGULAR EXPRESSION
        std::string s = v_str[i];
        std::smatch m;
79
        std::regex e ("\\/agent(\\d\\d\\d)\\/FlyingAgentClient");
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

        if(std::regex_search(s, m, e))
        {
            // GET THE MATCHED PART OF THE NODE NAME INTO A LOCAL VARIABLE
            // > Note: we use m[1] because we are interested ONLY in the first match
            // > Thus "found_string" should the the agentID, as a string with zero padding
            std::string found_string = m[1].str();


            // LET THE USER KNOW THAT WE FOUND A MATCH
            ROS_INFO_STREAM("[Coordinator Row GUI] Found an agent with ID = " << found_string.c_str() );
            
            // CONVERT THE STRING TO AN INTEGER
            int this_agentID = stoi(found_string);

            // ADD A ROW TO THE COORDINATOR FOR THE AGENT WITH THIS ID FOUND
            CoordinatorRow *temp_coordinatorRow = new CoordinatorRow(this,this_agentID);

            // Check the box if "coordinate all" is checked
99
            temp_coordinatorRow->setShouldCoordinate(shouldCoordinateAll);
100

101
102
103
104
105
106
107
            // Connect the "should coordinate value changed" signal to
            // the respective slot
            QObject::connect(
                    temp_coordinatorRow , &CoordinatorRow::shouldCoordinateThisAgentValueChanged ,
                    this , &Coordinator::setShouldCoordinateThisAgent
                    );

108
109
            // Add to the vector of coordinator rows
            vector_of_coordinatorRows.append(temp_coordinatorRow);
110
111
            vector_of_shouldCoordinate_perRow.append(shouldCoordinateAll);
            vector_of_agentID_perRow.append(this_agentID);
112
113
114
115
116
117
118
119

            ui->coordinated_agents_scrollAreaWidgetContents->layout()->addWidget(temp_coordinatorRow);
        }
    }
#else


    for ( int i_agent = 1 ; i_agent < 9 ; i_agent++ )
120
121
122
123
124
125
    {
        //ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout);

        CoordinatorRow *temp_coordinatorRow = new CoordinatorRow(this,i_agent);

        // Check the box if "coordinate all" is checked
126
127
128
129
130
131
132
133
        temp_coordinatorRow->setShouldCoordinate(shouldCoordinateAll);

        // Connect the "should coordinate value changed" signal to
        // the respective slot
        QObject::connect(
                temp_coordinatorRow , &CoordinatorRow::shouldCoordinateThisAgentValueChanged ,
                this , &Coordinator::setShouldCoordinateThisAgent
                );
134
135
136

        // Add to the vector of coordinator rows
        vector_of_coordinatorRows.append(temp_coordinatorRow);
137
138
        vector_of_shouldCoordinate_perRow.append(shouldCoordinateAll);
        vector_of_agentID_perRow.append(i_agent);
139
140
141

        ui->coordinated_agents_scrollAreaWidgetContents->layout()->addWidget(temp_coordinatorRow);
    }
142
#endif
143

144
145
    // Send out a signal with the current IDs to coordinate
    emit_signal_with_agentIDs_toCoordinate();
146
147
148
149
    
    // Call the function that applies this level
    // of detail to all the entries
    apply_level_of_detail_to_all_entries(level_of_detail_to_display);
150
151
}

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

void Coordinator::on_toggle_details_button_clicked()
{
    // Toggle the level of detail to display
    switch (level_of_detail_to_display)
    {
    case 0:
    {
        level_of_detail_to_display = 1;
        break;
    }
    case 1:
    {
        level_of_detail_to_display = 0;
        break;
    }
    default:
    {
        level_of_detail_to_display = 0;
        break;
    }
    }
    // Call the function that applies this level
    // of detail to all the entries
    apply_level_of_detail_to_all_entries(level_of_detail_to_display);
}

179
180
void Coordinator::on_delete_button_clicked()
{
181
182
    // Call the function that performs the task requested
    remove_all_entries_from_vector_of_coordinatorRows();
183
184
185

    // Send out a signal with the current IDs to coordinate
    emit_signal_with_agentIDs_toCoordinate();
186
}
187

188
189
190
void Coordinator::remove_all_entries_from_vector_of_coordinatorRows()
{
    // Iterate through and delete all entries
191
192
193
    foreach ( CoordinatorRow* temp_coordinatorRow, vector_of_coordinatorRows) {
        delete( temp_coordinatorRow );
    }
194
    // Clear the vector
195
    vector_of_coordinatorRows.clear();
196
197
    vector_of_shouldCoordinate_perRow.clear();
    vector_of_agentID_perRow.clear();
198
199
}

200
201
202
203
204
205
206
207
208
void Coordinator::apply_level_of_detail_to_all_entries(int level)
{
    // Apply this to all the rows
    for ( int irow = 0 ; irow < vector_of_coordinatorRows.length() ; irow++ )
    {
        vector_of_coordinatorRows[irow]->setLevelOfDetailToDisplay( level );
    }
}

209
210
211
212
213
214
215
216
217
void Coordinator::on_coordinate_all_checkBox_clicked()
{
    // Get the state of the "coordinate all" is check box
    bool shouldCoordinateAll = ui->coordinate_all_checkBox->isChecked();

    // Apply this to all the rows
    for ( int irow = 0 ; irow < vector_of_coordinatorRows.length() ; irow++ )
    {
        vector_of_coordinatorRows[irow]->setShouldCoordinate( shouldCoordinateAll );
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
        vector_of_shouldCoordinate_perRow[irow] = shouldCoordinateAll;
    }

    // Send out a signal with the current IDs to coordinate
    emit_signal_with_agentIDs_toCoordinate();
}


void Coordinator::setShouldCoordinateThisAgent(int agentID , bool shouldCoordinate)
{
    // Find the row with the matching ID, and update the "shouldCoordinate" vector
    for ( int irow = 0 ; irow < vector_of_agentID_perRow.length() ; irow++ )
    {
        if (vector_of_agentID_perRow[irow] == agentID)
        {
            vector_of_shouldCoordinate_perRow[irow] = shouldCoordinate;
            break;
        }
    }

    // Update the "Coordinate All Check Box" as appropriate
    bool shouldCoordinateAll = true;
    if (!shouldCoordinate)
    {
        shouldCoordinateAll = false;
243
    }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    else
    {
        for ( int irow = 0 ; irow < vector_of_shouldCoordinate_perRow.length() ; irow++ )
        {
            if (!(vector_of_shouldCoordinate_perRow[irow]))
            {
                shouldCoordinateAll = false;
                break;
            }
        }
    }
    ui->coordinate_all_checkBox->setChecked(shouldCoordinateAll);

    // Send out a signal with the current IDs to coordinate
    emit_signal_with_agentIDs_toCoordinate();
}

void Coordinator::emit_signal_with_agentIDs_toCoordinate()
{
    // Initilise a boolean for whether to coordinate all
    bool shouldCoordinateAll = true;
    // Send out a signal with the current IDs to coordinate
    QVector<int> agentIDsToCoordinate;
    for ( int irow = 0 ; irow < vector_of_shouldCoordinate_perRow.length() ; irow++ )
    {
        if (vector_of_shouldCoordinate_perRow[irow])
        {
            agentIDsToCoordinate.append(vector_of_agentID_perRow[irow]);
        }
        else
        {
            shouldCoordinateAll = false;
        }
    }
    emit agentIDsToCoordinateChanged( agentIDsToCoordinate , shouldCoordinateAll );


#ifdef CATKIN_MAKE
#else
    // TO ASSIST WITH DEBUGGING WHEN COMPILED AND RUN IN "QtCreator"
    QTextStream(stdout) << "[COORDINATOR] is coordinating agentIDs:";
    for ( int irow = 0 ; irow < vector_of_shouldCoordinate_perRow.length() ; irow++ )
    {
        if (vector_of_shouldCoordinate_perRow[irow])
        {
            QTextStream(stdout) << " " << vector_of_agentID_perRow[irow];
        }
    }
    QTextStream(stdout) << " " << endl;
#endif
294
}