Can we use arrays for multiple publish topics in ros? - arrays

So i was working on some ros based UAV simulation and it just struck me when I had to initialize separate publishers for each UAV. Is it possible to make an array of such publishers and then reference them by just using their index number? I know I should just do it and try it, but I guessed asking here would be a faster option:)

Yes this is possible by collecting multiple ros::Publishers in containers. Here is a small example using an array:
#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char *argv[])
{
ros::init(argc, argv, "test_node");
ros::NodeHandle nh;
ros::WallTimer timer;
//Create publishers
std::array<ros::Publisher, 3> publishers;
for (size_t i = 0; i < publishers.size(); i++)
{
std::stringstream topic_name;
topic_name << "topic" << i;
publishers[i] = nh.advertise<std_msgs::String>(topic_name.str(), 0);
}
//Publish
ros::Rate r(1);
std_msgs::String msg;
while (nh.ok())
{
std::stringstream message;
message << "Hello World " << ros::Time::now();
msg.data = message.str();
for (size_t i = 0; i < publishers.size(); i++)
{
publishers[i].publish(msg);
}
ros::spinOnce();
r.sleep();
}
return 0;
}
The node advertises the three topics
/topic0
/topic1
/topic2
and publishes a simple string like Hello World 1562571209.130936883 with a rate of 1 Hz.

Related

Changing char[] in C

I looking for a answer and can't find nowhere. I hope you'll help me. I write a simple app which include struct with a name of worker and . But when i want to change value of name i can't do it. I don't know why. Maybe you can't help me or you know another ways to do it? My code:
struct workers {
char name[256]="no";
int pay=-1;
};
void addOne(struct workers work[20]) {
char name[256];
int i=0;
for (i = 0; work[i].name != "no"; i++) {}
printf_s("Enter name of worker: ");
scanf_s("%s", &name);
//-----error here-----
work[i].name = name;
}
int main()
{
int i;
struct workers work[20];
for (i = 0;i < 20; i++) {
if (work[i].name != "no") {
work[i].pay = 100 * i;
}
}
for (i = 0; i < 20; i++) {
printf_s("%s\t%d\n", work[i].name, work[i].pay);
}
return 0;
}
work[i].name = name;
The above line is where the problem is.
Change as below:
snprintf( work[i].name, sizeof(work[i].name), "%s", name);
What you have done is trying to change the base pointer of the array and not the name.
Also there were few more errors in the code, pls resolve them.
It is not possible to set default values to structure as you have done in C.
You have to write code to init each array instance name variable with "no" in a loop and then use one of the string comparison functions to compare the strings. And then call your addOne.

Best choice for very simple lookup table

I am reading a file with commands that are [a-zA-Z][a-zA-Z0-9], i.e., two chars. There is a total of 43 different commands, and I would like to transform the two chars to a number (1..43).
How would you proceed? I was thinking on creating an array of 43 unsigned shorts (two bytes) each corresponding to the two chars of each command, and then doing something like:
//char1: first char of cmd, char2: second char of cmd, lut: array of 43 shorts.
unsigned short tag;
tag = (char1 << 8) | char2;
for(int i=1;i<=43;i++) {
if(tag==lut[i-1]) return i;
}
return 0;
The thing is I'm not sure if this is the best way for doing what I want. I guess that with just 43 elements it won't matter, but that list might increase in the future.
Here is a method I used on an old project. One big drawback to this method is the lookup table and enum are dependent on each other and need to be kept synchronized. I got this method from an online article quite a few years ago, but don't remember where. This is a complete example:
#include <stdio.h>
#include <string.h>
#define CMDSIZE 2
const char* cmd_table[] = { "qu",
"qr",
"fi",
"he"};
enum { CMD_QUIT,
CMD_QUIT_RESTART,
CMD_FILE,
CMD_HELP,
CMD_NONE };
int lookup(char command[])
{
int i = 0;
int cmdlength = strlen(command);
for (i = 0; i < cmdlength; i++)
{
command[i] = tolower(command[i]);
}
const int valid_cmd = sizeof cmd_table / sizeof *cmd_table;
for (i = 0; i < valid_cmd; i++)
{
if (strcmp(command, cmd_table[i]) == 0)
return i;
}
return CMD_NONE;
}
int main()
{
char key_in[BUFSIZ];
char command[CMDSIZE+1];
// Wait for command
do
{
printf("Enter command: ");
fgets(key_in, BUFSIZ, stdin);
key_in[strlen(key_in)-1] = '\0';
strncpy(command, key_in, CMDSIZE);
command[CMDSIZE] = '\0';
switch (lookup(command))
{
case CMD_QUIT:
printf ("quit\n");
break;
case CMD_QUIT_RESTART:
printf ("quit & restart\n");
break;
case CMD_FILE:
printf ("file\n");
break;
case CMD_HELP:
printf("help\n");
break;
case CMD_NONE:
if(strcmp(key_in, ""))
printf("\"%s\" is not a valid command\n", key_in);
break;
}
} while (strcmp(command, "qu"));
return 0;
}
EDIT:
I found the article I mentioned:
https://www.daniweb.com/software-development/cpp/threads/65343/lookup-tables-how-to-perform-a-switch-using-a-string

