Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CARMA Messenger Integration Test #231

Merged
merged 17 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions carma_messenger_vehicle_plugin/src/move_over_law.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def __init__(self, sumo_connector, veh_id):
self.sumo_connector = sumo_connector
self.sumo_connector.create_stop_veh(self._target_veh_id, self._stop_pos, self._stop_route)
self.first_time_two_vehicles = True
self.is_get_closer = False
Copy link
Contributor

@kjrush kjrush Dec 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not advocating for any kind of change, but wanted to point out some thoughts for future cases like this:

Generally at a design level, this is where something like a state machine would be good to consider. Right now you've got two variables is_get_closer and is_stopped (and possibly others here) that are really representing a single underlying state of the algorithm. The key is that these two variables are mutually exclusive, as far as I can tell, that the is_get_closer should never be true while is_stopped is true, and vice-versa. So they really encode an aspect of a single actual piece of information, having them as two separate variables like this doesn't really enforce or communicate that relationship between them.

A state machine implementation for something like this could be as simple as identifying the states of the algorithm and then defining an enum with a value per state:

class MoveOverLawState(Enum):
  INIT = 1
  GET_CLOSER = 2
  STOPPING = 3
  STOPPED = 4
  DEPART = 5

and then tracking it as a single self.state variable. This way you represent that there is really only one state value at a time (rather than two truly independent variables) and represented the total possible state space within that one variable. You could then design the class in a way that uses a switch statement or different methods per state, define transition conditions for each possible transition within the state space, etc.

def process():
  if self.state == INIT:
    do_init()
    if should_transition_to_approaching(): 
      self.state = APPROACHING
  elif self.state == APPROACHING:
    do_approaching()
    if should_transition_to_stopping();
      self.state = STOPPING
  #etc, etc.

The value of that depends on how complex the design is, probably not necessary for this particular example.

self.is_stopped = False

def close_lane(self):
#send lane closure message
Expand All @@ -45,6 +47,7 @@ def park_messenger(self):
target_lane_index = int(target_lane.split('_')[-1])
self.sumo_connector.move_veh_lane(self._veh_id, target_lane_index)
self.sumo_connector.stop_veh(self._veh_id)
self.is_stopped = True
return

def get_closer(self):
Expand All @@ -64,10 +67,10 @@ def move_over(self):
veh_pos = self.sumo_connector.get_veh_pos(self._veh_id)
target_pos = self.sumo_connector.get_veh_pos(self._target_veh_id)
distance = self.sumo_connector.cal_distance(veh_pos, target_pos)
print("Distance: " + str(distance))

if distance < 30:
if distance < 30 and not self.is_stopped:
self.park_messenger()
self.close_lane()
elif distance < 250:
elif distance < 250 and not self.is_get_closer:
self.is_get_closer = True
self.get_closer()
2 changes: 1 addition & 1 deletion carma_messenger_vehicle_plugin/src/msger_veh_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def run(args):
parser = argparse.ArgumentParser(description='Script to manage messenger vehicles in a SUMO simulation.')
parser.add_argument('--traci-ip', default="localhost", help='IP address for Traci to connect to SUMO.')
parser.add_argument('--traci-port', default=2010, help='Port number for Traci to connect to SUMO.')
parser.add_argument('--traci-order-num', default=2, help='Traci connection order number for SUMO multi-client setup.')
parser.add_argument('--traci-order-num', default=3, help='Traci connection order number for SUMO multi-client setup.')
parser.add_argument('--msger-veh-cfg-path', default="resources/msger_veh_cfg.json", help='Path to the messenger vehicle configuration JSON file.')
parser.add_argument('--log-level', default='INFO', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
help='Set the logging level')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[Settings]
closure_uptrack:50
closure_downtrack:50
closure_uptrack:5
closure_downtrack:5
target_id:target1
min_gap:5
advisory_speed_limit:10.0
stop_route:stop1
stop_pos:298
start_lane:-50_4
stop_pos:78
start_lane:-43_4
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
[
{
"id": "msger_1",
"route": ["-50","-43"],
"route": [ "-43",
"-36"],
"speed": 10,
"departureTime": 5,
"lcm" : 0,
"cfm" : "MoveOverLaw"
}
]
}
}
12 changes: 11 additions & 1 deletion carma_messenger_vehicle_plugin/src/sumo_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import os
import logging
import math
import time

