How to make a command line argument on Ros2 Humble at launch - c++

I want to use the command line argument on ros2.
In my node :
const std::string name ="test"; const rclcpp::ParameterValue test(10); const rclcpp::ParameterValue testArg(rclcpp::Node::declare_parameter(name,test,ParamDesc,true)); cout << testArg.to_value_msg().integer_value << "\n";
Then when I throw in with the argument:
$ ros2 run dip_sensors TI6843AOP_node --ros-args -p test:=42 10
The node starts well but it indicates 10 when I passed it 42.
I can set the argument this way later but not at startup :
$ ros2 param set /NameNode test 42 Set parameter successful
Then
$ ros2 param get /NameNode test Integer value is:42
Do you have any idea of my mistakes?
Thanks,
Dimi

I have the solution and it's simple. I misread the function description and to activate the overriding you must not put the argument true but false:
testArg(rclcpp::Node::declare_parameter(name,test,ParamDesc,true)); --> bad testArg(rclcpp::Node::declare_parameter(name,test,ParamDesc,false)); --> good

Related

How to pass a string to omnetpp simulation from the command prompt

In my .ned file I have a simple module
simple Txc1
{
parameters:
int dummy_number = default(10);
}
When I run the simulation from the command prompt by specifying dummy_number I want i.e.,
opp_run -l tictoc omnetpp.ini --**.dummy_number=15
dummy_number equals 15 in my simulation.
But when instead of integer I want to specify a string
simple Txc1
{
parameters:
string dummy_string = default("Some dummy string");
}
opp_run -l tictoc omnetpp.ini --**.dummy_string="Test"
I get the following error
Cannot evaluate parameter 'dummy_string':(omnetpp::cModule)Tictoc1: unknown parameter 'Test' -- in module (Txc1) Tictoc1.tic (id=2), during network setup
Why my string is perceived as a parameter when it is just a value and how do I circumvent the problem?
Thanks
As long as your string does not contain a space, add backslashes before quotes, i.e.:
opp_run -l tictoc omnetpp.ini --**.dummy_string=\"TestWithoutSpace\"

Change a constant variable without rebuilding C++

I've developed a c++ project with visual studio 2015. The output of my project is a single executable that must have a unique ID for every client and this ID must be accessible inside the code. A simple approach is to just define a constant variable inside the code and change its value for every client and build it many times but I have a Linux server and I'm not sure I can build it simply because I've used many Winapi libraries. I was thinking that maybe there is another way to change or add some constant value to the output like manipulating the executable.
For example:
#include <string>
#include <iostream>
#include <Windows.h>
const std::string ID = "some unique ID";
int main() {
std::cout << "Your ID: " << ID << std::endl;
getchar();
return(0);
}
It seems that there are only two approaches. One is just building the project inside a Linux environment which is a better method but must be used some tools like Mono XBuild link here.
Another option which may be simpler is just open the binary file and manipulate the specific string. As #aloMalbarez comment Here is a simple script based on this.
Suppose this example: (I used 50 ms as a fixed length for my ID)
#include <string>
#include <iostream>
#include <Windows.h>
#define ID "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"
using namespace std;
int main() {
cout << "Your ID: " << ID << "\nlen:" << strlen(ID) << endl;
getchar();
return(0);
}
After generating the executable use the following script to create output.
I'm not a Linux guy so you can help me improve this.
./build.sh input.exe output.exe "myfixedID"
#!/bin/bash
# build.sh input_file output_file <ID>
input_file=$1
output_file=$2
ID=$3
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
echo "wrong parameters"
echo "build.sh input_file output_file <ID>"
exit 1
fi
# use fixed string (ID) in the source file
# this creates 50 of "m"s
search_value=$(printf 'm%.0s' {1..50})
extension=".back"
temp_file="$input_file$extension"
tmpstring_file="./tmp"
null_termin='\0'
echo "copying the original file..."
yes | cp -rf $input_file $temp_file
address=$(strings -t d $temp_file | grep $search_value | grep -o '[0-9]*')
echo "Address:"
echo $address
if ! [[ $address =~ ^[0-9]+$ ]]; then
echo "cannot find valid ID in executable"
echo "removing temps"
rm $temp_file
exit 1
fi
# make the tempstring file
printf "$ID$null_termin" > $tmpstring_file
dd if=$tmpstring_file of=$temp_file obs=1 seek=$address conv=notrunc
echo "make new file"
yes | cp -rf $temp_file $output_file
echo "removing temps"
rm $temp_file $tmpstring_file
echo "Done!"
In init function of your program. Generate a unique id based of SHA-1
hash of current time, IP address, username (same more). you can do whatever you want to do in that program afterward (i.e save in database). Will that work ?
A Constant is not a Variable, they are opposite types. A Constant is an element that is assigned a particular value that does not change, thus the word constant, unchanging.
A Variable on the other hand is an element that is stored in memory as a changeable value, as your program runs, the VARIABLE can change it's current value.
In Visual Studio, you can create a configuration file that passes set values to your program, these values are variable, and can be changed programmatically and manually. But, as you stated you do not want a separate file to look up information from.
If you want to track users by their Unique ID, then you must have a database somewhere that can record new users and issue a unique ID, or, you can create a unique ID based on the date and time that the account is created, if you are creating a unique executable for each one, the date/time information is included in the file creation information, so you would simply use that, since every file is created at a unique date/time, that would always indicate the ID. You could keep the same name for each file, or incorporate the date/time into the filename, like myPro20180522183231.exe which would be year 2018 month 05 day 22 hour 18 minutes 32 seconds 31 and this could be confirmed through the date/time information of the file creation data.