Data inconsistency in XBee send and receive. Embedded C

I want send a string in the following format from a serial port in embedded C. I am using a Silicon Labs microcontroller. The desired output is
"01001ODR0001\r\n"
"01002ODR0001\r\n"
"01003ODR0001\r\n"
However, when I send the message, there is some randome behavor and the output comes in the following format.
0R00110
010
120 0D
01001ODR0001
0R0ODR0000
1OD01O01R10R
01002OR0001
0O012000
I use the following method for it
sendToXbee("01001ODR0001\r\n");
void sendToXbee(unsigned char *msg) {
while (*msg != '\0') //Checking up to null char
{
SerTx(*msg);
msg++;
Delay(1);
}
}
void SerTx(unsigned char x) {
SBUF0 = x;
while (TI0 == 0)
;
TI0 = 0;
}
/**
* Delay
*/
void Delay(unsigned char temp) {
unsigned int i, j;
for (i = 0; i <= temp; i++) {
for (j = 0; j <= 5000; j++)
;
}
}
Is there a better way of doing this?
Hi Guys thanks for the help. It seems that I was using a screen command on the terminal and at the same time running a python script that was using the same the object and hence the data inconsistency. if u see below the terminal output is better but still not perfect
04001ODR0001
04001OD000
04002ODR001
04002ODR0000
04003ODR0001
04003ODR0000
04004DR0001
04004ODR0000
04005ODR0001
04005ODR000
04004OD0001
0404ODR0000
04003ODR001
04003ODR0000
04003OR0001
04003ODR000
04003ODR001
0403OR000100
04003ODR0000
0400ODR0001
4003ODR000
04003OR0001
0400ODR0000

How create a simple program using threads in C?

I'm new in C development, I know just the basics and I need to create a program that discover a simple hash password like this one:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <crypt.h>
#include <stdlib.h>
#define SIZE_HASH 256
#define SIZE_PASSWORD 4
/* Get the hash from a passwod and put the result in hash. The array hash shoud have at lest 14 elements. */
void calculate_hash_password(const char *password, char *hash);
void increment_password(char *password);
void test_password(const char *p_hash, const char *password);
int main(int argc, char *argv[]) {
int i;
char password[SIZE_PASSWORD + 1];
if (argc != 2) {
printf("Use: %s <hash>", argv[0]);
return 1;
}
for (i = 0; i < SIZE_PASSWORD; i++) {
password[i] = 'a';
}
password[SIZE_PASSWORD] = '\0';
while (1) {
test_password(argv[1], password);
increment_password(password);
}
return 0;
}
void test_password(const char *p_hash, const char *password) {
char hash_calculado[SIZE_HASH + 1];
calculate_hash_password(password, hash_calculado);
if (!strcmp(p_hash, hash_calculado)) {
printf("Achou! %s\n", password);
exit(0);
}
}
void increment_password(char *password) {
int i;
i = SIZE_PASSWORD - 1;
while (i >= 0) {
if (password[i] != 'z') {
password[i]++;
i = -2;
} else {
password[i] = 'a';
i--;
}
}
if (i == -1) {
printf("Não achou!\n");
exit(1);
}
}
void calculate_hash_password(const char *password, char *hash) {
struct crypt_data data;
data.initialized = 0;
strcpy(hash, crypt_r(password, "aa", &data));
}
I must do the same thing as this one but using threads in C.
How can I do that ?
EDIT
Using threads to hash passwords is not a particularly intuitive or obviously useful approach, so it is not clear why anyone would want to do that.
Presumably the calculation for hashing is split up in some way: perhaps one thread processes passwords beginning with A through M and another does N through Z, or some such partitioning. One idea would be to run the same function multiple times with a parameter which determines which partition to execute. Here is a simple, functioning program which demonstrates the framework.
#include <iostream>
#include <pthread.h>
static void *calc_func (void *arg)
{
int param = (int) arg;
if (param == 1)
{
// do first partition of calculation
// ...
std::cout << "partition 1" << std::endl;
}
else
{
// do second partition of calculation
// ...
std::cout << "partition 2" << std::endl;
}
}
int main (...)
{
// ...
pthread_t threadh[2];
if (pthread_create (&threadh[0], NULL, calc_func, (void *)1) != 0)
{
std::cerr << "error creating thread 1" << std::endl;
}
if (pthread_create (&threadh[1], NULL, calc_func, (void *)2) != 0)
{
std::cerr << "error creating thread 2" << std::endl;
}
// wait for threads to exit
pthread_join (threadh[0], NULL);
pthread_join (threadh[1], NULL);
return 0;
}
To build it on Linux using gcc, use the command g++ -pthread filename.c++ -o filename
On a Linux shell execute:
man pthread_create
Read it carefully, and notice that provides a very descriptive example, on how to use threads. See also the man pages of the functions in the SEE ALSO section.
If you are on windows you can see the decomentation of pthreads-win32 here
After that you have to decide which part(s) of your code can be parallelized and assign that code to different threads.