if 'SUMO_HOME' in os.environ:
tools_path = os.path.join(os.environ['SUMO_HOME'], 'tools')
Expand Down Expand Up @@ -209,6 +210,7 @@ def cal_distance(self, pos_1, pos_2):
"""
try:
distance = math.sqrt((pos_1[0] - pos_2[0])**2 + (pos_1[1] - pos_2[1])**2)
logging.debug("Distance to target: " + str(distance))
return distance
except Exception as e:
logging.error(f"Failed to calculate vehicle distance ")
Expand All @@ -220,6 +222,14 @@ def stop_veh(self, veh_id):
"""
try:
traci.vehicle.setSpeed(veh_id, 0)
traci.vehicle.setStop(
vehID=veh_id, # Vehicle ID
edgeID=traci.vehicle.getRoadID(veh_id), # Edge ID where the vehicle stops
pos=70, # Position (meters) on the edge
laneIndex=2, # Lane index (e.g., 0 for the first lane)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pos and laneIndex seem hard coded? Will this work for other scenarios?

duration=10000, # Duration (in seconds) the vehicle stays stopped
flags=0 # Flags (optional, can be left as 0)
)

except Exception as e:
logging.error(f"Failed to stop vehicle for vehicle ID '{veh_id}': {e}")
Expand Down Expand Up @@ -257,7 +267,7 @@ def get_veh_pos(self, veh_id):

def create_stop_veh(self, veh_id, end_pos, stop_route):
try:
traci.vehicle.add(vehID = veh_id, routeID=stop_route, typeID="car", depart=0, departPos=end_pos)
traci.vehicle.add(vehID = veh_id, routeID=stop_route, typeID="car", depart=0, departPos=end_pos, departLane='2')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as comment above re hard-coding

traci.vehicle.setSpeed(veh_id, 0)
except Exception as e:
logging.error(f"Failed to create stopped vehicle for vehicle ID '{veh_id}': {e}")
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

#x-terminal-emulator
cd /opt/carma-simulation/bridge