How to pass input parameters to make? [duplicate]

How to pass argument to Makefile from command line?
I understand I can do
$ make action VAR="value"
$ value
with Makefile
VAR = "default"
action:
#echo $(VAR)
How do I get the following behavior?
$ make action value
value
How about
$make action value1 value2
value1 value2
You probably shouldn't do this; you're breaking the basic pattern of how Make works. But here it is:
action:
#echo action $(filter-out $#,$(MAKECMDGOALS))
%: # thanks to chakrit
#: # thanks to William Pursell
EDIT:
To explain the first command,
$(MAKECMDGOALS) is the list of "targets" spelled out on the command line, e.g. "action value1 value2".
$# is an automatic variable for the name of the target of the rule, in this case "action".
filter-out is a function that removes some elements from a list. So $(filter-out bar, foo bar baz) returns foo baz (it can be more subtle, but we don't need subtlety here).
Put these together and $(filter-out $#,$(MAKECMDGOALS)) returns the list of targets specified on the command line other than "action", which might be "value1 value2".
Here is a generic working solution based on #Beta's
I'm using GNU Make 4.1 with SHELL=/bin/bash atop my Makefile, so YMMV!
This allows us to accept extra arguments (by doing nothing when we get a job that doesn't match, rather than throwing an error).
%:
#:
And this is a macro which gets the args for us:
args = `arg="$(filter-out $#,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
Here is a job which might call this one:
test:
#echo $(call args,defaultstring)
The result would be:
$ make test
defaultstring
$ make test hi
hi
Note! You might be better off using a "Taskfile", which is a bash pattern that works similarly to make, only without the nuances of Maketools. See https://github.com/adriancooney/Taskfile
Much easier aproach. Consider a task:
provision:
ansible-playbook -vvvv \
-i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
--private-key=.vagrant/machines/default/virtualbox/private_key \
--start-at-task="$(AT)" \
-u vagrant playbook.yml
Now when I want to call it I just run something like:
AT="build assets" make provision
or just:
make provision in this case AT is an empty string
Few years later, want to suggest just for this: https://github.com/casey/just
action v1 v2=default:
#echo 'take action on {{v1}} and {{v2}}...'
You will be better of defining variables and calling your make instead of using parameters:
Makefile
action: ## My action helper
#echo $$VAR_NAME
Terminal
> VAR_NAME="Hello World" make action
Hello World
don't try to do this
$ make action value1 value2
instead create script:
#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$#"
and do this:
$ ./buildthenaction.sh value1 value2
for more explanation why do this and caveats of makefile hackery read my answer to another very similar but seemingly not duplicate question: Passing arguments to "make run"

Rare behaviour in command line arguments

I am trying to write a program in cpp using maps...
My goal is to allow * alone when we pass via comand line argument
And i have to restrict the characters coming along with * (ie)abc and abc
int main(int argc,char *argv[])
{
prinf("%s\n",argv[1]);
char str[256] = "";
int length;
strcpy(str,argv[1]);
length = strlen(str);
if((str[0] = '*' )&& (length == 1))
printf("success\n");
else
printf("failure");
return 0;
}
when i run this program ,getting the following output
$ ./exec *
$ 1
$ failure
argv[1] = 1(printing 1 instead of *)
failure because of not getting * as input argument,it results in failure.
Could someone help me to solve this issue?
Items on the command line are processed by the shell.
In the shell, the * performs a glob operation
In general, a glob operator, when standing alone, will result in a list of all the files in the current directory.
The character * has a special meaning in most shells. Your shell expands it to the files in the current directory resulting in a completely different arguments than the one you intended.
To avoid this, you can do:
$ ./exec "*"
or
$ ./exec '*'
If your shell is bash, then you can also turn off the globbing expansion with:
$ set -o noglob
or
$ set -f
but I would suggest the former options (above) as it's "minimal" and doesn't affect your shell's default behaviour otherwise.

How to unit test an Erlang function?

get_ue_supported_srvcc([]) ->
?SRVCC_3GPP_NONE_SUPPORT;
get_ue_supported_srvcc([#sip_contactV{extensionsP = EP} | T]) ->
case b2bLib:support_tags_to_value(EP) of
?SRVCC_3GPP_NONE_SUPPORT ->
get_ue_supported_srvcc(T);
Flag ->
Flag
end.
I want create a unit test for this function,
Here is my unit test case:
get_ue_supported_srvcc_test() ->
Contact =
[#sip_contactV{extensionsP =
[{"+sip.instance",
{quoted_string,"<urn:gsma:imei:35502406-005233-0>"}},
{"+g.3gpp.icsi-ref",
{quoted_string,"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel"}},
"+g.3gpp.mid-call",
"+g.3gpp.srvcc-alerting",
"+g.3gpp.ps2cs-srvcc-orig-pre-alerting",
"video"]}],
?assertEqual(7, b2bAtcfLib:get_ue_supported_srvcc(Contact)).
But when I run it, I get this error:
======================== EUnit ========================
module 'b2bAtcfLib'
b2bAtcfLib_tests: get_ue_supported_srvcc_test (module 'b2bAtcfLib_tests')...*failed*
in function b2bLib:support_tags_to_value/1
called as support_tags_to_value([{"+sip.instance",{quoted_string,"<urn:gsma:imei:35502406-005233-0>"}},
{"+g.3gpp.icsi-ref",
{quoted_string,"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel"}},
"+g.3gpp.mid-call","+g.3gpp.srvcc-alerting",
"+g.3gpp.ps2cs-srvcc-orig-pre-alerting","video"])
in call from b2bAtcfLib:get_ue_supported_srvcc/1 (src/b2bAtcfLib.erl, line 1735)
in call from b2bAtcfLib_tests:'-get_ue_supported_srvcc_test/0-fun-0-'/1 (test/unit/b2bAtcfLib_tests.erl, line 49)
in call from b2bAtcfLib_tests:get_ue_supported_srvcc_test/0
**error:undef
output:<<"">>
[done in 0.008 s]
=======================================================
The error means b2bLib:support_tags_to_value/1 is undef.
The define for this function b2bLib:support_tags_to_value:
support_tags_to_value(FieldStr) ->
lists:sum([Val || {Tag, Val} <- ?TAGLIST, lists:member(Tag, FieldStr)]).
The error is:
**error:undef
That means that the test is calling a function that's not defined. Either the module couldn't be found, or the module in question doesn't define a function with that name and arity.
The whole error message is a bit confusing. Now that we know that we got a "function undefined" error, we should be looking at this line:
in function b2bLib:support_tags_to_value/1
Even though it says that the error occurred "in" this function, this is the function that's undefined.
So either the test is run in such a way that it doesn't find the b2bLib module, or that module doesn't define a function called support_tags_to_value taking one argument. If it's the former, add -pa path/to/ebin to the Erlang command line in order to add the right directory to the code path.