Avoiding starvation when attempting to use a many-to-many implementation

I am trying to grant access to a shared resource to two types of threads. It can be accessed by more than one threads, if, and only if, that thread is of the same type. Let us consider blacks & whites. When the resource is used by whites, it cannot be used by blacks and vice-versa.
I attempted to implement this using semaphores. Once a black tries to access the resource, it will increment the number of blacks and if that number is 1, it will block the whites from accessing it.
Issue: there is a noticeable starvation when there are more than 1 thread of each type (in my case threads with id 0 never used it). I attempted to fix this by adding an extra semaphore to serve as a queue.
Observation: this resembles very well to the readers-writers problem, except there is a many to many access criteria. (it can be used by multiple threads of the same type) I have been bashing my head quite a lot around this problem lately and I cannot seem to understand how should I approach this.
Now, for some code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_RAND 100
#define TRUE 1
#define FALSE 0
#define WHITES 3
#define BLACKS 2
#define MAX_WORLOAD 10
sem_t semaphore;
sem_t resource_semaphore;
sem_t service_queue;
volatile int resource = 0;
volatile int currentWhites = 0;
volatile int currentBlacks = 0;
typedef struct
{
char *type;
int *id;
} data;
void *white(void *args)
{
data *thread_data = (data *)args;
int id = *(thread_data->id);
char *type = thread_data->type;
for (int i = 0; i < MAX_WORLOAD; i++)
{
sem_wait(&service_queue);
sem_wait(&semaphore);
sem_post(&service_queue);
currentWhites++;
if (currentWhites == 1)
{
sem_wait(&resource_semaphore);
}
sem_post(&semaphore);
sem_wait(&semaphore);
currentBlacks--;
resource = rand() % MAX_RAND;
printf("Thread %d of type %s has updated resource to %d\n\n", id, type, resource);
if (currentWhites == 0)
{
sem_post(&resource_semaphore);
}
sem_post(&semaphore);
}
}
void *black(void *args)
{
data *thread_data = (data *)args;
int id = *(thread_data->id);
char *type = thread_data->type;
for (int i = 0; i < MAX_WORLOAD; i++)
{
sem_wait(&service_queue);
sem_wait(&semaphore);
sem_post(&service_queue);
currentBlacks++;
if (currentBlacks == 1)
{
sem_wait(&resource_semaphore);
}
sem_post(&semaphore);
sem_wait(&semaphore);
currentBlacks--;
resource = rand() % MAX_RAND;
printf("Thread %d of type %s has updated resource to %d\n\n", id, type, resource);
if (currentBlacks == 0)
{
sem_post(&resource_semaphore);
}
sem_post(&semaphore);
}
}
data *initialize(pthread_t threads[], int size, char *type)
{
data *args = malloc(sizeof(data) * size);
int *id = malloc(sizeof(int));
void *function;
if (type == "WHITE")
{
function = white;
}
else
{
function = black;
}
for (int i = 0; i < size; i++)
{
*id = i;
args[i].type = type;
args[i].id = id;
printf("Initializing %d of type %s\n", *args[i].id, args[i].type);
pthread_create(&threads[i], NULL, function, (void **)&args[i]);
}
return args;
}
void join(pthread_t threads[], int size)
{
for (int i = 0; i < size; i++)
{
pthread_join(threads[i], NULL);
}
}
void initialize_locks()
{
sem_init(&semaphore, 0, 1);
sem_init(&resource_semaphore, 0, 1);
sem_init(&service_queue, 0, 1);
}
int main()
{
initialize_locks();
pthread_t whites[WHITES];
pthread_t blacks[BLACKS];
char *white = "white";
char *black = "black";
data *whites_arg = initialize(whites, WHITES, white);
data *blacks_arg = initialize(blacks, BLACKS, black);
join(whites, WHITES);
join(blacks, BLACKS);
free(whites_arg);
free(blacks_arg);
return 0;
}
If you want to force alternation between two types of threads accessing a single thing you can use two semaphores. Make it so the blacks and whites each have their own semaphores, start one semaphore with 0 keys and the other with 10 or something, then make it so that the whites release a key to the black semaphore, and the blacks release a key to the white semaphore, this way if you have 10 white threads in, when one of them unlocks you won't be able to put a 10th white thread in, but you will be able to put a black thread in, so that when all of the white threads release their keys you will have no white threads currently accessing the thing.
TL;DR: two semaphores that post to each other instead of themselves will allow alternation between groups, however independent of this operation you need to also make sure that whites don't go while blacks are still in.

Resources