x-terminal-emulator -e python3.7 carla_mosaic_bridge.py --bridge-server-port 8913 -m Town04 /opt/carma-simulation/scenarios/Town04_carma_messenger/sumo/Town04.net.xml --step-length 0.1 --tls-manager EVC
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"updateInterval": 100,
"carlaUE4Path": "/opt/carla/",
"bridgePath": "/opt/carma-simulation/scenarios/Town04_carma_messenger/carla; bridge.sh",
"carlaConnectionPort": 8913,
"carlaCDASimAdapterUrl":"http://172.2.0.5:8000/RPC2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"updateInterval": 100
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"updateInterval": 100,
"carmaVehicles": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"updateInterval": 100
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"prototypes": [],
"chargingStations": [],
"vehicles": [
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"messages": {
"destinationType": {
"AD_HOC_GEOCAST": true,
"AD_HOC_TOPOCAST": false,
"CELL_GEOCAST": false,
"CELL_GEOCAST_MBMS": false,
"CELL_TOPOCAST": false
},
"destinationAddress": {
"ipv4UnicastAddress": false,
"ipv4BroadcastAddress": true,
"ipv4AnycastAddress" : false
},
"protocolType": {
"UDP": true,
"TCP": false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ns3>
<LogLevel>
<!-- for name, refer to corresponding ns3 model -->
<!-- possible level values: error warn debug info function logic all * -->
<!-- including higher levels: level_error level_warn level_debug level_info level_function level_logic level_all ** -->
<!-- possible prefix values: func time node level prefix_func prefix_time prefix_node prefix_level prefix_all -->
<component name="*" value="prefix_level|prefix_time"/>

<component name="MosaicStarter" value="warn|error|debug|info"/>
<component name="MosaicSimulatorImpl" value="warn|error|debug|info"/>
<component name="MosaicNs3Server" value="warn|error|debug|info"/>
<component name="MosaicNodeManager" value="warn|error|debug|info"/>
<component name="MosaicProxyApp" value="warn|error|debug|info|function|func"/>

<component name="UdpSocketImpl" value="warn|error|info"/>
<component name="UdpL4Protocol" value="warn|error|info"/>
<component name="Ipv4L3Protocol" value="warn|error|info"/>
<component name="Ipv4Interface" value="warn|error|info"/>
<component name="TrafficControlLayer" value="warn|error|info"/>

<component name="PropagationLossModel" value="warn|error|info"/>
<component name="YansWifiPhy" value="warn|error|info"/>
<component name="WaveNetDevice" value="warn|error|info"/>
<component name="YansWifiChannel" value="warn|error|info"/>
<component name="InterferenceHelper" value="warn|error|info"/>
<!-- List can be extendy by other components to set logging for -->
</LogLevel>

<!-- Mosaic Federate settings -->
<default name="ns3::MosaicProxyApp::Port" value="8010"/>
<default name="ns3::MosaicNodeManager::DelayModel" value="ns3::ConstantSpeedPropagationDelayModel"/>
<default name="ns3::MosaicNodeManager::LossModel" value="ns3::FriisPropagationLossModel"/>


<!-- NS3 model settings -->
<default name="ns3::RandomPropagationDelayModel::Variable" value="ns3::UniformRandomVariable"/>
<default name="ns3::ConstantSpeedPropagationDelayModel::Speed" value="2.99792e+08"/>

<default name="ns3::RandomPropagationLossModel::Variable" value="ns3::ConstantRandomVariable[Constant=1.0]"/>

<default name="ns3::FriisPropagationLossModel::Frequency" value="5900000000"/>
<default name="ns3::FriisPropagationLossModel::SystemLoss" value="1"/>
<default name="ns3::FriisPropagationLossModel::MinLoss" value="0"/>

<default name="ns3::TwoRayGroundPropagationLossModel::Frequency" value="5900000000"/>
<default name="ns3::TwoRayGroundPropagationLossModel::SystemLoss" value="1"/>
<default name="ns3::TwoRayGroundPropagationLossModel::MinDistance" value="1"/>
<default name="ns3::TwoRayGroundPropagationLossModel::HeightAboveZ" value="2"/>

<default name="ns3::LogDistancePropagationLossModel::Exponent" value="2.0"/>
<default name="ns3::LogDistancePropagationLossModel::ReferenceDistance" value="1"/>
<default name="ns3::LogDistancePropagationLossModel::ReferenceLoss" value="47.85704"/>

<default name="ns3::WifiPhy::EnergyDetectionThreshold" value="-81.02"/>
<default name="ns3::WifiPhy::CcaMode1Threshold" value="-99.0"/>
<default name="ns3::WifiPhy::TxGain" value="0.0"/>
<default name="ns3::WifiPhy::RxGain" value="0.0"/>
<default name="ns3::WifiPhy::TxPowerLevels" value="1"/>
<default name="ns3::WifiPhy::TxPowerEnd" value="17"/>
<default name="ns3::WifiPhy::TxPowerStart" value="17"/>
<default name="ns3::WifiPhy::RxNoiseFigure" value="0"/>
<default name="ns3::WifiPhy::ChannelSwitchDelay" value="+250000.0ns"/>
<default name="ns3::WifiPhy::ChannelNumber" value="178"/>
<default name="ns3::WifiPhy::Frequency" value="5900"/>
<default name="ns3::WifiPhy::Antennas" value="1"/>
<default name="ns3::WifiPhy::ShortGuardEnabled" value="false"/>
<default name="ns3::WifiPhy::LdpcEnabled" value="false"/>
<default name="ns3::WifiPhy::STBCEnabled" value="false"/>
<default name="ns3::WifiPhy::GreenfieldEnabled" value="false"/>
<default name="ns3::WifiPhy::ShortPlcpPreambleSupported" value="false"/>
<default name="ns3::WifiPhy::ChannelWidth" value="10"/>

<default name="ns3::ConstantRateWifiManager::DataMode" value="OfdmRate6Mbps"/>
<default name="ns3::ConstantRateWifiManager::ControlMode" value="OfdmRate6Mbps"/>

<default name="ns3::QueueBase::MaxPackets" value="400"/>
<default name="ns3::WifiMacQueue::MaxDelay" value="+500000000.0ns"/>
<default name="ns3::WifiNetDevice::Mtu" value="2296"/>

<default name="ns3::WifiMac::CtsTimeout" value="+75000.0ns"/>
<default name="ns3::WifiMac::AckTimeout" value="+75000.0ns"/>
<default name="ns3::WifiMac::BasicBlockAckTimeout" value="+281000.0ns"/>
<default name="ns3::WifiMac::CompressedBlockAckTimeout" value="+107000.0ns"/>
<default name="ns3::WifiMac::Sifs" value="+16000.0ns"/>
<default name="ns3::WifiMac::EifsNoDifs" value="+60000.0ns"/>
<default name="ns3::WifiMac::Slot" value="+9000.0ns"/>
<default name="ns3::WifiMac::Pifs" value="+25000.0ns"/>
<default name="ns3::WifiMac::Rifs" value="+2000.0ns"/>
<default name="ns3::WifiMac::MaxPropagationDelay" value="+3333.0ns"/>
<default name="ns3::WifiMac::Ssid" value="default"/>
<global name="RngSeed" value="1"/>
</ns3>
Loading
Loading